OSDN Git Service

merge in nyc-mr2-release history after reset to nyc-mr2-dev
[android-x86/frameworks-base.git] / services / core / java / com / android / server / am / ActivityManagerService.java
1 /*
2  * Copyright (C) 2006-2008 The Android Open Source Project
3  *
4  * Licensed under the Apache License, Version 2.0 (the "License");
5  * you may not use this file except in compliance with the License.
6  * You may obtain a copy of the License at
7  *
8  *      http://www.apache.org/licenses/LICENSE-2.0
9  *
10  * Unless required by applicable law or agreed to in writing, software
11  * distributed under the License is distributed on an "AS IS" BASIS,
12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13  * See the License for the specific language governing permissions and
14  * limitations under the License.
15  */
16
17 package com.android.server.am;
18
19 import com.android.internal.telephony.TelephonyIntents;
20 import com.google.android.collect.Lists;
21 import com.google.android.collect.Maps;
22 import com.android.internal.R;
23 import com.android.internal.annotations.GuardedBy;
24 import com.android.internal.app.AssistUtils;
25 import com.android.internal.app.DumpHeapActivity;
26 import com.android.internal.app.IAppOpsCallback;
27 import com.android.internal.app.IAppOpsService;
28 import com.android.internal.app.IVoiceInteractor;
29 import com.android.internal.app.ProcessMap;
30 import com.android.internal.app.SystemUserHomeActivity;
31 import com.android.internal.app.procstats.ProcessStats;
32 import com.android.internal.os.BackgroundThread;
33 import com.android.internal.os.BatteryStatsImpl;
34 import com.android.internal.os.IResultReceiver;
35 import com.android.internal.os.ProcessCpuTracker;
36 import com.android.internal.os.TransferPipe;
37 import com.android.internal.os.Zygote;
38 import com.android.internal.os.InstallerConnection.InstallerException;
39 import com.android.internal.util.ArrayUtils;
40 import com.android.internal.util.FastPrintWriter;
41 import com.android.internal.util.FastXmlSerializer;
42 import com.android.internal.util.MemInfoReader;
43 import com.android.internal.util.Preconditions;
44 import com.android.server.AppOpsService;
45 import com.android.server.AttributeCache;
46 import com.android.server.DeviceIdleController;
47 import com.android.server.IntentResolver;
48 import com.android.server.LocalServices;
49 import com.android.server.LockGuard;
50 import com.android.server.ServiceThread;
51 import com.android.server.SystemService;
52 import com.android.server.SystemServiceManager;
53 import com.android.server.Watchdog;
54 import com.android.server.am.ActivityStack.ActivityState;
55 import com.android.server.firewall.IntentFirewall;
56 import com.android.server.pm.Installer;
57 import com.android.server.statusbar.StatusBarManagerInternal;
58 import com.android.server.vr.VrManagerInternal;
59 import com.android.server.wm.WindowManagerService;
60
61 import org.xmlpull.v1.XmlPullParser;
62 import org.xmlpull.v1.XmlPullParserException;
63 import org.xmlpull.v1.XmlSerializer;
64
65 import android.Manifest;
66 import android.Manifest.permission;
67 import android.annotation.NonNull;
68 import android.annotation.UserIdInt;
69 import android.app.Activity;
70 import android.app.ActivityManager;
71 import android.app.ActivityManager.RunningTaskInfo;
72 import android.app.ActivityManager.StackId;
73 import android.app.ActivityManager.StackInfo;
74 import android.app.ActivityManager.TaskThumbnailInfo;
75 import android.app.ActivityManagerInternal;
76 import android.app.ActivityManagerInternal.SleepToken;
77 import android.app.ActivityManagerNative;
78 import android.app.ActivityOptions;
79 import android.app.ActivityThread;
80 import android.app.AlertDialog;
81 import android.app.AppGlobals;
82 import android.app.AppOpsManager;
83 import android.app.ApplicationErrorReport;
84 import android.app.ApplicationThreadNative;
85 import android.app.BroadcastOptions;
86 import android.app.Dialog;
87 import android.app.IActivityContainer;
88 import android.app.IActivityContainerCallback;
89 import android.app.IActivityController;
90 import android.app.IAppTask;
91 import android.app.IApplicationThread;
92 import android.app.IInstrumentationWatcher;
93 import android.app.INotificationManager;
94 import android.app.IProcessObserver;
95 import android.app.IServiceConnection;
96 import android.app.IStopUserCallback;
97 import android.app.ITaskStackListener;
98 import android.app.IUiAutomationConnection;
99 import android.app.IUidObserver;
100 import android.app.IUserSwitchObserver;
101 import android.app.Instrumentation;
102 import android.app.Notification;
103 import android.app.NotificationManager;
104 import android.app.PendingIntent;
105 import android.app.ProfilerInfo;
106 import android.app.admin.DevicePolicyManager;
107 import android.app.assist.AssistContent;
108 import android.app.assist.AssistStructure;
109 import android.app.backup.IBackupManager;
110 import android.app.usage.UsageEvents;
111 import android.app.usage.UsageStatsManagerInternal;
112 import android.appwidget.AppWidgetManager;
113 import android.content.ActivityNotFoundException;
114 import android.content.BroadcastReceiver;
115 import android.content.ClipData;
116 import android.content.ComponentCallbacks2;
117 import android.content.ComponentName;
118 import android.content.ContentProvider;
119 import android.content.ContentResolver;
120 import android.content.Context;
121 import android.content.DialogInterface;
122 import android.content.IContentProvider;
123 import android.content.IIntentReceiver;
124 import android.content.IIntentSender;
125 import android.content.Intent;
126 import android.content.IntentFilter;
127 import android.content.IntentSender;
128 import android.content.pm.ActivityInfo;
129 import android.content.pm.ApplicationInfo;
130 import android.content.pm.ConfigurationInfo;
131 import android.content.pm.IPackageDataObserver;
132 import android.content.pm.IPackageManager;
133 import android.content.pm.InstrumentationInfo;
134 import android.content.pm.PackageInfo;
135 import android.content.pm.PackageManager;
136 import android.content.pm.PackageManager.NameNotFoundException;
137 import android.content.pm.PackageManagerInternal;
138 import android.content.pm.ParceledListSlice;
139 import android.content.pm.PathPermission;
140 import android.content.pm.PermissionInfo;
141 import android.content.pm.ProviderInfo;
142 import android.content.pm.ResolveInfo;
143 import android.content.pm.ServiceInfo;
144 import android.content.pm.UserInfo;
145 import android.content.res.CompatibilityInfo;
146 import android.content.res.Configuration;
147 import android.content.res.Resources;
148 import android.database.ContentObserver;
149 import android.graphics.Bitmap;
150 import android.graphics.Point;
151 import android.graphics.Rect;
152 import android.location.LocationManager;
153 import android.net.Proxy;
154 import android.net.ProxyInfo;
155 import android.net.Uri;
156 import android.os.BatteryStats;
157 import android.os.Binder;
158 import android.os.Build;
159 import android.os.Bundle;
160 import android.os.Debug;
161 import android.os.DropBoxManager;
162 import android.os.Environment;
163 import android.os.FactoryTest;
164 import android.os.FileObserver;
165 import android.os.FileUtils;
166 import android.os.Handler;
167 import android.os.IBinder;
168 import android.os.IPermissionController;
169 import android.os.IProcessInfoService;
170 import android.os.IProgressListener;
171 import android.os.LocaleList;
172 import android.os.Looper;
173 import android.os.Message;
174 import android.os.Parcel;
175 import android.os.ParcelFileDescriptor;
176 import android.os.PersistableBundle;
177 import android.os.PowerManager;
178 import android.os.PowerManagerInternal;
179 import android.os.Process;
180 import android.os.RemoteCallbackList;
181 import android.os.RemoteException;
182 import android.os.ResultReceiver;
183 import android.os.ServiceManager;
184 import android.os.StrictMode;
185 import android.os.SystemClock;
186 import android.os.SystemProperties;
187 import android.os.Trace;
188 import android.os.TransactionTooLargeException;
189 import android.os.UpdateLock;
190 import android.os.UserHandle;
191 import android.os.UserManager;
192 import android.os.WorkSource;
193 import android.provider.Downloads;
194 import android.os.storage.IMountService;
195 import android.os.storage.MountServiceInternal;
196 import android.os.storage.StorageManager;
197 import android.provider.Settings;
198 import android.service.voice.IVoiceInteractionSession;
199 import android.service.voice.VoiceInteractionManagerInternal;
200 import android.service.voice.VoiceInteractionSession;
201 import android.telecom.TelecomManager;
202 import android.text.format.DateUtils;
203 import android.text.format.Time;
204 import android.text.style.SuggestionSpan;
205 import android.util.ArrayMap;
206 import android.util.ArraySet;
207 import android.util.AtomicFile;
208 import android.util.DebugUtils;
209 import android.util.DisplayMetrics;
210 import android.util.EventLog;
211 import android.util.Log;
212 import android.util.Pair;
213 import android.util.PrintWriterPrinter;
214 import android.util.Slog;
215 import android.util.SparseArray;
216 import android.util.TimeUtils;
217 import android.util.Xml;
218 import android.view.Display;
219 import android.view.Gravity;
220 import android.view.LayoutInflater;
221 import android.view.View;
222 import android.view.WindowManager;
223
224 import java.io.File;
225 import java.io.FileDescriptor;
226 import java.io.FileInputStream;
227 import java.io.FileNotFoundException;
228 import java.io.FileOutputStream;
229 import java.io.IOException;
230 import java.io.InputStreamReader;
231 import java.io.PrintWriter;
232 import java.io.StringWriter;
233 import java.lang.ref.WeakReference;
234 import java.nio.charset.StandardCharsets;
235 import java.util.ArrayList;
236 import java.util.Arrays;
237 import java.util.Collections;
238 import java.util.Comparator;
239 import java.util.HashMap;
240 import java.util.HashSet;
241 import java.util.Iterator;
242 import java.util.List;
243 import java.util.Locale;
244 import java.util.Map;
245 import java.util.Objects;
246 import java.util.Set;
247 import java.util.concurrent.atomic.AtomicBoolean;
248 import java.util.concurrent.atomic.AtomicLong;
249
250 import dalvik.system.VMRuntime;
251
252 import libcore.io.IoUtils;
253 import libcore.util.EmptyArray;
254
255 import static android.Manifest.permission.INTERACT_ACROSS_USERS;
256 import static android.Manifest.permission.INTERACT_ACROSS_USERS_FULL;
257 import static android.Manifest.permission.MANAGE_ACTIVITY_STACKS;
258 import static android.Manifest.permission.START_TASKS_FROM_RECENTS;
259 import static android.app.ActivityManager.DOCKED_STACK_CREATE_MODE_TOP_OR_LEFT;
260 import static android.app.ActivityManager.RESIZE_MODE_PRESERVE_WINDOW;
261 import static android.app.ActivityManager.StackId.DOCKED_STACK_ID;
262 import static android.app.ActivityManager.StackId.FREEFORM_WORKSPACE_STACK_ID;
263 import static android.app.ActivityManager.StackId.FULLSCREEN_WORKSPACE_STACK_ID;
264 import static android.app.ActivityManager.StackId.HOME_STACK_ID;
265 import static android.app.ActivityManager.StackId.INVALID_STACK_ID;
266 import static android.app.ActivityManager.StackId.PINNED_STACK_ID;
267 import static android.content.pm.PackageManager.FEATURE_FREEFORM_WINDOW_MANAGEMENT;
268 import static android.content.pm.PackageManager.FEATURE_LEANBACK_ONLY;
269 import static android.content.pm.PackageManager.FEATURE_PICTURE_IN_PICTURE;
270 import static android.content.pm.PackageManager.GET_PROVIDERS;
271 import static android.content.pm.PackageManager.MATCH_DEBUG_TRIAGED_MISSING;
272 import static android.content.pm.PackageManager.MATCH_DIRECT_BOOT_AWARE;
273 import static android.content.pm.PackageManager.MATCH_DIRECT_BOOT_UNAWARE;
274 import static android.content.pm.PackageManager.MATCH_SYSTEM_ONLY;
275 import static android.content.pm.PackageManager.MATCH_UNINSTALLED_PACKAGES;
276 import static android.content.pm.PackageManager.PERMISSION_GRANTED;
277 import static android.content.res.Configuration.UI_MODE_TYPE_TELEVISION;
278 import static android.os.Process.PROC_CHAR;
279 import static android.os.Process.PROC_OUT_LONG;
280 import static android.os.Process.PROC_PARENS;
281 import static android.os.Process.PROC_SPACE_TERM;
282 import static android.provider.Settings.Global.ALWAYS_FINISH_ACTIVITIES;
283 import static android.provider.Settings.Global.DEBUG_APP;
284 import static android.provider.Settings.Global.DEVELOPMENT_ENABLE_FREEFORM_WINDOWS_SUPPORT;
285 import static android.provider.Settings.Global.DEVELOPMENT_FORCE_RESIZABLE_ACTIVITIES;
286 import static android.provider.Settings.Global.DEVELOPMENT_FORCE_RTL;
287 import static android.provider.Settings.Global.LENIENT_BACKGROUND_CHECK;
288 import static android.provider.Settings.Global.WAIT_FOR_DEBUGGER;
289 import static android.provider.Settings.System.FONT_SCALE;
290 import static com.android.internal.util.XmlUtils.readBooleanAttribute;
291 import static com.android.internal.util.XmlUtils.readIntAttribute;
292 import static com.android.internal.util.XmlUtils.readLongAttribute;
293 import static com.android.internal.util.XmlUtils.writeBooleanAttribute;
294 import static com.android.internal.util.XmlUtils.writeIntAttribute;
295 import static com.android.internal.util.XmlUtils.writeLongAttribute;
296 import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_ALL;
297 import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_ANR;
298 import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_BACKUP;
299 import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_BROADCAST;
300 import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_BROADCAST_BACKGROUND;
301 import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_BROADCAST_LIGHT;
302 import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_CLEANUP;
303 import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_CONFIGURATION;
304 import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_FOCUS;
305 import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_IMMERSIVE;
306 import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_LOCKSCREEN;
307 import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_LOCKTASK;
308 import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_LRU;
309 import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_MU;
310 import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_OOM_ADJ;
311 import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_PERMISSIONS_REVIEW;
312 import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_POWER;
313 import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_POWER_QUICK;
314 import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_PROCESSES;
315 import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_PROCESS_OBSERVERS;
316 import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_PROVIDER;
317 import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_PSS;
318 import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_RECENTS;
319 import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_SERVICE;
320 import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_STACK;
321 import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_SWITCH;
322 import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_TASKS;
323 import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_UID_OBSERVERS;
324 import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_URI_PERMISSION;
325 import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_USAGE_STATS;
326 import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_VISIBILITY;
327 import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_VISIBLE_BEHIND;
328 import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_WHITELISTS;
329 import static com.android.server.am.ActivityManagerDebugConfig.POSTFIX_BACKUP;
330 import static com.android.server.am.ActivityManagerDebugConfig.POSTFIX_BROADCAST;
331 import static com.android.server.am.ActivityManagerDebugConfig.POSTFIX_CLEANUP;
332 import static com.android.server.am.ActivityManagerDebugConfig.POSTFIX_CONFIGURATION;
333 import static com.android.server.am.ActivityManagerDebugConfig.POSTFIX_FOCUS;
334 import static com.android.server.am.ActivityManagerDebugConfig.POSTFIX_IMMERSIVE;
335 import static com.android.server.am.ActivityManagerDebugConfig.POSTFIX_LOCKSCREEN;
336 import static com.android.server.am.ActivityManagerDebugConfig.POSTFIX_LOCKTASK;
337 import static com.android.server.am.ActivityManagerDebugConfig.POSTFIX_LRU;
338 import static com.android.server.am.ActivityManagerDebugConfig.POSTFIX_MU;
339 import static com.android.server.am.ActivityManagerDebugConfig.POSTFIX_OOM_ADJ;
340 import static com.android.server.am.ActivityManagerDebugConfig.POSTFIX_POWER;
341 import static com.android.server.am.ActivityManagerDebugConfig.POSTFIX_PROCESSES;
342 import static com.android.server.am.ActivityManagerDebugConfig.POSTFIX_PROCESS_OBSERVERS;
343 import static com.android.server.am.ActivityManagerDebugConfig.POSTFIX_PROVIDER;
344 import static com.android.server.am.ActivityManagerDebugConfig.POSTFIX_PSS;
345 import static com.android.server.am.ActivityManagerDebugConfig.POSTFIX_RECENTS;
346 import static com.android.server.am.ActivityManagerDebugConfig.POSTFIX_SERVICE;
347 import static com.android.server.am.ActivityManagerDebugConfig.POSTFIX_STACK;
348 import static com.android.server.am.ActivityManagerDebugConfig.POSTFIX_SWITCH;
349 import static com.android.server.am.ActivityManagerDebugConfig.POSTFIX_UID_OBSERVERS;
350 import static com.android.server.am.ActivityManagerDebugConfig.POSTFIX_URI_PERMISSION;
351 import static com.android.server.am.ActivityManagerDebugConfig.POSTFIX_VISIBILITY;
352 import static com.android.server.am.ActivityManagerDebugConfig.POSTFIX_VISIBLE_BEHIND;
353 import static com.android.server.am.ActivityManagerDebugConfig.TAG_AM;
354 import static com.android.server.am.ActivityManagerDebugConfig.TAG_WITH_CLASS_NAME;
355 import static com.android.server.am.ActivityRecord.RECENTS_ACTIVITY_TYPE;
356 import static com.android.server.am.ActivityStackSupervisor.ActivityContainer.FORCE_NEW_TASK_FLAGS;
357 import static com.android.server.am.ActivityStackSupervisor.DEFER_RESUME;
358 import static com.android.server.am.ActivityStackSupervisor.FORCE_FOCUS;
359 import static com.android.server.am.ActivityStackSupervisor.ON_TOP;
360 import static com.android.server.am.ActivityStackSupervisor.PRESERVE_WINDOWS;
361 import static com.android.server.am.ActivityStackSupervisor.RESTORE_FROM_RECENTS;
362 import static com.android.server.am.TaskRecord.INVALID_TASK_ID;
363 import static com.android.server.am.TaskRecord.LOCK_TASK_AUTH_DONT_LOCK;
364 import static com.android.server.am.TaskRecord.LOCK_TASK_AUTH_LAUNCHABLE_PRIV;
365 import static com.android.server.am.TaskRecord.LOCK_TASK_AUTH_PINNABLE;
366 import static com.android.server.wm.AppTransition.TRANSIT_ACTIVITY_OPEN;
367 import static com.android.server.wm.AppTransition.TRANSIT_ACTIVITY_RELAUNCH;
368 import static com.android.server.wm.AppTransition.TRANSIT_TASK_IN_PLACE;
369 import static com.android.server.wm.AppTransition.TRANSIT_TASK_OPEN;
370 import static com.android.server.wm.AppTransition.TRANSIT_TASK_TO_FRONT;
371 import static org.xmlpull.v1.XmlPullParser.END_DOCUMENT;
372 import static org.xmlpull.v1.XmlPullParser.START_TAG;
373
374 public final class ActivityManagerService extends ActivityManagerNative
375         implements Watchdog.Monitor, BatteryStatsImpl.BatteryCallback {
376
377     private static final String TAG = TAG_WITH_CLASS_NAME ? "ActivityManagerService" : TAG_AM;
378     private static final String TAG_BACKUP = TAG + POSTFIX_BACKUP;
379     private static final String TAG_BROADCAST = TAG + POSTFIX_BROADCAST;
380     private static final String TAG_CLEANUP = TAG + POSTFIX_CLEANUP;
381     private static final String TAG_CONFIGURATION = TAG + POSTFIX_CONFIGURATION;
382     private static final String TAG_FOCUS = TAG + POSTFIX_FOCUS;
383     private static final String TAG_IMMERSIVE = TAG + POSTFIX_IMMERSIVE;
384     private static final String TAG_LOCKSCREEN = TAG + POSTFIX_LOCKSCREEN;
385     private static final String TAG_LOCKTASK = TAG + POSTFIX_LOCKTASK;
386     private static final String TAG_LRU = TAG + POSTFIX_LRU;
387     private static final String TAG_MU = TAG + POSTFIX_MU;
388     private static final String TAG_OOM_ADJ = TAG + POSTFIX_OOM_ADJ;
389     private static final String TAG_POWER = TAG + POSTFIX_POWER;
390     private static final String TAG_PROCESS_OBSERVERS = TAG + POSTFIX_PROCESS_OBSERVERS;
391     private static final String TAG_PROCESSES = TAG + POSTFIX_PROCESSES;
392     private static final String TAG_PROVIDER = TAG + POSTFIX_PROVIDER;
393     private static final String TAG_PSS = TAG + POSTFIX_PSS;
394     private static final String TAG_RECENTS = TAG + POSTFIX_RECENTS;
395     private static final String TAG_SERVICE = TAG + POSTFIX_SERVICE;
396     private static final String TAG_STACK = TAG + POSTFIX_STACK;
397     private static final String TAG_SWITCH = TAG + POSTFIX_SWITCH;
398     private static final String TAG_UID_OBSERVERS = TAG + POSTFIX_UID_OBSERVERS;
399     private static final String TAG_URI_PERMISSION = TAG + POSTFIX_URI_PERMISSION;
400     private static final String TAG_VISIBILITY = TAG + POSTFIX_VISIBILITY;
401     private static final String TAG_VISIBLE_BEHIND = TAG + POSTFIX_VISIBLE_BEHIND;
402
403     // Mock "pretend we're idle now" broadcast action to the job scheduler; declared
404     // here so that while the job scheduler can depend on AMS, the other way around
405     // need not be the case.
406     public static final String ACTION_TRIGGER_IDLE = "com.android.server.ACTION_TRIGGER_IDLE";
407
408     /** Control over CPU and battery monitoring */
409     // write battery stats every 30 minutes.
410     static final long BATTERY_STATS_TIME = 30 * 60 * 1000;
411     static final boolean MONITOR_CPU_USAGE = true;
412     // don't sample cpu less than every 5 seconds.
413     static final long MONITOR_CPU_MIN_TIME = 5 * 1000;
414     // wait possibly forever for next cpu sample.
415     static final long MONITOR_CPU_MAX_TIME = 0x0fffffff;
416     static final boolean MONITOR_THREAD_CPU_USAGE = false;
417
418     // The flags that are set for all calls we make to the package manager.
419     static final int STOCK_PM_FLAGS = PackageManager.GET_SHARED_LIBRARY_FILES;
420
421     static final String SYSTEM_DEBUGGABLE = "ro.debuggable";
422
423     static final boolean IS_USER_BUILD = "user".equals(Build.TYPE);
424
425     // Amount of time after a call to stopAppSwitches() during which we will
426     // prevent further untrusted switches from happening.
427     static final long APP_SWITCH_DELAY_TIME = 5*1000;
428
429     // How long we wait for a launched process to attach to the activity manager
430     // before we decide it's never going to come up for real.
431     static final int PROC_START_TIMEOUT = 10*1000;
432     // How long we wait for an attached process to publish its content providers
433     // before we decide it must be hung.
434     static final int CONTENT_PROVIDER_PUBLISH_TIMEOUT = 10*1000;
435
436     // How long we will retain processes hosting content providers in the "last activity"
437     // state before allowing them to drop down to the regular cached LRU list.  This is
438     // to avoid thrashing of provider processes under low memory situations.
439     static final int CONTENT_PROVIDER_RETAIN_TIME = 20*1000;
440
441     // How long we wait for a launched process to attach to the activity manager
442     // before we decide it's never going to come up for real, when the process was
443     // started with a wrapper for instrumentation (such as Valgrind) because it
444     // could take much longer than usual.
445     static final int PROC_START_TIMEOUT_WITH_WRAPPER = 1200*1000;
446
447     // How long to wait after going idle before forcing apps to GC.
448     static final int GC_TIMEOUT = 5*1000;
449
450     // The minimum amount of time between successive GC requests for a process.
451     static final int GC_MIN_INTERVAL = 60*1000;
452
453     // The minimum amount of time between successive PSS requests for a process.
454     static final int FULL_PSS_MIN_INTERVAL = 10*60*1000;
455
456     // The minimum amount of time between successive PSS requests for a process
457     // when the request is due to the memory state being lowered.
458     static final int FULL_PSS_LOWERED_INTERVAL = 2*60*1000;
459
460     // The rate at which we check for apps using excessive power -- 15 mins.
461     static final int POWER_CHECK_DELAY = (DEBUG_POWER_QUICK ? 2 : 15) * 60*1000;
462
463     // The minimum sample duration we will allow before deciding we have
464     // enough data on wake locks to start killing things.
465     static final int WAKE_LOCK_MIN_CHECK_DURATION = (DEBUG_POWER_QUICK ? 1 : 5) * 60*1000;
466
467     // The minimum sample duration we will allow before deciding we have
468     // enough data on CPU usage to start killing things.
469     static final int CPU_MIN_CHECK_DURATION = (DEBUG_POWER_QUICK ? 1 : 5) * 60*1000;
470
471     // How long we allow a receiver to run before giving up on it.
472     static final int BROADCAST_FG_TIMEOUT = 10*1000;
473     static final int BROADCAST_BG_TIMEOUT = 60*1000;
474
475     // How long we wait until we timeout on key dispatching.
476     static final int KEY_DISPATCHING_TIMEOUT = 5*1000;
477
478     // How long we wait until we timeout on key dispatching during instrumentation.
479     static final int INSTRUMENTATION_KEY_DISPATCHING_TIMEOUT = 60*1000;
480
481     // This is the amount of time an app needs to be running a foreground service before
482     // we will consider it to be doing interaction for usage stats.
483     static final int SERVICE_USAGE_INTERACTION_TIME = 30*60*1000;
484
485     // Maximum amount of time we will allow to elapse before re-reporting usage stats
486     // interaction with foreground processes.
487     static final long USAGE_STATS_INTERACTION_INTERVAL = 24*60*60*1000L;
488
489     // This is the amount of time we allow an app to settle after it goes into the background,
490     // before we start restricting what it can do.
491     static final int BACKGROUND_SETTLE_TIME = 1*60*1000;
492
493     // How long to wait in getAssistContextExtras for the activity and foreground services
494     // to respond with the result.
495     static final int PENDING_ASSIST_EXTRAS_TIMEOUT = 500;
496
497     // How long top wait when going through the modern assist (which doesn't need to block
498     // on getting this result before starting to launch its UI).
499     static final int PENDING_ASSIST_EXTRAS_LONG_TIMEOUT = 2000;
500
501     // Maximum number of persisted Uri grants a package is allowed
502     static final int MAX_PERSISTED_URI_GRANTS = 128;
503
504     static final int MY_PID = Process.myPid();
505
506     static final String[] EMPTY_STRING_ARRAY = new String[0];
507
508     // How many bytes to write into the dropbox log before truncating
509     static final int DROPBOX_MAX_SIZE = 192 * 1024;
510     // Assumes logcat entries average around 100 bytes; that's not perfect stack traces count
511     // as one line, but close enough for now.
512     static final int RESERVED_BYTES_PER_LOGCAT_LINE = 100;
513
514     // Access modes for handleIncomingUser.
515     static final int ALLOW_NON_FULL = 0;
516     static final int ALLOW_NON_FULL_IN_PROFILE = 1;
517     static final int ALLOW_FULL_ONLY = 2;
518
519     // Delay in notifying task stack change listeners (in millis)
520     static final int NOTIFY_TASK_STACK_CHANGE_LISTENERS_DELAY = 100;
521
522     // Necessary ApplicationInfo flags to mark an app as persistent
523     private static final int PERSISTENT_MASK =
524             ApplicationInfo.FLAG_SYSTEM|ApplicationInfo.FLAG_PERSISTENT;
525
526     // Intent sent when remote bugreport collection has been completed
527     private static final String INTENT_REMOTE_BUGREPORT_FINISHED =
528             "android.intent.action.REMOTE_BUGREPORT_FINISHED";
529
530     // Delay to disable app launch boost
531     static final int APP_BOOST_MESSAGE_DELAY = 3000;
532     // Lower delay than APP_BOOST_MESSAGE_DELAY to disable the boost
533     static final int APP_BOOST_TIMEOUT = 2500;
534
535     // Used to indicate that a task is removed it should also be removed from recents.
536     private static final boolean REMOVE_FROM_RECENTS = true;
537     // Used to indicate that an app transition should be animated.
538     static final boolean ANIMATE = true;
539
540     // Determines whether to take full screen screenshots
541     static final boolean TAKE_FULLSCREEN_SCREENSHOTS = true;
542     public static final float FULLSCREEN_SCREENSHOT_SCALE = 0.6f;
543
544     private static native int nativeMigrateToBoost();
545     private static native int nativeMigrateFromBoost();
546     private boolean mIsBoosted = false;
547     private long mBoostStartTime = 0;
548
549     /** All system services */
550     SystemServiceManager mSystemServiceManager;
551
552     private Installer mInstaller;
553
554     /** Run all ActivityStacks through this */
555     final ActivityStackSupervisor mStackSupervisor;
556
557     final ActivityStarter mActivityStarter;
558
559     /** Task stack change listeners. */
560     private final RemoteCallbackList<ITaskStackListener> mTaskStackListeners =
561             new RemoteCallbackList<ITaskStackListener>();
562
563     final InstrumentationReporter mInstrumentationReporter = new InstrumentationReporter();
564
565     public IntentFirewall mIntentFirewall;
566
567     // Whether we should show our dialogs (ANR, crash, etc) or just perform their
568     // default actuion automatically.  Important for devices without direct input
569     // devices.
570     private boolean mShowDialogs = true;
571     private boolean mInVrMode = false;
572
573     // Whether we should use SCHED_FIFO for UI and RenderThreads.
574     private boolean mUseFifoUiScheduling = false;
575
576     BroadcastQueue mFgBroadcastQueue;
577     BroadcastQueue mBgBroadcastQueue;
578     // Convenient for easy iteration over the queues. Foreground is first
579     // so that dispatch of foreground broadcasts gets precedence.
580     final BroadcastQueue[] mBroadcastQueues = new BroadcastQueue[2];
581
582     BroadcastStats mLastBroadcastStats;
583     BroadcastStats mCurBroadcastStats;
584
585     BroadcastQueue broadcastQueueForIntent(Intent intent) {
586         final boolean isFg = (intent.getFlags() & Intent.FLAG_RECEIVER_FOREGROUND) != 0;
587         if (DEBUG_BROADCAST_BACKGROUND) Slog.i(TAG_BROADCAST,
588                 "Broadcast intent " + intent + " on "
589                 + (isFg ? "foreground" : "background") + " queue");
590         return (isFg) ? mFgBroadcastQueue : mBgBroadcastQueue;
591     }
592
593     /**
594      * Activity we have told the window manager to have key focus.
595      */
596     ActivityRecord mFocusedActivity = null;
597
598     /**
599      * User id of the last activity mFocusedActivity was set to.
600      */
601     private int mLastFocusedUserId;
602
603     /**
604      * If non-null, we are tracking the time the user spends in the currently focused app.
605      */
606     private AppTimeTracker mCurAppTimeTracker;
607
608     /**
609      * List of intents that were used to start the most recent tasks.
610      */
611     final RecentTasks mRecentTasks;
612
613     /**
614      * For addAppTask: cached of the last activity component that was added.
615      */
616     ComponentName mLastAddedTaskComponent;
617
618     /**
619      * For addAppTask: cached of the last activity uid that was added.
620      */
621     int mLastAddedTaskUid;
622
623     /**
624      * For addAppTask: cached of the last ActivityInfo that was added.
625      */
626     ActivityInfo mLastAddedTaskActivity;
627
628     /**
629      * List of packages whitelisted by DevicePolicyManager for locktask. Indexed by userId.
630      */
631     SparseArray<String[]> mLockTaskPackages = new SparseArray<>();
632
633     /**
634      * The package name of the DeviceOwner. This package is not permitted to have its data cleared.
635      */
636     String mDeviceOwnerName;
637
638     final UserController mUserController;
639
640     final AppErrors mAppErrors;
641
642     boolean mDoingSetFocusedActivity;
643
644     public boolean canShowErrorDialogs() {
645         return mShowDialogs && !mSleeping && !mShuttingDown
646                 && mLockScreenShown != LOCK_SCREEN_SHOWN;
647     }
648
649     private static final class PriorityState {
650         // Acts as counter for number of synchronized region that needs to acquire 'this' as a lock
651         // the current thread is currently in. When it drops down to zero, we will no longer boost
652         // the thread's priority.
653         private int regionCounter = 0;
654
655         // The thread's previous priority before boosting.
656         private int prevPriority = Integer.MIN_VALUE;
657     }
658
659     static ThreadLocal<PriorityState> sThreadPriorityState = new ThreadLocal<PriorityState>() {
660         @Override protected PriorityState initialValue() {
661             return new PriorityState();
662         }
663     };
664
665     static void boostPriorityForLockedSection() {
666         int tid = Process.myTid();
667         int prevPriority = Process.getThreadPriority(tid);
668         PriorityState state = sThreadPriorityState.get();
669         if (state.regionCounter == 0 && prevPriority > -2) {
670             state.prevPriority = prevPriority;
671             Process.setThreadPriority(tid, -2);
672         }
673         state.regionCounter++;
674     }
675
676     static void resetPriorityAfterLockedSection() {
677         PriorityState state = sThreadPriorityState.get();
678         state.regionCounter--;
679         if (state.regionCounter == 0 && state.prevPriority > -2) {
680             Process.setThreadPriority(Process.myTid(), state.prevPriority);
681         }
682     }
683
684     public class PendingAssistExtras extends Binder implements Runnable {
685         public final ActivityRecord activity;
686         public final Bundle extras;
687         public final Intent intent;
688         public final String hint;
689         public final IResultReceiver receiver;
690         public final int userHandle;
691         public boolean haveResult = false;
692         public Bundle result = null;
693         public AssistStructure structure = null;
694         public AssistContent content = null;
695         public Bundle receiverExtras;
696
697         public PendingAssistExtras(ActivityRecord _activity, Bundle _extras, Intent _intent,
698                 String _hint, IResultReceiver _receiver, Bundle _receiverExtras, int _userHandle) {
699             activity = _activity;
700             extras = _extras;
701             intent = _intent;
702             hint = _hint;
703             receiver = _receiver;
704             receiverExtras = _receiverExtras;
705             userHandle = _userHandle;
706         }
707         @Override
708         public void run() {
709             Slog.w(TAG, "getAssistContextExtras failed: timeout retrieving from " + activity);
710             synchronized (this) {
711                 haveResult = true;
712                 notifyAll();
713             }
714             pendingAssistExtrasTimedOut(this);
715         }
716     }
717
718     final ArrayList<PendingAssistExtras> mPendingAssistExtras
719             = new ArrayList<PendingAssistExtras>();
720
721     /**
722      * Process management.
723      */
724     final ProcessList mProcessList = new ProcessList();
725
726     /**
727      * All of the applications we currently have running organized by name.
728      * The keys are strings of the application package name (as
729      * returned by the package manager), and the keys are ApplicationRecord
730      * objects.
731      */
732     final ProcessMap<ProcessRecord> mProcessNames = new ProcessMap<ProcessRecord>();
733
734     /**
735      * Tracking long-term execution of processes to look for abuse and other
736      * bad app behavior.
737      */
738     final ProcessStatsService mProcessStats;
739
740     /**
741      * The currently running isolated processes.
742      */
743     final SparseArray<ProcessRecord> mIsolatedProcesses = new SparseArray<ProcessRecord>();
744
745     /**
746      * Counter for assigning isolated process uids, to avoid frequently reusing the
747      * same ones.
748      */
749     int mNextIsolatedProcessUid = 0;
750
751     /**
752      * The currently running heavy-weight process, if any.
753      */
754     ProcessRecord mHeavyWeightProcess = null;
755
756     /**
757      * All of the processes we currently have running organized by pid.
758      * The keys are the pid running the application.
759      *
760      * <p>NOTE: This object is protected by its own lock, NOT the global
761      * activity manager lock!
762      */
763     final SparseArray<ProcessRecord> mPidsSelfLocked = new SparseArray<ProcessRecord>();
764
765     /**
766      * All of the processes that have been forced to be foreground.  The key
767      * is the pid of the caller who requested it (we hold a death
768      * link on it).
769      */
770     abstract class ForegroundToken implements IBinder.DeathRecipient {
771         int pid;
772         IBinder token;
773     }
774     final SparseArray<ForegroundToken> mForegroundProcesses = new SparseArray<ForegroundToken>();
775
776     /**
777      * List of records for processes that someone had tried to start before the
778      * system was ready.  We don't start them at that point, but ensure they
779      * are started by the time booting is complete.
780      */
781     final ArrayList<ProcessRecord> mProcessesOnHold = new ArrayList<ProcessRecord>();
782
783     /**
784      * List of persistent applications that are in the process
785      * of being started.
786      */
787     final ArrayList<ProcessRecord> mPersistentStartingProcesses = new ArrayList<ProcessRecord>();
788
789     /**
790      * Processes that are being forcibly torn down.
791      */
792     final ArrayList<ProcessRecord> mRemovedProcesses = new ArrayList<ProcessRecord>();
793
794     /**
795      * List of running applications, sorted by recent usage.
796      * The first entry in the list is the least recently used.
797      */
798     final ArrayList<ProcessRecord> mLruProcesses = new ArrayList<ProcessRecord>();
799
800     /**
801      * Where in mLruProcesses that the processes hosting activities start.
802      */
803     int mLruProcessActivityStart = 0;
804
805     /**
806      * Where in mLruProcesses that the processes hosting services start.
807      * This is after (lower index) than mLruProcessesActivityStart.
808      */
809     int mLruProcessServiceStart = 0;
810
811     /**
812      * List of processes that should gc as soon as things are idle.
813      */
814     final ArrayList<ProcessRecord> mProcessesToGc = new ArrayList<ProcessRecord>();
815
816     /**
817      * Processes we want to collect PSS data from.
818      */
819     final ArrayList<ProcessRecord> mPendingPssProcesses = new ArrayList<ProcessRecord>();
820
821     private boolean mBinderTransactionTrackingEnabled = false;
822
823     /**
824      * Last time we requested PSS data of all processes.
825      */
826     long mLastFullPssTime = SystemClock.uptimeMillis();
827
828     /**
829      * If set, the next time we collect PSS data we should do a full collection
830      * with data from native processes and the kernel.
831      */
832     boolean mFullPssPending = false;
833
834     /**
835      * This is the process holding what we currently consider to be
836      * the "home" activity.
837      */
838     ProcessRecord mHomeProcess;
839
840     /**
841      * This is the process holding the activity the user last visited that
842      * is in a different process from the one they are currently in.
843      */
844     ProcessRecord mPreviousProcess;
845
846     /**
847      * The time at which the previous process was last visible.
848      */
849     long mPreviousProcessVisibleTime;
850
851     /**
852      * Track all uids that have actively running processes.
853      */
854     final SparseArray<UidRecord> mActiveUids = new SparseArray<>();
855
856     /**
857      * This is for verifying the UID report flow.
858      */
859     static final boolean VALIDATE_UID_STATES = true;
860     final SparseArray<UidRecord> mValidateUids = new SparseArray<>();
861
862     /**
863      * Packages that the user has asked to have run in screen size
864      * compatibility mode instead of filling the screen.
865      */
866     final CompatModePackages mCompatModePackages;
867
868     /**
869      * Set of IntentSenderRecord objects that are currently active.
870      */
871     final HashMap<PendingIntentRecord.Key, WeakReference<PendingIntentRecord>> mIntentSenderRecords
872             = new HashMap<PendingIntentRecord.Key, WeakReference<PendingIntentRecord>>();
873
874     /**
875      * Fingerprints (hashCode()) of stack traces that we've
876      * already logged DropBox entries for.  Guarded by itself.  If
877      * something (rogue user app) forces this over
878      * MAX_DUP_SUPPRESSED_STACKS entries, the contents are cleared.
879      */
880     private final HashSet<Integer> mAlreadyLoggedViolatedStacks = new HashSet<Integer>();
881     private static final int MAX_DUP_SUPPRESSED_STACKS = 5000;
882
883     /**
884      * Strict Mode background batched logging state.
885      *
886      * The string buffer is guarded by itself, and its lock is also
887      * used to determine if another batched write is already
888      * in-flight.
889      */
890     private final StringBuilder mStrictModeBuffer = new StringBuilder();
891
892     /**
893      * Keeps track of all IIntentReceivers that have been registered for broadcasts.
894      * Hash keys are the receiver IBinder, hash value is a ReceiverList.
895      */
896     final HashMap<IBinder, ReceiverList> mRegisteredReceivers = new HashMap<>();
897
898     /**
899      * Resolver for broadcast intents to registered receivers.
900      * Holds BroadcastFilter (subclass of IntentFilter).
901      */
902     final IntentResolver<BroadcastFilter, BroadcastFilter> mReceiverResolver
903             = new IntentResolver<BroadcastFilter, BroadcastFilter>() {
904         @Override
905         protected boolean allowFilterResult(
906                 BroadcastFilter filter, List<BroadcastFilter> dest) {
907             IBinder target = filter.receiverList.receiver.asBinder();
908             for (int i = dest.size() - 1; i >= 0; i--) {
909                 if (dest.get(i).receiverList.receiver.asBinder() == target) {
910                     return false;
911                 }
912             }
913             return true;
914         }
915
916         @Override
917         protected BroadcastFilter newResult(BroadcastFilter filter, int match, int userId) {
918             if (userId == UserHandle.USER_ALL || filter.owningUserId == UserHandle.USER_ALL
919                     || userId == filter.owningUserId) {
920                 return super.newResult(filter, match, userId);
921             }
922             return null;
923         }
924
925         @Override
926         protected BroadcastFilter[] newArray(int size) {
927             return new BroadcastFilter[size];
928         }
929
930         @Override
931         protected boolean isPackageForFilter(String packageName, BroadcastFilter filter) {
932             return packageName.equals(filter.packageName);
933         }
934     };
935
936     /**
937      * State of all active sticky broadcasts per user.  Keys are the action of the
938      * sticky Intent, values are an ArrayList of all broadcasted intents with
939      * that action (which should usually be one).  The SparseArray is keyed
940      * by the user ID the sticky is for, and can include UserHandle.USER_ALL
941      * for stickies that are sent to all users.
942      */
943     final SparseArray<ArrayMap<String, ArrayList<Intent>>> mStickyBroadcasts =
944             new SparseArray<ArrayMap<String, ArrayList<Intent>>>();
945
946     final ActiveServices mServices;
947
948     final static class Association {
949         final int mSourceUid;
950         final String mSourceProcess;
951         final int mTargetUid;
952         final ComponentName mTargetComponent;
953         final String mTargetProcess;
954
955         int mCount;
956         long mTime;
957
958         int mNesting;
959         long mStartTime;
960
961         // states of the source process when the bind occurred.
962         int mLastState = ActivityManager.MAX_PROCESS_STATE + 1;
963         long mLastStateUptime;
964         long[] mStateTimes = new long[ActivityManager.MAX_PROCESS_STATE
965                 - ActivityManager.MIN_PROCESS_STATE+1];
966
967         Association(int sourceUid, String sourceProcess, int targetUid,
968                 ComponentName targetComponent, String targetProcess) {
969             mSourceUid = sourceUid;
970             mSourceProcess = sourceProcess;
971             mTargetUid = targetUid;
972             mTargetComponent = targetComponent;
973             mTargetProcess = targetProcess;
974         }
975     }
976
977     /**
978      * When service association tracking is enabled, this is all of the associations we
979      * have seen.  Mapping is target uid -> target component -> source uid -> source process name
980      * -> association data.
981      */
982     final SparseArray<ArrayMap<ComponentName, SparseArray<ArrayMap<String, Association>>>>
983             mAssociations = new SparseArray<>();
984     boolean mTrackingAssociations;
985
986     /**
987      * Backup/restore process management
988      */
989     String mBackupAppName = null;
990     BackupRecord mBackupTarget = null;
991
992     final ProviderMap mProviderMap;
993
994     /**
995      * List of content providers who have clients waiting for them.  The
996      * application is currently being launched and the provider will be
997      * removed from this list once it is published.
998      */
999     final ArrayList<ContentProviderRecord> mLaunchingProviders
1000             = new ArrayList<ContentProviderRecord>();
1001
1002     /**
1003      * File storing persisted {@link #mGrantedUriPermissions}.
1004      */
1005     private final AtomicFile mGrantFile;
1006
1007     /** XML constants used in {@link #mGrantFile} */
1008     private static final String TAG_URI_GRANTS = "uri-grants";
1009     private static final String TAG_URI_GRANT = "uri-grant";
1010     private static final String ATTR_USER_HANDLE = "userHandle";
1011     private static final String ATTR_SOURCE_USER_ID = "sourceUserId";
1012     private static final String ATTR_TARGET_USER_ID = "targetUserId";
1013     private static final String ATTR_SOURCE_PKG = "sourcePkg";
1014     private static final String ATTR_TARGET_PKG = "targetPkg";
1015     private static final String ATTR_URI = "uri";
1016     private static final String ATTR_MODE_FLAGS = "modeFlags";
1017     private static final String ATTR_CREATED_TIME = "createdTime";
1018     private static final String ATTR_PREFIX = "prefix";
1019
1020     /**
1021      * Global set of specific {@link Uri} permissions that have been granted.
1022      * This optimized lookup structure maps from {@link UriPermission#targetUid}
1023      * to {@link UriPermission#uri} to {@link UriPermission}.
1024      */
1025     @GuardedBy("this")
1026     private final SparseArray<ArrayMap<GrantUri, UriPermission>>
1027             mGrantedUriPermissions = new SparseArray<ArrayMap<GrantUri, UriPermission>>();
1028
1029     public static class GrantUri {
1030         public final int sourceUserId;
1031         public final Uri uri;
1032         public boolean prefix;
1033
1034         public GrantUri(int sourceUserId, Uri uri, boolean prefix) {
1035             this.sourceUserId = sourceUserId;
1036             this.uri = uri;
1037             this.prefix = prefix;
1038         }
1039
1040         @Override
1041         public int hashCode() {
1042             int hashCode = 1;
1043             hashCode = 31 * hashCode + sourceUserId;
1044             hashCode = 31 * hashCode + uri.hashCode();
1045             hashCode = 31 * hashCode + (prefix ? 1231 : 1237);
1046             return hashCode;
1047         }
1048
1049         @Override
1050         public boolean equals(Object o) {
1051             if (o instanceof GrantUri) {
1052                 GrantUri other = (GrantUri) o;
1053                 return uri.equals(other.uri) && (sourceUserId == other.sourceUserId)
1054                         && prefix == other.prefix;
1055             }
1056             return false;
1057         }
1058
1059         @Override
1060         public String toString() {
1061             String result = Integer.toString(sourceUserId) + " @ " + uri.toString();
1062             if (prefix) result += " [prefix]";
1063             return result;
1064         }
1065
1066         public String toSafeString() {
1067             String result = Integer.toString(sourceUserId) + " @ " + uri.toSafeString();
1068             if (prefix) result += " [prefix]";
1069             return result;
1070         }
1071
1072         public static GrantUri resolve(int defaultSourceUserHandle, Uri uri) {
1073             return new GrantUri(ContentProvider.getUserIdFromUri(uri, defaultSourceUserHandle),
1074                     ContentProvider.getUriWithoutUserId(uri), false);
1075         }
1076     }
1077
1078     CoreSettingsObserver mCoreSettingsObserver;
1079
1080     FontScaleSettingObserver mFontScaleSettingObserver;
1081
1082     private final class FontScaleSettingObserver extends ContentObserver {
1083         private final Uri mFontScaleUri = Settings.System.getUriFor(FONT_SCALE);
1084
1085         public FontScaleSettingObserver() {
1086             super(mHandler);
1087             ContentResolver resolver = mContext.getContentResolver();
1088             resolver.registerContentObserver(mFontScaleUri, false, this, UserHandle.USER_ALL);
1089         }
1090
1091         @Override
1092         public void onChange(boolean selfChange, Uri uri, @UserIdInt int userId) {
1093             if (mFontScaleUri.equals(uri)) {
1094                 updateFontScaleIfNeeded(userId);
1095             }
1096         }
1097     }
1098
1099     /**
1100      * Thread-local storage used to carry caller permissions over through
1101      * indirect content-provider access.
1102      */
1103     private class Identity {
1104         public final IBinder token;
1105         public final int pid;
1106         public final int uid;
1107
1108         Identity(IBinder _token, int _pid, int _uid) {
1109             token = _token;
1110             pid = _pid;
1111             uid = _uid;
1112         }
1113     }
1114
1115     private static final ThreadLocal<Identity> sCallerIdentity = new ThreadLocal<Identity>();
1116
1117     /**
1118      * All information we have collected about the runtime performance of
1119      * any user id that can impact battery performance.
1120      */
1121     final BatteryStatsService mBatteryStatsService;
1122
1123     /**
1124      * Information about component usage
1125      */
1126     UsageStatsManagerInternal mUsageStatsService;
1127
1128     /**
1129      * Access to DeviceIdleController service.
1130      */
1131     DeviceIdleController.LocalService mLocalDeviceIdleController;
1132
1133     /**
1134      * Information about and control over application operations
1135      */
1136     final AppOpsService mAppOpsService;
1137
1138     /**
1139      * Current configuration information.  HistoryRecord objects are given
1140      * a reference to this object to indicate which configuration they are
1141      * currently running in, so this object must be kept immutable.
1142      */
1143     Configuration mConfiguration = new Configuration();
1144
1145     /**
1146      * Current sequencing integer of the configuration, for skipping old
1147      * configurations.
1148      */
1149     int mConfigurationSeq = 0;
1150
1151     boolean mSuppressResizeConfigChanges = false;
1152
1153     /**
1154      * Hardware-reported OpenGLES version.
1155      */
1156     final int GL_ES_VERSION;
1157
1158     /**
1159      * List of initialization arguments to pass to all processes when binding applications to them.
1160      * For example, references to the commonly used services.
1161      */
1162     HashMap<String, IBinder> mAppBindArgs;
1163     HashMap<String, IBinder> mIsolatedAppBindArgs;
1164
1165     /**
1166      * Temporary to avoid allocations.  Protected by main lock.
1167      */
1168     final StringBuilder mStringBuilder = new StringBuilder(256);
1169
1170     /**
1171      * Used to control how we initialize the service.
1172      */
1173     ComponentName mTopComponent;
1174     String mTopAction = Intent.ACTION_MAIN;
1175     String mTopData;
1176
1177     volatile boolean mProcessesReady = false;
1178     volatile boolean mSystemReady = false;
1179     volatile boolean mOnBattery = false;
1180     volatile int mFactoryTest;
1181
1182     @GuardedBy("this") boolean mBooting = false;
1183     @GuardedBy("this") boolean mCallFinishBooting = false;
1184     @GuardedBy("this") boolean mBootAnimationComplete = false;
1185     @GuardedBy("this") boolean mLaunchWarningShown = false;
1186     @GuardedBy("this") boolean mCheckedForSetup = false;
1187
1188     Context mContext;
1189
1190     /**
1191      * The time at which we will allow normal application switches again,
1192      * after a call to {@link #stopAppSwitches()}.
1193      */
1194     long mAppSwitchesAllowedTime;
1195
1196     /**
1197      * This is set to true after the first switch after mAppSwitchesAllowedTime
1198      * is set; any switches after that will clear the time.
1199      */
1200     boolean mDidAppSwitch;
1201
1202     /**
1203      * Last time (in realtime) at which we checked for power usage.
1204      */
1205     long mLastPowerCheckRealtime;
1206
1207     /**
1208      * Last time (in uptime) at which we checked for power usage.
1209      */
1210     long mLastPowerCheckUptime;
1211
1212     /**
1213      * Set while we are wanting to sleep, to prevent any
1214      * activities from being started/resumed.
1215      *
1216      * TODO(b/33594039): Clarify the actual state transitions represented by mSleeping.
1217      *
1218      * Currently mSleeping is set to true when transitioning into the sleep state, and remains true
1219      * while in the sleep state until there is a pending transition out of sleep, in which case
1220      * mSleeping is set to false, and remains false while awake.
1221      *
1222      * Whether mSleeping can quickly toggled between true/false without the device actually
1223      * display changing states is undefined.
1224      */
1225     private boolean mSleeping = false;
1226
1227     /**
1228      * The process state used for processes that are running the top activities.
1229      * This changes between TOP and TOP_SLEEPING to following mSleeping.
1230      */
1231     int mTopProcessState = ActivityManager.PROCESS_STATE_TOP;
1232
1233     /**
1234      * Set while we are running a voice interaction.  This overrides
1235      * sleeping while it is active.
1236      */
1237     private IVoiceInteractionSession mRunningVoice;
1238
1239     /**
1240      * For some direct access we need to power manager.
1241      */
1242     PowerManagerInternal mLocalPowerManager;
1243
1244     /**
1245      * We want to hold a wake lock while running a voice interaction session, since
1246      * this may happen with the screen off and we need to keep the CPU running to
1247      * be able to continue to interact with the user.
1248      */
1249     PowerManager.WakeLock mVoiceWakeLock;
1250
1251     /**
1252      * State of external calls telling us if the device is awake or asleep.
1253      */
1254     private int mWakefulness = PowerManagerInternal.WAKEFULNESS_AWAKE;
1255
1256     /**
1257      * A list of tokens that cause the top activity to be put to sleep.
1258      * They are used by components that may hide and block interaction with underlying
1259      * activities.
1260      */
1261     final ArrayList<SleepToken> mSleepTokens = new ArrayList<SleepToken>();
1262
1263     static final int LOCK_SCREEN_HIDDEN = 0;
1264     static final int LOCK_SCREEN_LEAVING = 1;
1265     static final int LOCK_SCREEN_SHOWN = 2;
1266     /**
1267      * State of external call telling us if the lock screen is shown.
1268      */
1269     int mLockScreenShown = LOCK_SCREEN_HIDDEN;
1270
1271     /**
1272      * Set if we are shutting down the system, similar to sleeping.
1273      */
1274     boolean mShuttingDown = false;
1275
1276     /**
1277      * Current sequence id for oom_adj computation traversal.
1278      */
1279     int mAdjSeq = 0;
1280
1281     /**
1282      * Current sequence id for process LRU updating.
1283      */
1284     int mLruSeq = 0;
1285
1286     /**
1287      * Keep track of the non-cached/empty process we last found, to help
1288      * determine how to distribute cached/empty processes next time.
1289      */
1290     int mNumNonCachedProcs = 0;
1291
1292     /**
1293      * Keep track of the number of cached hidden procs, to balance oom adj
1294      * distribution between those and empty procs.
1295      */
1296     int mNumCachedHiddenProcs = 0;
1297
1298     /**
1299      * Keep track of the number of service processes we last found, to
1300      * determine on the next iteration which should be B services.
1301      */
1302     int mNumServiceProcs = 0;
1303     int mNewNumAServiceProcs = 0;
1304     int mNewNumServiceProcs = 0;
1305
1306     /**
1307      * Allow the current computed overall memory level of the system to go down?
1308      * This is set to false when we are killing processes for reasons other than
1309      * memory management, so that the now smaller process list will not be taken as
1310      * an indication that memory is tighter.
1311      */
1312     boolean mAllowLowerMemLevel = false;
1313
1314     /**
1315      * The last computed memory level, for holding when we are in a state that
1316      * processes are going away for other reasons.
1317      */
1318     int mLastMemoryLevel = ProcessStats.ADJ_MEM_FACTOR_NORMAL;
1319
1320     /**
1321      * The last total number of process we have, to determine if changes actually look
1322      * like a shrinking number of process due to lower RAM.
1323      */
1324     int mLastNumProcesses;
1325
1326     /**
1327      * The uptime of the last time we performed idle maintenance.
1328      */
1329     long mLastIdleTime = SystemClock.uptimeMillis();
1330
1331     /**
1332      * Total time spent with RAM that has been added in the past since the last idle time.
1333      */
1334     long mLowRamTimeSinceLastIdle = 0;
1335
1336     /**
1337      * If RAM is currently low, when that horrible situation started.
1338      */
1339     long mLowRamStartTime = 0;
1340
1341     /**
1342      * For reporting to battery stats the current top application.
1343      */
1344     private String mCurResumedPackage = null;
1345     private int mCurResumedUid = -1;
1346
1347     /**
1348      * For reporting to battery stats the apps currently running foreground
1349      * service.  The ProcessMap is package/uid tuples; each of these contain
1350      * an array of the currently foreground processes.
1351      */
1352     final ProcessMap<ArrayList<ProcessRecord>> mForegroundPackages
1353             = new ProcessMap<ArrayList<ProcessRecord>>();
1354
1355     /**
1356      * This is set if we had to do a delayed dexopt of an app before launching
1357      * it, to increase the ANR timeouts in that case.
1358      */
1359     boolean mDidDexOpt;
1360
1361     /**
1362      * Set if the systemServer made a call to enterSafeMode.
1363      */
1364     boolean mSafeMode;
1365
1366     /**
1367      * If true, we are running under a test environment so will sample PSS from processes
1368      * much more rapidly to try to collect better data when the tests are rapidly
1369      * running through apps.
1370      */
1371     boolean mTestPssMode = false;
1372
1373     String mDebugApp = null;
1374     boolean mWaitForDebugger = false;
1375     boolean mDebugTransient = false;
1376     String mOrigDebugApp = null;
1377     boolean mOrigWaitForDebugger = false;
1378     boolean mAlwaysFinishActivities = false;
1379     boolean mLenientBackgroundCheck = false;
1380     boolean mForceResizableActivities;
1381     boolean mSupportsMultiWindow;
1382     boolean mSupportsFreeformWindowManagement;
1383     boolean mSupportsPictureInPicture;
1384     boolean mSupportsLeanbackOnly;
1385     Rect mDefaultPinnedStackBounds;
1386     IActivityController mController = null;
1387     boolean mControllerIsAMonkey = false;
1388     String mProfileApp = null;
1389     ProcessRecord mProfileProc = null;
1390     String mProfileFile;
1391     ParcelFileDescriptor mProfileFd;
1392     int mSamplingInterval = 0;
1393     boolean mAutoStopProfiler = false;
1394     int mProfileType = 0;
1395     final ProcessMap<Pair<Long, String>> mMemWatchProcesses = new ProcessMap<>();
1396     String mMemWatchDumpProcName;
1397     String mMemWatchDumpFile;
1398     int mMemWatchDumpPid;
1399     int mMemWatchDumpUid;
1400     String mTrackAllocationApp = null;
1401     String mNativeDebuggingApp = null;
1402
1403     final long[] mTmpLong = new long[2];
1404
1405     static final class ProcessChangeItem {
1406         static final int CHANGE_ACTIVITIES = 1<<0;
1407         static final int CHANGE_PROCESS_STATE = 1<<1;
1408         int changes;
1409         int uid;
1410         int pid;
1411         int processState;
1412         boolean foregroundActivities;
1413     }
1414
1415     final RemoteCallbackList<IProcessObserver> mProcessObservers = new RemoteCallbackList<>();
1416     ProcessChangeItem[] mActiveProcessChanges = new ProcessChangeItem[5];
1417
1418     final ArrayList<ProcessChangeItem> mPendingProcessChanges = new ArrayList<>();
1419     final ArrayList<ProcessChangeItem> mAvailProcessChanges = new ArrayList<>();
1420
1421     final RemoteCallbackList<IUidObserver> mUidObservers = new RemoteCallbackList<>();
1422     UidRecord.ChangeItem[] mActiveUidChanges = new UidRecord.ChangeItem[5];
1423
1424     final ArrayList<UidRecord.ChangeItem> mPendingUidChanges = new ArrayList<>();
1425     final ArrayList<UidRecord.ChangeItem> mAvailUidChanges = new ArrayList<>();
1426
1427     /**
1428      * Runtime CPU use collection thread.  This object's lock is used to
1429      * perform synchronization with the thread (notifying it to run).
1430      */
1431     final Thread mProcessCpuThread;
1432
1433     /**
1434      * Used to collect per-process CPU use for ANRs, battery stats, etc.
1435      * Must acquire this object's lock when accessing it.
1436      * NOTE: this lock will be held while doing long operations (trawling
1437      * through all processes in /proc), so it should never be acquired by
1438      * any critical paths such as when holding the main activity manager lock.
1439      */
1440     final ProcessCpuTracker mProcessCpuTracker = new ProcessCpuTracker(
1441             MONITOR_THREAD_CPU_USAGE);
1442     final AtomicLong mLastCpuTime = new AtomicLong(0);
1443     final AtomicBoolean mProcessCpuMutexFree = new AtomicBoolean(true);
1444
1445     long mLastWriteTime = 0;
1446
1447     /**
1448      * Used to retain an update lock when the foreground activity is in
1449      * immersive mode.
1450      */
1451     final UpdateLock mUpdateLock = new UpdateLock("immersive");
1452
1453     /**
1454      * Set to true after the system has finished booting.
1455      */
1456     boolean mBooted = false;
1457
1458     int mProcessLimit = ProcessList.MAX_CACHED_APPS;
1459     int mProcessLimitOverride = -1;
1460
1461     WindowManagerService mWindowManager;
1462     final ActivityThread mSystemThread;
1463
1464     private final class AppDeathRecipient implements IBinder.DeathRecipient {
1465         final ProcessRecord mApp;
1466         final int mPid;
1467         final IApplicationThread mAppThread;
1468
1469         AppDeathRecipient(ProcessRecord app, int pid,
1470                 IApplicationThread thread) {
1471             if (DEBUG_ALL) Slog.v(
1472                 TAG, "New death recipient " + this
1473                 + " for thread " + thread.asBinder());
1474             mApp = app;
1475             mPid = pid;
1476             mAppThread = thread;
1477         }
1478
1479         @Override
1480         public void binderDied() {
1481             if (DEBUG_ALL) Slog.v(
1482                 TAG, "Death received in " + this
1483                 + " for thread " + mAppThread.asBinder());
1484             synchronized(ActivityManagerService.this) {
1485                 appDiedLocked(mApp, mPid, mAppThread, true);
1486             }
1487         }
1488     }
1489
1490     static final int SHOW_ERROR_UI_MSG = 1;
1491     static final int SHOW_NOT_RESPONDING_UI_MSG = 2;
1492     static final int SHOW_FACTORY_ERROR_UI_MSG = 3;
1493     static final int UPDATE_CONFIGURATION_MSG = 4;
1494     static final int GC_BACKGROUND_PROCESSES_MSG = 5;
1495     static final int WAIT_FOR_DEBUGGER_UI_MSG = 6;
1496     static final int SERVICE_TIMEOUT_MSG = 12;
1497     static final int UPDATE_TIME_ZONE = 13;
1498     static final int SHOW_UID_ERROR_UI_MSG = 14;
1499     static final int SHOW_FINGERPRINT_ERROR_UI_MSG = 15;
1500     static final int PROC_START_TIMEOUT_MSG = 20;
1501     static final int DO_PENDING_ACTIVITY_LAUNCHES_MSG = 21;
1502     static final int KILL_APPLICATION_MSG = 22;
1503     static final int FINALIZE_PENDING_INTENT_MSG = 23;
1504     static final int POST_HEAVY_NOTIFICATION_MSG = 24;
1505     static final int CANCEL_HEAVY_NOTIFICATION_MSG = 25;
1506     static final int SHOW_STRICT_MODE_VIOLATION_UI_MSG = 26;
1507     static final int CHECK_EXCESSIVE_WAKE_LOCKS_MSG = 27;
1508     static final int CLEAR_DNS_CACHE_MSG = 28;
1509     static final int UPDATE_HTTP_PROXY_MSG = 29;
1510     static final int SHOW_COMPAT_MODE_DIALOG_UI_MSG = 30;
1511     static final int DISPATCH_PROCESSES_CHANGED_UI_MSG = 31;
1512     static final int DISPATCH_PROCESS_DIED_UI_MSG = 32;
1513     static final int REPORT_MEM_USAGE_MSG = 33;
1514     static final int REPORT_USER_SWITCH_MSG = 34;
1515     static final int CONTINUE_USER_SWITCH_MSG = 35;
1516     static final int USER_SWITCH_TIMEOUT_MSG = 36;
1517     static final int IMMERSIVE_MODE_LOCK_MSG = 37;
1518     static final int PERSIST_URI_GRANTS_MSG = 38;
1519     static final int REQUEST_ALL_PSS_MSG = 39;
1520     static final int START_PROFILES_MSG = 40;
1521     static final int UPDATE_TIME = 41;
1522     static final int SYSTEM_USER_START_MSG = 42;
1523     static final int SYSTEM_USER_CURRENT_MSG = 43;
1524     static final int ENTER_ANIMATION_COMPLETE_MSG = 44;
1525     static final int FINISH_BOOTING_MSG = 45;
1526     static final int START_USER_SWITCH_UI_MSG = 46;
1527     static final int SEND_LOCALE_TO_MOUNT_DAEMON_MSG = 47;
1528     static final int DISMISS_DIALOG_UI_MSG = 48;
1529     static final int NOTIFY_TASK_STACK_CHANGE_LISTENERS_MSG = 49;
1530     static final int NOTIFY_CLEARTEXT_NETWORK_MSG = 50;
1531     static final int POST_DUMP_HEAP_NOTIFICATION_MSG = 51;
1532     static final int DELETE_DUMPHEAP_MSG = 52;
1533     static final int FOREGROUND_PROFILE_CHANGED_MSG = 53;
1534     static final int DISPATCH_UIDS_CHANGED_UI_MSG = 54;
1535     static final int REPORT_TIME_TRACKER_MSG = 55;
1536     static final int REPORT_USER_SWITCH_COMPLETE_MSG = 56;
1537     static final int SHUTDOWN_UI_AUTOMATION_CONNECTION_MSG = 57;
1538     static final int APP_BOOST_DEACTIVATE_MSG = 58;
1539     static final int CONTENT_PROVIDER_PUBLISH_TIMEOUT_MSG = 59;
1540     static final int IDLE_UIDS_MSG = 60;
1541     static final int SYSTEM_USER_UNLOCK_MSG = 61;
1542     static final int LOG_STACK_STATE = 62;
1543     static final int VR_MODE_CHANGE_MSG = 63;
1544     static final int NOTIFY_ACTIVITY_PINNED_LISTENERS_MSG = 64;
1545     static final int NOTIFY_PINNED_ACTIVITY_RESTART_ATTEMPT_LISTENERS_MSG = 65;
1546     static final int NOTIFY_PINNED_STACK_ANIMATION_ENDED_LISTENERS_MSG = 66;
1547     static final int NOTIFY_FORCED_RESIZABLE_MSG = 67;
1548     static final int NOTIFY_ACTIVITY_DISMISSING_DOCKED_STACK_MSG = 68;
1549     static final int SHOW_UNSUPPORTED_DISPLAY_SIZE_DIALOG_MSG = 69;
1550     static final int NOTIFY_VR_SLEEPING_MSG = 70;
1551
1552     static final int FIRST_ACTIVITY_STACK_MSG = 100;
1553     static final int FIRST_BROADCAST_QUEUE_MSG = 200;
1554     static final int FIRST_COMPAT_MODE_MSG = 300;
1555     static final int FIRST_SUPERVISOR_STACK_MSG = 100;
1556
1557     static ServiceThread sKillThread = null;
1558     static KillHandler sKillHandler = null;
1559
1560     CompatModeDialog mCompatModeDialog;
1561     UnsupportedDisplaySizeDialog mUnsupportedDisplaySizeDialog;
1562     long mLastMemUsageReportTime = 0;
1563
1564     /**
1565      * Flag whether the current user is a "monkey", i.e. whether
1566      * the UI is driven by a UI automation tool.
1567      */
1568     private boolean mUserIsMonkey;
1569
1570     /** Flag whether the device has a Recents UI */
1571     boolean mHasRecents;
1572
1573     /** The dimensions of the thumbnails in the Recents UI. */
1574     int mThumbnailWidth;
1575     int mThumbnailHeight;
1576     float mFullscreenThumbnailScale;
1577
1578     final ServiceThread mHandlerThread;
1579     final MainHandler mHandler;
1580     final UiHandler mUiHandler;
1581
1582     PackageManagerInternal mPackageManagerInt;
1583
1584     // VoiceInteraction session ID that changes for each new request except when
1585     // being called for multiwindow assist in a single session.
1586     private int mViSessionId = 1000;
1587
1588     final boolean mPermissionReviewRequired;
1589
1590     final class KillHandler extends Handler {
1591         static final int KILL_PROCESS_GROUP_MSG = 4000;
1592
1593         public KillHandler(Looper looper) {
1594             super(looper, null, true);
1595         }
1596
1597         @Override
1598         public void handleMessage(Message msg) {
1599             switch (msg.what) {
1600                 case KILL_PROCESS_GROUP_MSG:
1601                 {
1602                     Trace.traceBegin(Trace.TRACE_TAG_ACTIVITY_MANAGER, "killProcessGroup");
1603                     Process.killProcessGroup(msg.arg1 /* uid */, msg.arg2 /* pid */);
1604                     Trace.traceEnd(Trace.TRACE_TAG_ACTIVITY_MANAGER);
1605                 }
1606                 break;
1607
1608                 default:
1609                     super.handleMessage(msg);
1610             }
1611         }
1612     }
1613
1614     final class UiHandler extends Handler {
1615         public UiHandler() {
1616             super(com.android.server.UiThread.get().getLooper(), null, true);
1617         }
1618
1619         @Override
1620         public void handleMessage(Message msg) {
1621             switch (msg.what) {
1622             case SHOW_ERROR_UI_MSG: {
1623                 mAppErrors.handleShowAppErrorUi(msg);
1624                 ensureBootCompleted();
1625             } break;
1626             case SHOW_NOT_RESPONDING_UI_MSG: {
1627                 mAppErrors.handleShowAnrUi(msg);
1628                 ensureBootCompleted();
1629             } break;
1630             case SHOW_STRICT_MODE_VIOLATION_UI_MSG: {
1631                 HashMap<String, Object> data = (HashMap<String, Object>) msg.obj;
1632                 synchronized (ActivityManagerService.this) {
1633                     ProcessRecord proc = (ProcessRecord) data.get("app");
1634                     if (proc == null) {
1635                         Slog.e(TAG, "App not found when showing strict mode dialog.");
1636                         break;
1637                     }
1638                     if (proc.crashDialog != null) {
1639                         Slog.e(TAG, "App already has strict mode dialog: " + proc);
1640                         return;
1641                     }
1642                     AppErrorResult res = (AppErrorResult) data.get("result");
1643                     if (mShowDialogs && !mSleeping && !mShuttingDown) {
1644                         Dialog d = new StrictModeViolationDialog(mContext,
1645                                 ActivityManagerService.this, res, proc);
1646                         d.show();
1647                         proc.crashDialog = d;
1648                     } else {
1649                         // The device is asleep, so just pretend that the user
1650                         // saw a crash dialog and hit "force quit".
1651                         res.set(0);
1652                     }
1653                 }
1654                 ensureBootCompleted();
1655             } break;
1656             case SHOW_FACTORY_ERROR_UI_MSG: {
1657                 Dialog d = new FactoryErrorDialog(
1658                     mContext, msg.getData().getCharSequence("msg"));
1659                 d.show();
1660                 ensureBootCompleted();
1661             } break;
1662             case WAIT_FOR_DEBUGGER_UI_MSG: {
1663                 synchronized (ActivityManagerService.this) {
1664                     ProcessRecord app = (ProcessRecord)msg.obj;
1665                     if (msg.arg1 != 0) {
1666                         if (!app.waitedForDebugger) {
1667                             Dialog d = new AppWaitingForDebuggerDialog(
1668                                     ActivityManagerService.this,
1669                                     mContext, app);
1670                             app.waitDialog = d;
1671                             app.waitedForDebugger = true;
1672                             d.show();
1673                         }
1674                     } else {
1675                         if (app.waitDialog != null) {
1676                             app.waitDialog.dismiss();
1677                             app.waitDialog = null;
1678                         }
1679                     }
1680                 }
1681             } break;
1682             case SHOW_UID_ERROR_UI_MSG: {
1683                 if (mShowDialogs) {
1684                     AlertDialog d = new BaseErrorDialog(mContext);
1685                     d.getWindow().setType(WindowManager.LayoutParams.TYPE_SYSTEM_ERROR);
1686                     d.setCancelable(false);
1687                     d.setTitle(mContext.getText(R.string.android_system_label));
1688                     d.setMessage(mContext.getText(R.string.system_error_wipe_data));
1689                     d.setButton(DialogInterface.BUTTON_POSITIVE, mContext.getText(R.string.ok),
1690                             obtainMessage(DISMISS_DIALOG_UI_MSG, d));
1691                     d.show();
1692                 }
1693             } break;
1694             case SHOW_FINGERPRINT_ERROR_UI_MSG: {
1695                 if (mShowDialogs) {
1696                     AlertDialog d = new BaseErrorDialog(mContext);
1697                     d.getWindow().setType(WindowManager.LayoutParams.TYPE_SYSTEM_ERROR);
1698                     d.setCancelable(false);
1699                     d.setTitle(mContext.getText(R.string.android_system_label));
1700                     d.setMessage(mContext.getText(R.string.system_error_manufacturer));
1701                     d.setButton(DialogInterface.BUTTON_POSITIVE, mContext.getText(R.string.ok),
1702                             obtainMessage(DISMISS_DIALOG_UI_MSG, d));
1703                     d.show();
1704                 }
1705             } break;
1706             case SHOW_COMPAT_MODE_DIALOG_UI_MSG: {
1707                 synchronized (ActivityManagerService.this) {
1708                     ActivityRecord ar = (ActivityRecord) msg.obj;
1709                     if (mCompatModeDialog != null) {
1710                         if (mCompatModeDialog.mAppInfo.packageName.equals(
1711                                 ar.info.applicationInfo.packageName)) {
1712                             return;
1713                         }
1714                         mCompatModeDialog.dismiss();
1715                         mCompatModeDialog = null;
1716                     }
1717                     if (ar != null && false) {
1718                         if (mCompatModePackages.getPackageAskCompatModeLocked(
1719                                 ar.packageName)) {
1720                             int mode = mCompatModePackages.computeCompatModeLocked(
1721                                     ar.info.applicationInfo);
1722                             if (mode == ActivityManager.COMPAT_MODE_DISABLED
1723                                     || mode == ActivityManager.COMPAT_MODE_ENABLED) {
1724                                 mCompatModeDialog = new CompatModeDialog(
1725                                         ActivityManagerService.this, mContext,
1726                                         ar.info.applicationInfo);
1727                                 mCompatModeDialog.show();
1728                             }
1729                         }
1730                     }
1731                 }
1732                 break;
1733             }
1734             case SHOW_UNSUPPORTED_DISPLAY_SIZE_DIALOG_MSG: {
1735                 synchronized (ActivityManagerService.this) {
1736                     final ActivityRecord ar = (ActivityRecord) msg.obj;
1737                     if (mUnsupportedDisplaySizeDialog != null) {
1738                         mUnsupportedDisplaySizeDialog.dismiss();
1739                         mUnsupportedDisplaySizeDialog = null;
1740                     }
1741                     if (ar != null && mCompatModePackages.getPackageNotifyUnsupportedZoomLocked(
1742                             ar.packageName)) {
1743                         mUnsupportedDisplaySizeDialog = new UnsupportedDisplaySizeDialog(
1744                                 ActivityManagerService.this, mContext, ar.info.applicationInfo);
1745                         mUnsupportedDisplaySizeDialog.show();
1746                     }
1747                 }
1748                 break;
1749             }
1750             case START_USER_SWITCH_UI_MSG: {
1751                 mUserController.showUserSwitchDialog((Pair<UserInfo, UserInfo>) msg.obj);
1752                 break;
1753             }
1754             case DISMISS_DIALOG_UI_MSG: {
1755                 final Dialog d = (Dialog) msg.obj;
1756                 d.dismiss();
1757                 break;
1758             }
1759             case DISPATCH_PROCESSES_CHANGED_UI_MSG: {
1760                 dispatchProcessesChanged();
1761                 break;
1762             }
1763             case DISPATCH_PROCESS_DIED_UI_MSG: {
1764                 final int pid = msg.arg1;
1765                 final int uid = msg.arg2;
1766                 dispatchProcessDied(pid, uid);
1767                 break;
1768             }
1769             case DISPATCH_UIDS_CHANGED_UI_MSG: {
1770                 dispatchUidsChanged();
1771             } break;
1772             }
1773         }
1774     }
1775
1776     final class MainHandler extends Handler {
1777         public MainHandler(Looper looper) {
1778             super(looper, null, true);
1779         }
1780
1781         @Override
1782         public void handleMessage(Message msg) {
1783             switch (msg.what) {
1784             case UPDATE_CONFIGURATION_MSG: {
1785                 final ContentResolver resolver = mContext.getContentResolver();
1786                 Settings.System.putConfigurationForUser(resolver, (Configuration) msg.obj,
1787                         msg.arg1);
1788             } break;
1789             case GC_BACKGROUND_PROCESSES_MSG: {
1790                 synchronized (ActivityManagerService.this) {
1791                     performAppGcsIfAppropriateLocked();
1792                 }
1793             } break;
1794             case SERVICE_TIMEOUT_MSG: {
1795                 if (mDidDexOpt) {
1796                     mDidDexOpt = false;
1797                     Message nmsg = mHandler.obtainMessage(SERVICE_TIMEOUT_MSG);
1798                     nmsg.obj = msg.obj;
1799                     mHandler.sendMessageDelayed(nmsg, ActiveServices.SERVICE_TIMEOUT);
1800                     return;
1801                 }
1802                 mServices.serviceTimeout((ProcessRecord)msg.obj);
1803             } break;
1804             case UPDATE_TIME_ZONE: {
1805                 synchronized (ActivityManagerService.this) {
1806                     for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) {
1807                         ProcessRecord r = mLruProcesses.get(i);
1808                         if (r.thread != null) {
1809                             try {
1810                                 r.thread.updateTimeZone();
1811                             } catch (RemoteException ex) {
1812                                 Slog.w(TAG, "Failed to update time zone for: " + r.info.processName);
1813                             }
1814                         }
1815                     }
1816                 }
1817             } break;
1818             case CLEAR_DNS_CACHE_MSG: {
1819                 synchronized (ActivityManagerService.this) {
1820                     for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) {
1821                         ProcessRecord r = mLruProcesses.get(i);
1822                         if (r.thread != null) {
1823                             try {
1824                                 r.thread.clearDnsCache();
1825                             } catch (RemoteException ex) {
1826                                 Slog.w(TAG, "Failed to clear dns cache for: " + r.info.processName);
1827                             }
1828                         }
1829                     }
1830                 }
1831             } break;
1832             case UPDATE_HTTP_PROXY_MSG: {
1833                 ProxyInfo proxy = (ProxyInfo)msg.obj;
1834                 String host = "";
1835                 String port = "";
1836                 String exclList = "";
1837                 Uri pacFileUrl = Uri.EMPTY;
1838                 if (proxy != null) {
1839                     host = proxy.getHost();
1840                     port = Integer.toString(proxy.getPort());
1841                     exclList = proxy.getExclusionListAsString();
1842                     pacFileUrl = proxy.getPacFileUrl();
1843                 }
1844                 synchronized (ActivityManagerService.this) {
1845                     for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) {
1846                         ProcessRecord r = mLruProcesses.get(i);
1847                         if (r.thread != null) {
1848                             try {
1849                                 r.thread.setHttpProxy(host, port, exclList, pacFileUrl);
1850                             } catch (RemoteException ex) {
1851                                 Slog.w(TAG, "Failed to update http proxy for: " +
1852                                         r.info.processName);
1853                             }
1854                         }
1855                     }
1856                 }
1857             } break;
1858             case PROC_START_TIMEOUT_MSG: {
1859                 if (mDidDexOpt) {
1860                     mDidDexOpt = false;
1861                     Message nmsg = mHandler.obtainMessage(PROC_START_TIMEOUT_MSG);
1862                     nmsg.obj = msg.obj;
1863                     mHandler.sendMessageDelayed(nmsg, PROC_START_TIMEOUT);
1864                     return;
1865                 }
1866                 ProcessRecord app = (ProcessRecord)msg.obj;
1867                 synchronized (ActivityManagerService.this) {
1868                     processStartTimedOutLocked(app);
1869                 }
1870             } break;
1871             case CONTENT_PROVIDER_PUBLISH_TIMEOUT_MSG: {
1872                 ProcessRecord app = (ProcessRecord)msg.obj;
1873                 synchronized (ActivityManagerService.this) {
1874                     processContentProviderPublishTimedOutLocked(app);
1875                 }
1876             } break;
1877             case DO_PENDING_ACTIVITY_LAUNCHES_MSG: {
1878                 synchronized (ActivityManagerService.this) {
1879                     mActivityStarter.doPendingActivityLaunchesLocked(true);
1880                 }
1881             } break;
1882             case KILL_APPLICATION_MSG: {
1883                 synchronized (ActivityManagerService.this) {
1884                     final int appId = msg.arg1;
1885                     final int userId = msg.arg2;
1886                     Bundle bundle = (Bundle)msg.obj;
1887                     String pkg = bundle.getString("pkg");
1888                     String reason = bundle.getString("reason");
1889                     forceStopPackageLocked(pkg, appId, false, false, true, false,
1890                             false, userId, reason);
1891                 }
1892             } break;
1893             case FINALIZE_PENDING_INTENT_MSG: {
1894                 ((PendingIntentRecord)msg.obj).completeFinalize();
1895             } break;
1896             case POST_HEAVY_NOTIFICATION_MSG: {
1897                 INotificationManager inm = NotificationManager.getService();
1898                 if (inm == null) {
1899                     return;
1900                 }
1901
1902                 ActivityRecord root = (ActivityRecord)msg.obj;
1903                 ProcessRecord process = root.app;
1904                 if (process == null) {
1905                     return;
1906                 }
1907
1908                 try {
1909                     Context context = mContext.createPackageContext(process.info.packageName, 0);
1910                     String text = mContext.getString(R.string.heavy_weight_notification,
1911                             context.getApplicationInfo().loadLabel(context.getPackageManager()));
1912                     Notification notification = new Notification.Builder(context)
1913                             .setSmallIcon(com.android.internal.R.drawable.stat_sys_adb)
1914                             .setWhen(0)
1915                             .setOngoing(true)
1916                             .setTicker(text)
1917                             .setColor(mContext.getColor(
1918                                     com.android.internal.R.color.system_notification_accent_color))
1919                             .setContentTitle(text)
1920                             .setContentText(
1921                                     mContext.getText(R.string.heavy_weight_notification_detail))
1922                             .setContentIntent(PendingIntent.getActivityAsUser(mContext, 0,
1923                                     root.intent, PendingIntent.FLAG_CANCEL_CURRENT, null,
1924                                     new UserHandle(root.userId)))
1925                             .build();
1926                     try {
1927                         int[] outId = new int[1];
1928                         inm.enqueueNotificationWithTag("android", "android", null,
1929                                 R.string.heavy_weight_notification,
1930                                 notification, outId, root.userId);
1931                     } catch (RuntimeException e) {
1932                         Slog.w(ActivityManagerService.TAG,
1933                                 "Error showing notification for heavy-weight app", e);
1934                     } catch (RemoteException e) {
1935                     }
1936                 } catch (NameNotFoundException e) {
1937                     Slog.w(TAG, "Unable to create context for heavy notification", e);
1938                 }
1939             } break;
1940             case CANCEL_HEAVY_NOTIFICATION_MSG: {
1941                 INotificationManager inm = NotificationManager.getService();
1942                 if (inm == null) {
1943                     return;
1944                 }
1945                 try {
1946                     inm.cancelNotificationWithTag("android", null,
1947                             R.string.heavy_weight_notification,  msg.arg1);
1948                 } catch (RuntimeException e) {
1949                     Slog.w(ActivityManagerService.TAG,
1950                             "Error canceling notification for service", e);
1951                 } catch (RemoteException e) {
1952                 }
1953             } break;
1954             case CHECK_EXCESSIVE_WAKE_LOCKS_MSG: {
1955                 synchronized (ActivityManagerService.this) {
1956                     checkExcessivePowerUsageLocked(true);
1957                     removeMessages(CHECK_EXCESSIVE_WAKE_LOCKS_MSG);
1958                     Message nmsg = obtainMessage(CHECK_EXCESSIVE_WAKE_LOCKS_MSG);
1959                     sendMessageDelayed(nmsg, POWER_CHECK_DELAY);
1960                 }
1961             } break;
1962             case REPORT_MEM_USAGE_MSG: {
1963                 final ArrayList<ProcessMemInfo> memInfos = (ArrayList<ProcessMemInfo>)msg.obj;
1964                 Thread thread = new Thread() {
1965                     @Override public void run() {
1966                         reportMemUsage(memInfos);
1967                     }
1968                 };
1969                 thread.start();
1970                 break;
1971             }
1972             case REPORT_USER_SWITCH_MSG: {
1973                 mUserController.dispatchUserSwitch((UserState) msg.obj, msg.arg1, msg.arg2);
1974                 break;
1975             }
1976             case CONTINUE_USER_SWITCH_MSG: {
1977                 mUserController.continueUserSwitch((UserState) msg.obj, msg.arg1, msg.arg2);
1978                 break;
1979             }
1980             case USER_SWITCH_TIMEOUT_MSG: {
1981                 mUserController.timeoutUserSwitch((UserState) msg.obj, msg.arg1, msg.arg2);
1982                 break;
1983             }
1984             case IMMERSIVE_MODE_LOCK_MSG: {
1985                 final boolean nextState = (msg.arg1 != 0);
1986                 if (mUpdateLock.isHeld() != nextState) {
1987                     if (DEBUG_IMMERSIVE) Slog.d(TAG_IMMERSIVE,
1988                             "Applying new update lock state '" + nextState
1989                             + "' for " + (ActivityRecord)msg.obj);
1990                     if (nextState) {
1991                         mUpdateLock.acquire();
1992                     } else {
1993                         mUpdateLock.release();
1994                     }
1995                 }
1996                 break;
1997             }
1998             case PERSIST_URI_GRANTS_MSG: {
1999                 writeGrantedUriPermissions();
2000                 break;
2001             }
2002             case REQUEST_ALL_PSS_MSG: {
2003                 synchronized (ActivityManagerService.this) {
2004                     requestPssAllProcsLocked(SystemClock.uptimeMillis(), true, false);
2005                 }
2006                 break;
2007             }
2008             case START_PROFILES_MSG: {
2009                 synchronized (ActivityManagerService.this) {
2010                     mUserController.startProfilesLocked();
2011                 }
2012                 break;
2013             }
2014             case UPDATE_TIME: {
2015                 synchronized (ActivityManagerService.this) {
2016                     for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) {
2017                         ProcessRecord r = mLruProcesses.get(i);
2018                         if (r.thread != null) {
2019                             try {
2020                                 r.thread.updateTimePrefs(msg.arg1 == 0 ? false : true);
2021                             } catch (RemoteException ex) {
2022                                 Slog.w(TAG, "Failed to update preferences for: " + r.info.processName);
2023                             }
2024                         }
2025                     }
2026                 }
2027                 break;
2028             }
2029             case SYSTEM_USER_START_MSG: {
2030                 mBatteryStatsService.noteEvent(BatteryStats.HistoryItem.EVENT_USER_RUNNING_START,
2031                         Integer.toString(msg.arg1), msg.arg1);
2032                 mSystemServiceManager.startUser(msg.arg1);
2033                 break;
2034             }
2035             case SYSTEM_USER_UNLOCK_MSG: {
2036                 final int userId = msg.arg1;
2037                 mSystemServiceManager.unlockUser(userId);
2038                 synchronized (ActivityManagerService.this) {
2039                     mRecentTasks.loadUserRecentsLocked(userId);
2040                 }
2041                 if (userId == UserHandle.USER_SYSTEM) {
2042                     startPersistentApps(PackageManager.MATCH_DIRECT_BOOT_UNAWARE);
2043                 }
2044                 installEncryptionUnawareProviders(userId);
2045                 mUserController.finishUserUnlocked((UserState) msg.obj);
2046                 break;
2047             }
2048             case SYSTEM_USER_CURRENT_MSG: {
2049                 mBatteryStatsService.noteEvent(
2050                         BatteryStats.HistoryItem.EVENT_USER_FOREGROUND_FINISH,
2051                         Integer.toString(msg.arg2), msg.arg2);
2052                 mBatteryStatsService.noteEvent(
2053                         BatteryStats.HistoryItem.EVENT_USER_FOREGROUND_START,
2054                         Integer.toString(msg.arg1), msg.arg1);
2055                 mSystemServiceManager.switchUser(msg.arg1);
2056                 break;
2057             }
2058             case ENTER_ANIMATION_COMPLETE_MSG: {
2059                 synchronized (ActivityManagerService.this) {
2060                     ActivityRecord r = ActivityRecord.forTokenLocked((IBinder) msg.obj);
2061                     if (r != null && r.app != null && r.app.thread != null) {
2062                         try {
2063                             r.app.thread.scheduleEnterAnimationComplete(r.appToken);
2064                         } catch (RemoteException e) {
2065                         }
2066                     }
2067                 }
2068                 break;
2069             }
2070             case FINISH_BOOTING_MSG: {
2071                 if (msg.arg1 != 0) {
2072                     Trace.traceBegin(Trace.TRACE_TAG_ACTIVITY_MANAGER, "FinishBooting");
2073                     finishBooting();
2074                     Trace.traceEnd(Trace.TRACE_TAG_ACTIVITY_MANAGER);
2075                 }
2076                 if (msg.arg2 != 0) {
2077                     enableScreenAfterBoot();
2078                 }
2079                 break;
2080             }
2081             case SEND_LOCALE_TO_MOUNT_DAEMON_MSG: {
2082                 try {
2083                     Locale l = (Locale) msg.obj;
2084                     IBinder service = ServiceManager.getService("mount");
2085                     IMountService mountService = IMountService.Stub.asInterface(service);
2086                     Log.d(TAG, "Storing locale " + l.toLanguageTag() + " for decryption UI");
2087                     mountService.setField(StorageManager.SYSTEM_LOCALE_KEY, l.toLanguageTag());
2088                 } catch (RemoteException e) {
2089                     Log.e(TAG, "Error storing locale for decryption UI", e);
2090                 }
2091                 break;
2092             }
2093             case NOTIFY_TASK_STACK_CHANGE_LISTENERS_MSG: {
2094                 synchronized (ActivityManagerService.this) {
2095                     for (int i = mTaskStackListeners.beginBroadcast() - 1; i >= 0; i--) {
2096                         try {
2097                             // Make a one-way callback to the listener
2098                             mTaskStackListeners.getBroadcastItem(i).onTaskStackChanged();
2099                         } catch (RemoteException e){
2100                             // Handled by the RemoteCallbackList
2101                         }
2102                     }
2103                     mTaskStackListeners.finishBroadcast();
2104                 }
2105                 break;
2106             }
2107             case NOTIFY_ACTIVITY_PINNED_LISTENERS_MSG: {
2108                 synchronized (ActivityManagerService.this) {
2109                     for (int i = mTaskStackListeners.beginBroadcast() - 1; i >= 0; i--) {
2110                         try {
2111                             // Make a one-way callback to the listener
2112                             mTaskStackListeners.getBroadcastItem(i).onActivityPinned();
2113                         } catch (RemoteException e){
2114                             // Handled by the RemoteCallbackList
2115                         }
2116                     }
2117                     mTaskStackListeners.finishBroadcast();
2118                 }
2119                 break;
2120             }
2121             case NOTIFY_PINNED_ACTIVITY_RESTART_ATTEMPT_LISTENERS_MSG: {
2122                 synchronized (ActivityManagerService.this) {
2123                     for (int i = mTaskStackListeners.beginBroadcast() - 1; i >= 0; i--) {
2124                         try {
2125                             // Make a one-way callback to the listener
2126                             mTaskStackListeners.getBroadcastItem(i).onPinnedActivityRestartAttempt();
2127                         } catch (RemoteException e){
2128                             // Handled by the RemoteCallbackList
2129                         }
2130                     }
2131                     mTaskStackListeners.finishBroadcast();
2132                 }
2133                 break;
2134             }
2135             case NOTIFY_PINNED_STACK_ANIMATION_ENDED_LISTENERS_MSG: {
2136                 synchronized (ActivityManagerService.this) {
2137                     for (int i = mTaskStackListeners.beginBroadcast() - 1; i >= 0; i--) {
2138                         try {
2139                             // Make a one-way callback to the listener
2140                             mTaskStackListeners.getBroadcastItem(i).onPinnedStackAnimationEnded();
2141                         } catch (RemoteException e){
2142                             // Handled by the RemoteCallbackList
2143                         }
2144                     }
2145                     mTaskStackListeners.finishBroadcast();
2146                 }
2147                 break;
2148             }
2149             case NOTIFY_FORCED_RESIZABLE_MSG: {
2150                 synchronized (ActivityManagerService.this) {
2151                     for (int i = mTaskStackListeners.beginBroadcast() - 1; i >= 0; i--) {
2152                         try {
2153                             // Make a one-way callback to the listener
2154                             mTaskStackListeners.getBroadcastItem(i).onActivityForcedResizable(
2155                                     (String) msg.obj, msg.arg1);
2156                         } catch (RemoteException e){
2157                             // Handled by the RemoteCallbackList
2158                         }
2159                     }
2160                     mTaskStackListeners.finishBroadcast();
2161                 }
2162                 break;
2163             }
2164                 case NOTIFY_ACTIVITY_DISMISSING_DOCKED_STACK_MSG: {
2165                     synchronized (ActivityManagerService.this) {
2166                         for (int i = mTaskStackListeners.beginBroadcast() - 1; i >= 0; i--) {
2167                             try {
2168                                 // Make a one-way callback to the listener
2169                                 mTaskStackListeners.getBroadcastItem(i)
2170                                         .onActivityDismissingDockedStack();
2171                             } catch (RemoteException e){
2172                                 // Handled by the RemoteCallbackList
2173                             }
2174                         }
2175                         mTaskStackListeners.finishBroadcast();
2176                     }
2177                     break;
2178                 }
2179             case NOTIFY_CLEARTEXT_NETWORK_MSG: {
2180                 final int uid = msg.arg1;
2181                 final byte[] firstPacket = (byte[]) msg.obj;
2182
2183                 synchronized (mPidsSelfLocked) {
2184                     for (int i = 0; i < mPidsSelfLocked.size(); i++) {
2185                         final ProcessRecord p = mPidsSelfLocked.valueAt(i);
2186                         if (p.uid == uid) {
2187                             try {
2188                                 p.thread.notifyCleartextNetwork(firstPacket);
2189                             } catch (RemoteException ignored) {
2190                             }
2191                         }
2192                     }
2193                 }
2194                 break;
2195             }
2196             case POST_DUMP_HEAP_NOTIFICATION_MSG: {
2197                 final String procName;
2198                 final int uid;
2199                 final long memLimit;
2200                 final String reportPackage;
2201                 synchronized (ActivityManagerService.this) {
2202                     procName = mMemWatchDumpProcName;
2203                     uid = mMemWatchDumpUid;
2204                     Pair<Long, String> val = mMemWatchProcesses.get(procName, uid);
2205                     if (val == null) {
2206                         val = mMemWatchProcesses.get(procName, 0);
2207                     }
2208                     if (val != null) {
2209                         memLimit = val.first;
2210                         reportPackage = val.second;
2211                     } else {
2212                         memLimit = 0;
2213                         reportPackage = null;
2214                     }
2215                 }
2216                 if (procName == null) {
2217                     return;
2218                 }
2219
2220                 if (DEBUG_PSS) Slog.d(TAG_PSS,
2221                         "Showing dump heap notification from " + procName + "/" + uid);
2222
2223                 INotificationManager inm = NotificationManager.getService();
2224                 if (inm == null) {
2225                     return;
2226                 }
2227
2228                 String text = mContext.getString(R.string.dump_heap_notification, procName);
2229
2230
2231                 Intent deleteIntent = new Intent();
2232                 deleteIntent.setAction(DumpHeapActivity.ACTION_DELETE_DUMPHEAP);
2233                 Intent intent = new Intent();
2234                 intent.setClassName("android", DumpHeapActivity.class.getName());
2235                 intent.putExtra(DumpHeapActivity.KEY_PROCESS, procName);
2236                 intent.putExtra(DumpHeapActivity.KEY_SIZE, memLimit);
2237                 if (reportPackage != null) {
2238                     intent.putExtra(DumpHeapActivity.KEY_DIRECT_LAUNCH, reportPackage);
2239                 }
2240                 int userId = UserHandle.getUserId(uid);
2241                 Notification notification = new Notification.Builder(mContext)
2242                         .setSmallIcon(com.android.internal.R.drawable.stat_sys_adb)
2243                         .setWhen(0)
2244                         .setOngoing(true)
2245                         .setAutoCancel(true)
2246                         .setTicker(text)
2247                         .setColor(mContext.getColor(
2248                                 com.android.internal.R.color.system_notification_accent_color))
2249                         .setContentTitle(text)
2250                         .setContentText(
2251                                 mContext.getText(R.string.dump_heap_notification_detail))
2252                         .setContentIntent(PendingIntent.getActivityAsUser(mContext, 0,
2253                                 intent, PendingIntent.FLAG_CANCEL_CURRENT, null,
2254                                 new UserHandle(userId)))
2255                         .setDeleteIntent(PendingIntent.getBroadcastAsUser(mContext, 0,
2256                                 deleteIntent, 0, UserHandle.SYSTEM))
2257                         .build();
2258
2259                 try {
2260                     int[] outId = new int[1];
2261                     inm.enqueueNotificationWithTag("android", "android", null,
2262                             R.string.dump_heap_notification,
2263                             notification, outId, userId);
2264                 } catch (RuntimeException e) {
2265                     Slog.w(ActivityManagerService.TAG,
2266                             "Error showing notification for dump heap", e);
2267                 } catch (RemoteException e) {
2268                 }
2269             } break;
2270             case DELETE_DUMPHEAP_MSG: {
2271                 revokeUriPermission(ActivityThread.currentActivityThread().getApplicationThread(),
2272                         DumpHeapActivity.JAVA_URI,
2273                         Intent.FLAG_GRANT_READ_URI_PERMISSION
2274                                 | Intent.FLAG_GRANT_WRITE_URI_PERMISSION,
2275                         UserHandle.myUserId());
2276                 synchronized (ActivityManagerService.this) {
2277                     mMemWatchDumpFile = null;
2278                     mMemWatchDumpProcName = null;
2279                     mMemWatchDumpPid = -1;
2280                     mMemWatchDumpUid = -1;
2281                 }
2282             } break;
2283             case FOREGROUND_PROFILE_CHANGED_MSG: {
2284                 mUserController.dispatchForegroundProfileChanged(msg.arg1);
2285             } break;
2286             case REPORT_TIME_TRACKER_MSG: {
2287                 AppTimeTracker tracker = (AppTimeTracker)msg.obj;
2288                 tracker.deliverResult(mContext);
2289             } break;
2290             case REPORT_USER_SWITCH_COMPLETE_MSG: {
2291                 mUserController.dispatchUserSwitchComplete(msg.arg1);
2292             } break;
2293             case SHUTDOWN_UI_AUTOMATION_CONNECTION_MSG: {
2294                 IUiAutomationConnection connection = (IUiAutomationConnection) msg.obj;
2295                 try {
2296                     connection.shutdown();
2297                 } catch (RemoteException e) {
2298                     Slog.w(TAG, "Error shutting down UiAutomationConnection");
2299                 }
2300                 // Only a UiAutomation can set this flag and now that
2301                 // it is finished we make sure it is reset to its default.
2302                 mUserIsMonkey = false;
2303             } break;
2304             case APP_BOOST_DEACTIVATE_MSG: {
2305                 synchronized(ActivityManagerService.this) {
2306                     if (mIsBoosted) {
2307                         if (mBoostStartTime < (SystemClock.uptimeMillis() - APP_BOOST_TIMEOUT)) {
2308                             nativeMigrateFromBoost();
2309                             mIsBoosted = false;
2310                             mBoostStartTime = 0;
2311                         } else {
2312                             Message newmsg = mHandler.obtainMessage(APP_BOOST_DEACTIVATE_MSG);
2313                             mHandler.sendMessageDelayed(newmsg, APP_BOOST_TIMEOUT);
2314                         }
2315                     }
2316                 }
2317             } break;
2318             case IDLE_UIDS_MSG: {
2319                 idleUids();
2320             } break;
2321             case LOG_STACK_STATE: {
2322                 synchronized (ActivityManagerService.this) {
2323                     mStackSupervisor.logStackState();
2324                 }
2325             } break;
2326             case VR_MODE_CHANGE_MSG: {
2327                 VrManagerInternal vrService = LocalServices.getService(VrManagerInternal.class);
2328                 if (vrService == null) {
2329                     break;
2330                 }
2331                 final ActivityRecord r = (ActivityRecord) msg.obj;
2332                 boolean vrMode;
2333                 ComponentName requestedPackage;
2334                 ComponentName callingPackage;
2335                 int userId;
2336                 synchronized (ActivityManagerService.this) {
2337                     vrMode = r.requestedVrComponent != null;
2338                     requestedPackage = r.requestedVrComponent;
2339                     userId = r.userId;
2340                     callingPackage = r.info.getComponentName();
2341                     if (mInVrMode != vrMode) {
2342                         mInVrMode = vrMode;
2343                         mShowDialogs = shouldShowDialogs(mConfiguration, mInVrMode);
2344                         if (r.app != null) {
2345                             ProcessRecord proc = r.app;
2346                             if (proc.vrThreadTid > 0) {
2347                                 if (proc.curSchedGroup == ProcessList.SCHED_GROUP_TOP_APP) {
2348                                     try {
2349                                         if (mInVrMode == true) {
2350                                             Process.setThreadScheduler(proc.vrThreadTid,
2351                                                 Process.SCHED_FIFO | Process.SCHED_RESET_ON_FORK, 1);
2352                                         } else {
2353                                             Process.setThreadScheduler(proc.vrThreadTid,
2354                                                 Process.SCHED_OTHER, 0);
2355                                         }
2356                                     } catch (IllegalArgumentException e) {
2357                                         Slog.w(TAG, "Failed to set scheduling policy, thread does"
2358                                                 + " not exist:\n" + e);
2359                                     }
2360                                 }
2361                             }
2362                         }
2363                     }
2364                 }
2365                 vrService.setVrMode(vrMode, requestedPackage, userId, callingPackage);
2366             } case NOTIFY_VR_SLEEPING_MSG: {
2367                 notifyVrManagerOfSleepState(msg.arg1 != 0);
2368             } break;
2369             }
2370         }
2371     };
2372
2373     static final int COLLECT_PSS_BG_MSG = 1;
2374
2375     final Handler mBgHandler = new Handler(BackgroundThread.getHandler().getLooper()) {
2376         @Override
2377         public void handleMessage(Message msg) {
2378             switch (msg.what) {
2379             case COLLECT_PSS_BG_MSG: {
2380                 long start = SystemClock.uptimeMillis();
2381                 MemInfoReader memInfo = null;
2382                 synchronized (ActivityManagerService.this) {
2383                     if (mFullPssPending) {
2384                         mFullPssPending = false;
2385                         memInfo = new MemInfoReader();
2386                     }
2387                 }
2388                 if (memInfo != null) {
2389                     updateCpuStatsNow();
2390                     long nativeTotalPss = 0;
2391                     final List<ProcessCpuTracker.Stats> stats;
2392                     synchronized (mProcessCpuTracker) {
2393                         stats = mProcessCpuTracker.getStats( (st)-> {
2394                             return st.vsize > 0 && st.uid < Process.FIRST_APPLICATION_UID;
2395                         });
2396                     }
2397                     final int N = stats.size();
2398                     for (int j = 0; j < N; j++) {
2399                         synchronized (mPidsSelfLocked) {
2400                             if (mPidsSelfLocked.indexOfKey(stats.get(j).pid) >= 0) {
2401                                 // This is one of our own processes; skip it.
2402                                 continue;
2403                             }
2404                         }
2405                         nativeTotalPss += Debug.getPss(stats.get(j).pid, null, null);
2406                     }
2407                     memInfo.readMemInfo();
2408                     synchronized (ActivityManagerService.this) {
2409                         if (DEBUG_PSS) Slog.d(TAG_PSS, "Collected native and kernel memory in "
2410                                 + (SystemClock.uptimeMillis()-start) + "ms");
2411                         final long cachedKb = memInfo.getCachedSizeKb();
2412                         final long freeKb = memInfo.getFreeSizeKb();
2413                         final long zramKb = memInfo.getZramTotalSizeKb();
2414                         final long kernelKb = memInfo.getKernelUsedSizeKb();
2415                         EventLogTags.writeAmMeminfo(cachedKb*1024, freeKb*1024, zramKb*1024,
2416                                 kernelKb*1024, nativeTotalPss*1024);
2417                         mProcessStats.addSysMemUsageLocked(cachedKb, freeKb, zramKb, kernelKb,
2418                                 nativeTotalPss);
2419                     }
2420                 }
2421
2422                 int num = 0;
2423                 long[] tmp = new long[2];
2424                 do {
2425                     ProcessRecord proc;
2426                     int procState;
2427                     int pid;
2428                     long lastPssTime;
2429                     synchronized (ActivityManagerService.this) {
2430                         if (mPendingPssProcesses.size() <= 0) {
2431                             if (mTestPssMode || DEBUG_PSS) Slog.d(TAG_PSS,
2432                                     "Collected PSS of " + num + " processes in "
2433                                     + (SystemClock.uptimeMillis() - start) + "ms");
2434                             mPendingPssProcesses.clear();
2435                             return;
2436                         }
2437                         proc = mPendingPssProcesses.remove(0);
2438                         procState = proc.pssProcState;
2439                         lastPssTime = proc.lastPssTime;
2440                         if (proc.thread != null && procState == proc.setProcState
2441                                 && (lastPssTime+ProcessList.PSS_SAFE_TIME_FROM_STATE_CHANGE)
2442                                         < SystemClock.uptimeMillis()) {
2443                             pid = proc.pid;
2444                         } else {
2445                             proc = null;
2446                             pid = 0;
2447                         }
2448                     }
2449                     if (proc != null) {
2450                         long pss = Debug.getPss(pid, tmp, null);
2451                         synchronized (ActivityManagerService.this) {
2452                             if (pss != 0 && proc.thread != null && proc.setProcState == procState
2453                                     && proc.pid == pid && proc.lastPssTime == lastPssTime) {
2454                                 num++;
2455                                 recordPssSampleLocked(proc, procState, pss, tmp[0], tmp[1],
2456                                         SystemClock.uptimeMillis());
2457                             }
2458                         }
2459                     }
2460                 } while (true);
2461             }
2462             }
2463         }
2464     };
2465
2466     public void setSystemProcess() {
2467         try {
2468             ServiceManager.addService(Context.ACTIVITY_SERVICE, this, true);
2469             ServiceManager.addService(ProcessStats.SERVICE_NAME, mProcessStats);
2470             ServiceManager.addService("meminfo", new MemBinder(this));
2471             ServiceManager.addService("gfxinfo", new GraphicsBinder(this));
2472             ServiceManager.addService("dbinfo", new DbBinder(this));
2473             if (MONITOR_CPU_USAGE) {
2474                 ServiceManager.addService("cpuinfo", new CpuBinder(this));
2475             }
2476             ServiceManager.addService("permission", new PermissionController(this));
2477             ServiceManager.addService("processinfo", new ProcessInfoService(this));
2478
2479             ApplicationInfo info = mContext.getPackageManager().getApplicationInfo(
2480                     "android", STOCK_PM_FLAGS | MATCH_SYSTEM_ONLY);
2481             mSystemThread.installSystemApplicationInfo(info, getClass().getClassLoader());
2482
2483             synchronized (this) {
2484                 ProcessRecord app = newProcessRecordLocked(info, info.processName, false, 0);
2485                 app.persistent = true;
2486                 app.pid = MY_PID;
2487                 app.maxAdj = ProcessList.SYSTEM_ADJ;
2488                 app.makeActive(mSystemThread.getApplicationThread(), mProcessStats);
2489                 synchronized (mPidsSelfLocked) {
2490                     mPidsSelfLocked.put(app.pid, app);
2491                 }
2492                 updateLruProcessLocked(app, false, null);
2493                 updateOomAdjLocked();
2494             }
2495         } catch (PackageManager.NameNotFoundException e) {
2496             throw new RuntimeException(
2497                     "Unable to find android system package", e);
2498         }
2499     }
2500
2501     public void setWindowManager(WindowManagerService wm) {
2502         mWindowManager = wm;
2503         mStackSupervisor.setWindowManager(wm);
2504         mActivityStarter.setWindowManager(wm);
2505     }
2506
2507     public void setUsageStatsManager(UsageStatsManagerInternal usageStatsManager) {
2508         mUsageStatsService = usageStatsManager;
2509     }
2510
2511     public void startObservingNativeCrashes() {
2512         final NativeCrashListener ncl = new NativeCrashListener(this);
2513         ncl.start();
2514     }
2515
2516     public IAppOpsService getAppOpsService() {
2517         return mAppOpsService;
2518     }
2519
2520     static class MemBinder extends Binder {
2521         ActivityManagerService mActivityManagerService;
2522         MemBinder(ActivityManagerService activityManagerService) {
2523             mActivityManagerService = activityManagerService;
2524         }
2525
2526         @Override
2527         protected void dump(FileDescriptor fd, PrintWriter pw, String[] args) {
2528             if (mActivityManagerService.checkCallingPermission(android.Manifest.permission.DUMP)
2529                     != PackageManager.PERMISSION_GRANTED) {
2530                 pw.println("Permission Denial: can't dump meminfo from from pid="
2531                         + Binder.getCallingPid() + ", uid=" + Binder.getCallingUid()
2532                         + " without permission " + android.Manifest.permission.DUMP);
2533                 return;
2534             }
2535
2536             mActivityManagerService.dumpApplicationMemoryUsage(fd, pw, "  ", args, false, null);
2537         }
2538     }
2539
2540     static class GraphicsBinder extends Binder {
2541         ActivityManagerService mActivityManagerService;
2542         GraphicsBinder(ActivityManagerService activityManagerService) {
2543             mActivityManagerService = activityManagerService;
2544         }
2545
2546         @Override
2547         protected void dump(FileDescriptor fd, PrintWriter pw, String[] args) {
2548             if (mActivityManagerService.checkCallingPermission(android.Manifest.permission.DUMP)
2549                     != PackageManager.PERMISSION_GRANTED) {
2550                 pw.println("Permission Denial: can't dump gfxinfo from from pid="
2551                         + Binder.getCallingPid() + ", uid=" + Binder.getCallingUid()
2552                         + " without permission " + android.Manifest.permission.DUMP);
2553                 return;
2554             }
2555
2556             mActivityManagerService.dumpGraphicsHardwareUsage(fd, pw, args);
2557         }
2558     }
2559
2560     static class DbBinder extends Binder {
2561         ActivityManagerService mActivityManagerService;
2562         DbBinder(ActivityManagerService activityManagerService) {
2563             mActivityManagerService = activityManagerService;
2564         }
2565
2566         @Override
2567         protected void dump(FileDescriptor fd, PrintWriter pw, String[] args) {
2568             if (mActivityManagerService.checkCallingPermission(android.Manifest.permission.DUMP)
2569                     != PackageManager.PERMISSION_GRANTED) {
2570                 pw.println("Permission Denial: can't dump dbinfo from from pid="
2571                         + Binder.getCallingPid() + ", uid=" + Binder.getCallingUid()
2572                         + " without permission " + android.Manifest.permission.DUMP);
2573                 return;
2574             }
2575
2576             mActivityManagerService.dumpDbInfo(fd, pw, args);
2577         }
2578     }
2579
2580     static class CpuBinder extends Binder {
2581         ActivityManagerService mActivityManagerService;
2582         CpuBinder(ActivityManagerService activityManagerService) {
2583             mActivityManagerService = activityManagerService;
2584         }
2585
2586         @Override
2587         protected void dump(FileDescriptor fd, PrintWriter pw, String[] args) {
2588             if (mActivityManagerService.checkCallingPermission(android.Manifest.permission.DUMP)
2589                     != PackageManager.PERMISSION_GRANTED) {
2590                 pw.println("Permission Denial: can't dump cpuinfo from from pid="
2591                         + Binder.getCallingPid() + ", uid=" + Binder.getCallingUid()
2592                         + " without permission " + android.Manifest.permission.DUMP);
2593                 return;
2594             }
2595
2596             synchronized (mActivityManagerService.mProcessCpuTracker) {
2597                 pw.print(mActivityManagerService.mProcessCpuTracker.printCurrentLoad());
2598                 pw.print(mActivityManagerService.mProcessCpuTracker.printCurrentState(
2599                         SystemClock.uptimeMillis()));
2600             }
2601         }
2602     }
2603
2604     public static final class Lifecycle extends SystemService {
2605         private final ActivityManagerService mService;
2606
2607         public Lifecycle(Context context) {
2608             super(context);
2609             mService = new ActivityManagerService(context);
2610         }
2611
2612         @Override
2613         public void onStart() {
2614             mService.start();
2615         }
2616
2617         public ActivityManagerService getService() {
2618             return mService;
2619         }
2620     }
2621
2622     // Note: This method is invoked on the main thread but may need to attach various
2623     // handlers to other threads.  So take care to be explicit about the looper.
2624     public ActivityManagerService(Context systemContext) {
2625         mContext = systemContext;
2626         mFactoryTest = FactoryTest.getMode();
2627         mSystemThread = ActivityThread.currentActivityThread();
2628
2629         Slog.i(TAG, "Memory class: " + ActivityManager.staticGetMemoryClass());
2630
2631         mPermissionReviewRequired = mContext.getResources().getBoolean(
2632                 com.android.internal.R.bool.config_permissionReviewRequired);
2633
2634         mHandlerThread = new ServiceThread(TAG,
2635                 android.os.Process.THREAD_PRIORITY_FOREGROUND, false /*allowIo*/);
2636         mHandlerThread.start();
2637         mHandler = new MainHandler(mHandlerThread.getLooper());
2638         mUiHandler = new UiHandler();
2639
2640         /* static; one-time init here */
2641         if (sKillHandler == null) {
2642             sKillThread = new ServiceThread(TAG + ":kill",
2643                     android.os.Process.THREAD_PRIORITY_BACKGROUND, true /* allowIo */);
2644             sKillThread.start();
2645             sKillHandler = new KillHandler(sKillThread.getLooper());
2646         }
2647
2648         mFgBroadcastQueue = new BroadcastQueue(this, mHandler,
2649                 "foreground", BROADCAST_FG_TIMEOUT, false);
2650         mBgBroadcastQueue = new BroadcastQueue(this, mHandler,
2651                 "background", BROADCAST_BG_TIMEOUT, true);
2652         mBroadcastQueues[0] = mFgBroadcastQueue;
2653         mBroadcastQueues[1] = mBgBroadcastQueue;
2654
2655         mServices = new ActiveServices(this);
2656         mProviderMap = new ProviderMap(this);
2657         mAppErrors = new AppErrors(mContext, this);
2658
2659         // TODO: Move creation of battery stats service outside of activity manager service.
2660         File dataDir = Environment.getDataDirectory();
2661         File systemDir = new File(dataDir, "system");
2662         systemDir.mkdirs();
2663         mBatteryStatsService = new BatteryStatsService(systemDir, mHandler);
2664         mBatteryStatsService.getActiveStatistics().readLocked();
2665         mBatteryStatsService.scheduleWriteToDisk();
2666         mOnBattery = DEBUG_POWER ? true
2667                 : mBatteryStatsService.getActiveStatistics().getIsOnBattery();
2668         mBatteryStatsService.getActiveStatistics().setCallback(this);
2669
2670         mProcessStats = new ProcessStatsService(this, new File(systemDir, "procstats"));
2671
2672         mAppOpsService = new AppOpsService(new File(systemDir, "appops.xml"), mHandler);
2673         mAppOpsService.startWatchingMode(AppOpsManager.OP_RUN_IN_BACKGROUND, null,
2674                 new IAppOpsCallback.Stub() {
2675                     @Override public void opChanged(int op, int uid, String packageName) {
2676                         if (op == AppOpsManager.OP_RUN_IN_BACKGROUND && packageName != null) {
2677                             if (mAppOpsService.checkOperation(op, uid, packageName)
2678                                     != AppOpsManager.MODE_ALLOWED) {
2679                                 runInBackgroundDisabled(uid);
2680                             }
2681                         }
2682                     }
2683                 });
2684
2685         mGrantFile = new AtomicFile(new File(systemDir, "urigrants.xml"));
2686
2687         mUserController = new UserController(this);
2688
2689         GL_ES_VERSION = SystemProperties.getInt("ro.opengles.version",
2690             ConfigurationInfo.GL_ES_VERSION_UNDEFINED);
2691
2692         if (SystemProperties.getInt("sys.use_fifo_ui", 0) != 0) {
2693             mUseFifoUiScheduling = true;
2694         }
2695
2696         mTrackingAssociations = "1".equals(SystemProperties.get("debug.track-associations"));
2697
2698         mConfiguration.setToDefaults();
2699         mConfiguration.setLocales(LocaleList.getDefault());
2700
2701         mConfigurationSeq = mConfiguration.seq = 1;
2702         mProcessCpuTracker.init();
2703
2704         mCompatModePackages = new CompatModePackages(this, systemDir, mHandler);
2705         mIntentFirewall = new IntentFirewall(new IntentFirewallInterface(), mHandler);
2706         mStackSupervisor = new ActivityStackSupervisor(this);
2707         mActivityStarter = new ActivityStarter(this, mStackSupervisor);
2708         mRecentTasks = new RecentTasks(this, mStackSupervisor);
2709
2710         mProcessCpuThread = new Thread("CpuTracker") {
2711             @Override
2712             public void run() {
2713                 while (true) {
2714                     try {
2715                         try {
2716                             synchronized(this) {
2717                                 final long now = SystemClock.uptimeMillis();
2718                                 long nextCpuDelay = (mLastCpuTime.get()+MONITOR_CPU_MAX_TIME)-now;
2719                                 long nextWriteDelay = (mLastWriteTime+BATTERY_STATS_TIME)-now;
2720                                 //Slog.i(TAG, "Cpu delay=" + nextCpuDelay
2721                                 //        + ", write delay=" + nextWriteDelay);
2722                                 if (nextWriteDelay < nextCpuDelay) {
2723                                     nextCpuDelay = nextWriteDelay;
2724                                 }
2725                                 if (nextCpuDelay > 0) {
2726                                     mProcessCpuMutexFree.set(true);
2727                                     this.wait(nextCpuDelay);
2728                                 }
2729                             }
2730                         } catch (InterruptedException e) {
2731                         }
2732                         updateCpuStatsNow();
2733                     } catch (Exception e) {
2734                         Slog.e(TAG, "Unexpected exception collecting process stats", e);
2735                     }
2736                 }
2737             }
2738         };
2739
2740         Watchdog.getInstance().addMonitor(this);
2741         Watchdog.getInstance().addThread(mHandler);
2742     }
2743
2744     public void setSystemServiceManager(SystemServiceManager mgr) {
2745         mSystemServiceManager = mgr;
2746     }
2747
2748     public void setInstaller(Installer installer) {
2749         mInstaller = installer;
2750     }
2751
2752     private void start() {
2753         Process.removeAllProcessGroups();
2754         mProcessCpuThread.start();
2755
2756         mBatteryStatsService.publish(mContext);
2757         mAppOpsService.publish(mContext);
2758         Slog.d("AppOps", "AppOpsService published");
2759         LocalServices.addService(ActivityManagerInternal.class, new LocalService());
2760     }
2761
2762     void onUserStoppedLocked(int userId) {
2763         mRecentTasks.unloadUserDataFromMemoryLocked(userId);
2764     }
2765
2766     public void initPowerManagement() {
2767         mStackSupervisor.initPowerManagement();
2768         mBatteryStatsService.initPowerManagement();
2769         mLocalPowerManager = LocalServices.getService(PowerManagerInternal.class);
2770         PowerManager pm = (PowerManager)mContext.getSystemService(Context.POWER_SERVICE);
2771         mVoiceWakeLock = pm.newWakeLock(PowerManager.PARTIAL_WAKE_LOCK, "*voice*");
2772         mVoiceWakeLock.setReferenceCounted(false);
2773     }
2774
2775     @Override
2776     public boolean onTransact(int code, Parcel data, Parcel reply, int flags)
2777             throws RemoteException {
2778         if (code == SYSPROPS_TRANSACTION) {
2779             // We need to tell all apps about the system property change.
2780             ArrayList<IBinder> procs = new ArrayList<IBinder>();
2781             synchronized(this) {
2782                 final int NP = mProcessNames.getMap().size();
2783                 for (int ip=0; ip<NP; ip++) {
2784                     SparseArray<ProcessRecord> apps = mProcessNames.getMap().valueAt(ip);
2785                     final int NA = apps.size();
2786                     for (int ia=0; ia<NA; ia++) {
2787                         ProcessRecord app = apps.valueAt(ia);
2788                         if (app.thread != null) {
2789                             procs.add(app.thread.asBinder());
2790                         }
2791                     }
2792                 }
2793             }
2794
2795             int N = procs.size();
2796             for (int i=0; i<N; i++) {
2797                 Parcel data2 = Parcel.obtain();
2798                 try {
2799                     procs.get(i).transact(IBinder.SYSPROPS_TRANSACTION, data2, null, 0);
2800                 } catch (RemoteException e) {
2801                 }
2802                 data2.recycle();
2803             }
2804         }
2805         try {
2806             return super.onTransact(code, data, reply, flags);
2807         } catch (RuntimeException e) {
2808             // The activity manager only throws security exceptions, so let's
2809             // log all others.
2810             if (!(e instanceof SecurityException)) {
2811                 Slog.wtf(TAG, "Activity Manager Crash", e);
2812             }
2813             throw e;
2814         }
2815     }
2816
2817     void updateCpuStats() {
2818         final long now = SystemClock.uptimeMillis();
2819         if (mLastCpuTime.get() >= now - MONITOR_CPU_MIN_TIME) {
2820             return;
2821         }
2822         if (mProcessCpuMutexFree.compareAndSet(true, false)) {
2823             synchronized (mProcessCpuThread) {
2824                 mProcessCpuThread.notify();
2825             }
2826         }
2827     }
2828
2829     void updateCpuStatsNow() {
2830         synchronized (mProcessCpuTracker) {
2831             mProcessCpuMutexFree.set(false);
2832             final long now = SystemClock.uptimeMillis();
2833             boolean haveNewCpuStats = false;
2834
2835             if (MONITOR_CPU_USAGE &&
2836                     mLastCpuTime.get() < (now-MONITOR_CPU_MIN_TIME)) {
2837                 mLastCpuTime.set(now);
2838                 mProcessCpuTracker.update();
2839                 if (mProcessCpuTracker.hasGoodLastStats()) {
2840                     haveNewCpuStats = true;
2841                     //Slog.i(TAG, mProcessCpu.printCurrentState());
2842                     //Slog.i(TAG, "Total CPU usage: "
2843                     //        + mProcessCpu.getTotalCpuPercent() + "%");
2844
2845                     // Slog the cpu usage if the property is set.
2846                     if ("true".equals(SystemProperties.get("events.cpu"))) {
2847                         int user = mProcessCpuTracker.getLastUserTime();
2848                         int system = mProcessCpuTracker.getLastSystemTime();
2849                         int iowait = mProcessCpuTracker.getLastIoWaitTime();
2850                         int irq = mProcessCpuTracker.getLastIrqTime();
2851                         int softIrq = mProcessCpuTracker.getLastSoftIrqTime();
2852                         int idle = mProcessCpuTracker.getLastIdleTime();
2853
2854                         int total = user + system + iowait + irq + softIrq + idle;
2855                         if (total == 0) total = 1;
2856
2857                         EventLog.writeEvent(EventLogTags.CPU,
2858                                 ((user+system+iowait+irq+softIrq) * 100) / total,
2859                                 (user * 100) / total,
2860                                 (system * 100) / total,
2861                                 (iowait * 100) / total,
2862                                 (irq * 100) / total,
2863                                 (softIrq * 100) / total);
2864                     }
2865                 }
2866             }
2867
2868             final BatteryStatsImpl bstats = mBatteryStatsService.getActiveStatistics();
2869             synchronized(bstats) {
2870                 synchronized(mPidsSelfLocked) {
2871                     if (haveNewCpuStats) {
2872                         if (bstats.startAddingCpuLocked()) {
2873                             int totalUTime = 0;
2874                             int totalSTime = 0;
2875                             final int N = mProcessCpuTracker.countStats();
2876                             for (int i=0; i<N; i++) {
2877                                 ProcessCpuTracker.Stats st = mProcessCpuTracker.getStats(i);
2878                                 if (!st.working) {
2879                                     continue;
2880                                 }
2881                                 ProcessRecord pr = mPidsSelfLocked.get(st.pid);
2882                                 totalUTime += st.rel_utime;
2883                                 totalSTime += st.rel_stime;
2884                                 if (pr != null) {
2885                                     BatteryStatsImpl.Uid.Proc ps = pr.curProcBatteryStats;
2886                                     if (ps == null || !ps.isActive()) {
2887                                         pr.curProcBatteryStats = ps = bstats.getProcessStatsLocked(
2888                                                 pr.info.uid, pr.processName);
2889                                     }
2890                                     ps.addCpuTimeLocked(st.rel_utime, st.rel_stime);
2891                                     pr.curCpuTime += st.rel_utime + st.rel_stime;
2892                                 } else {
2893                                     BatteryStatsImpl.Uid.Proc ps = st.batteryStats;
2894                                     if (ps == null || !ps.isActive()) {
2895                                         st.batteryStats = ps = bstats.getProcessStatsLocked(
2896                                                 bstats.mapUid(st.uid), st.name);
2897                                     }
2898                                     ps.addCpuTimeLocked(st.rel_utime, st.rel_stime);
2899                                 }
2900                             }
2901                             final int userTime = mProcessCpuTracker.getLastUserTime();
2902                             final int systemTime = mProcessCpuTracker.getLastSystemTime();
2903                             final int iowaitTime = mProcessCpuTracker.getLastIoWaitTime();
2904                             final int irqTime = mProcessCpuTracker.getLastIrqTime();
2905                             final int softIrqTime = mProcessCpuTracker.getLastSoftIrqTime();
2906                             final int idleTime = mProcessCpuTracker.getLastIdleTime();
2907                             bstats.finishAddingCpuLocked(totalUTime, totalSTime, userTime,
2908                                     systemTime, iowaitTime, irqTime, softIrqTime, idleTime);
2909                         }
2910                     }
2911                 }
2912
2913                 if (mLastWriteTime < (now-BATTERY_STATS_TIME)) {
2914                     mLastWriteTime = now;
2915                     mBatteryStatsService.scheduleWriteToDisk();
2916                 }
2917             }
2918         }
2919     }
2920
2921     @Override
2922     public void batteryNeedsCpuUpdate() {
2923         updateCpuStatsNow();
2924     }
2925
2926     @Override
2927     public void batteryPowerChanged(boolean onBattery) {
2928         // When plugging in, update the CPU stats first before changing
2929         // the plug state.
2930         updateCpuStatsNow();
2931         synchronized (this) {
2932             synchronized(mPidsSelfLocked) {
2933                 mOnBattery = DEBUG_POWER ? true : onBattery;
2934             }
2935         }
2936     }
2937
2938     @Override
2939     public void batterySendBroadcast(Intent intent) {
2940         broadcastIntentLocked(null, null, intent, null, null, 0, null, null, null,
2941                 AppOpsManager.OP_NONE, null, false, false,
2942                 -1, Process.SYSTEM_UID, UserHandle.USER_ALL);
2943     }
2944
2945     /**
2946      * Initialize the application bind args. These are passed to each
2947      * process when the bindApplication() IPC is sent to the process. They're
2948      * lazily setup to make sure the services are running when they're asked for.
2949      */
2950     private HashMap<String, IBinder> getCommonServicesLocked(boolean isolated) {
2951         // Isolated processes won't get this optimization, so that we don't
2952         // violate the rules about which services they have access to.
2953         if (isolated) {
2954             if (mIsolatedAppBindArgs == null) {
2955                 mIsolatedAppBindArgs = new HashMap<>();
2956                 mIsolatedAppBindArgs.put("package", ServiceManager.getService("package"));
2957             }
2958             return mIsolatedAppBindArgs;
2959         }
2960
2961         if (mAppBindArgs == null) {
2962             mAppBindArgs = new HashMap<>();
2963
2964             // Setup the application init args
2965             mAppBindArgs.put("package", ServiceManager.getService("package"));
2966             mAppBindArgs.put("window", ServiceManager.getService("window"));
2967             mAppBindArgs.put(Context.ALARM_SERVICE,
2968                     ServiceManager.getService(Context.ALARM_SERVICE));
2969         }
2970         return mAppBindArgs;
2971     }
2972
2973     boolean setFocusedActivityLocked(ActivityRecord r, String reason) {
2974         if (r == null || mFocusedActivity == r) {
2975             return false;
2976         }
2977
2978         if (!r.isFocusable()) {
2979             if (DEBUG_FOCUS) Slog.d(TAG_FOCUS, "setFocusedActivityLocked: unfocusable r=" + r);
2980             return false;
2981         }
2982
2983         if (DEBUG_FOCUS) Slog.d(TAG_FOCUS, "setFocusedActivityLocked: r=" + r);
2984
2985         final boolean wasDoingSetFocusedActivity = mDoingSetFocusedActivity;
2986         if (wasDoingSetFocusedActivity) Slog.w(TAG,
2987                 "setFocusedActivityLocked: called recursively, r=" + r + ", reason=" + reason);
2988         mDoingSetFocusedActivity = true;
2989
2990         final ActivityRecord last = mFocusedActivity;
2991         mFocusedActivity = r;
2992         if (r.task.isApplicationTask()) {
2993             if (mCurAppTimeTracker != r.appTimeTracker) {
2994                 // We are switching app tracking.  Complete the current one.
2995                 if (mCurAppTimeTracker != null) {
2996                     mCurAppTimeTracker.stop();
2997                     mHandler.obtainMessage(
2998                             REPORT_TIME_TRACKER_MSG, mCurAppTimeTracker).sendToTarget();
2999                     mStackSupervisor.clearOtherAppTimeTrackers(r.appTimeTracker);
3000                     mCurAppTimeTracker = null;
3001                 }
3002                 if (r.appTimeTracker != null) {
3003                     mCurAppTimeTracker = r.appTimeTracker;
3004                     startTimeTrackingFocusedActivityLocked();
3005                 }
3006             } else {
3007                 startTimeTrackingFocusedActivityLocked();
3008             }
3009         } else {
3010             r.appTimeTracker = null;
3011         }
3012         // TODO: VI Maybe r.task.voiceInteractor || r.voiceInteractor != null
3013         // TODO: Probably not, because we don't want to resume voice on switching
3014         // back to this activity
3015         if (r.task.voiceInteractor != null) {
3016             startRunningVoiceLocked(r.task.voiceSession, r.info.applicationInfo.uid);
3017         } else {
3018             finishRunningVoiceLocked();
3019             IVoiceInteractionSession session;
3020             if (last != null && ((session = last.task.voiceSession) != null
3021                     || (session = last.voiceSession) != null)) {
3022                 // We had been in a voice interaction session, but now focused has
3023                 // move to something different.  Just finish the session, we can't
3024                 // return to it and retain the proper state and synchronization with
3025                 // the voice interaction service.
3026                 finishVoiceTask(session);
3027             }
3028         }
3029         if (mStackSupervisor.moveActivityStackToFront(r, reason + " setFocusedActivity")) {
3030             mWindowManager.setFocusedApp(r.appToken, true);
3031         }
3032         applyUpdateLockStateLocked(r);
3033         applyUpdateVrModeLocked(r);
3034         if (mFocusedActivity.userId != mLastFocusedUserId) {
3035             mHandler.removeMessages(FOREGROUND_PROFILE_CHANGED_MSG);
3036             mHandler.obtainMessage(
3037                     FOREGROUND_PROFILE_CHANGED_MSG, mFocusedActivity.userId, 0).sendToTarget();
3038             mLastFocusedUserId = mFocusedActivity.userId;
3039         }
3040
3041         // Log a warning if the focused app is changed during the process. This could
3042         // indicate a problem of the focus setting logic!
3043         if (mFocusedActivity != r) Slog.w(TAG,
3044                 "setFocusedActivityLocked: r=" + r + " but focused to " + mFocusedActivity);
3045         mDoingSetFocusedActivity = wasDoingSetFocusedActivity;
3046
3047         EventLogTags.writeAmFocusedActivity(
3048                 mFocusedActivity == null ? -1 : mFocusedActivity.userId,
3049                 mFocusedActivity == null ? "NULL" : mFocusedActivity.shortComponentName,
3050                 reason);
3051         return true;
3052     }
3053
3054     final void resetFocusedActivityIfNeededLocked(ActivityRecord goingAway) {
3055         if (mFocusedActivity != goingAway) {
3056             return;
3057         }
3058
3059         final ActivityStack focusedStack = mStackSupervisor.getFocusedStack();
3060         if (focusedStack != null) {
3061             final ActivityRecord top = focusedStack.topActivity();
3062             if (top != null && top.userId != mLastFocusedUserId) {
3063                 mHandler.removeMessages(FOREGROUND_PROFILE_CHANGED_MSG);
3064                 mHandler.sendMessage(
3065                         mHandler.obtainMessage(FOREGROUND_PROFILE_CHANGED_MSG, top.userId, 0));
3066                 mLastFocusedUserId = top.userId;
3067             }
3068         }
3069
3070         // Try to move focus to another activity if possible.
3071         if (setFocusedActivityLocked(
3072                 focusedStack.topRunningActivityLocked(), "resetFocusedActivityIfNeeded")) {
3073             return;
3074         }
3075
3076         if (DEBUG_FOCUS) Slog.d(TAG_FOCUS, "resetFocusedActivityIfNeeded: Setting focus to NULL "
3077                 + "prev mFocusedActivity=" + mFocusedActivity + " goingAway=" + goingAway);
3078         mFocusedActivity = null;
3079         EventLogTags.writeAmFocusedActivity(-1, "NULL", "resetFocusedActivityIfNeeded");
3080     }
3081
3082     @Override
3083     public void setFocusedStack(int stackId) {
3084         enforceCallingPermission(MANAGE_ACTIVITY_STACKS, "setFocusedStack()");
3085         if (DEBUG_FOCUS) Slog.d(TAG_FOCUS, "setFocusedStack: stackId=" + stackId);
3086         final long callingId = Binder.clearCallingIdentity();
3087         try {
3088             synchronized (this) {
3089                 final ActivityStack stack = mStackSupervisor.getStack(stackId);
3090                 if (stack == null) {
3091                     return;
3092                 }
3093                 final ActivityRecord r = stack.topRunningActivityLocked();
3094                 if (setFocusedActivityLocked(r, "setFocusedStack")) {
3095                     mStackSupervisor.resumeFocusedStackTopActivityLocked();
3096                 }
3097             }
3098         } finally {
3099             Binder.restoreCallingIdentity(callingId);
3100         }
3101     }
3102
3103     @Override
3104     public void setFocusedTask(int taskId) {
3105         enforceCallingPermission(MANAGE_ACTIVITY_STACKS, "setFocusedTask()");
3106         if (DEBUG_FOCUS) Slog.d(TAG_FOCUS, "setFocusedTask: taskId=" + taskId);
3107         final long callingId = Binder.clearCallingIdentity();
3108         try {
3109             synchronized (this) {
3110                 final TaskRecord task = mStackSupervisor.anyTaskForIdLocked(taskId);
3111                 if (task == null) {
3112                     return;
3113                 }
3114                 if (mUserController.shouldConfirmCredentials(task.userId)) {
3115                     mActivityStarter.showConfirmDeviceCredential(task.userId);
3116                     if (task.stack != null && task.stack.mStackId == FREEFORM_WORKSPACE_STACK_ID) {
3117                         mStackSupervisor.moveTaskToStackLocked(task.taskId,
3118                                 FULLSCREEN_WORKSPACE_STACK_ID, !ON_TOP, !FORCE_FOCUS,
3119                                 "setFocusedTask", ANIMATE);
3120                     }
3121                     return;
3122                 }
3123                 final ActivityRecord r = task.topRunningActivityLocked();
3124                 if (setFocusedActivityLocked(r, "setFocusedTask")) {
3125                     mStackSupervisor.resumeFocusedStackTopActivityLocked();
3126                 }
3127             }
3128         } finally {
3129             Binder.restoreCallingIdentity(callingId);
3130         }
3131     }
3132
3133     /** Sets the task stack listener that gets callbacks when a task stack changes. */
3134     @Override
3135     public void registerTaskStackListener(ITaskStackListener listener) throws RemoteException {
3136         enforceCallingPermission(MANAGE_ACTIVITY_STACKS, "registerTaskStackListener()");
3137         synchronized (this) {
3138             if (listener != null) {
3139                 mTaskStackListeners.register(listener);
3140             }
3141         }
3142     }
3143
3144     @Override
3145     public void notifyActivityDrawn(IBinder token) {
3146         if (DEBUG_VISIBILITY) Slog.d(TAG_VISIBILITY, "notifyActivityDrawn: token=" + token);
3147         synchronized (this) {
3148             ActivityRecord r = mStackSupervisor.isInAnyStackLocked(token);
3149             if (r != null) {
3150                 r.task.stack.notifyActivityDrawnLocked(r);
3151             }
3152         }
3153     }
3154
3155     final void applyUpdateLockStateLocked(ActivityRecord r) {
3156         // Modifications to the UpdateLock state are done on our handler, outside
3157         // the activity manager's locks.  The new state is determined based on the
3158         // state *now* of the relevant activity record.  The object is passed to
3159         // the handler solely for logging detail, not to be consulted/modified.
3160         final boolean nextState = r != null && r.immersive;
3161         mHandler.sendMessage(
3162                 mHandler.obtainMessage(IMMERSIVE_MODE_LOCK_MSG, (nextState) ? 1 : 0, 0, r));
3163     }
3164
3165     final void applyUpdateVrModeLocked(ActivityRecord r) {
3166         mHandler.sendMessage(
3167                 mHandler.obtainMessage(VR_MODE_CHANGE_MSG, 0, 0, r));
3168     }
3169
3170     private void sendNotifyVrManagerOfSleepState(boolean isSleeping) {
3171         mHandler.sendMessage(
3172                 mHandler.obtainMessage(NOTIFY_VR_SLEEPING_MSG, isSleeping ? 1 : 0, 0));
3173     }
3174
3175     private void notifyVrManagerOfSleepState(boolean isSleeping) {
3176         final VrManagerInternal vrService = LocalServices.getService(VrManagerInternal.class);
3177         if (vrService == null) {
3178             return;
3179         }
3180         vrService.onSleepStateChanged(isSleeping);
3181     }
3182
3183     final void showAskCompatModeDialogLocked(ActivityRecord r) {
3184         Message msg = Message.obtain();
3185         msg.what = SHOW_COMPAT_MODE_DIALOG_UI_MSG;
3186         msg.obj = r.task.askedCompatMode ? null : r;
3187         mUiHandler.sendMessage(msg);
3188     }
3189
3190     final void showUnsupportedZoomDialogIfNeededLocked(ActivityRecord r) {
3191         if (mConfiguration.densityDpi != DisplayMetrics.DENSITY_DEVICE_STABLE
3192                 && r.appInfo.requiresSmallestWidthDp > mConfiguration.smallestScreenWidthDp) {
3193             final Message msg = Message.obtain();
3194             msg.what = SHOW_UNSUPPORTED_DISPLAY_SIZE_DIALOG_MSG;
3195             msg.obj = r;
3196             mUiHandler.sendMessage(msg);
3197         }
3198     }
3199
3200     private int updateLruProcessInternalLocked(ProcessRecord app, long now, int index,
3201             String what, Object obj, ProcessRecord srcApp) {
3202         app.lastActivityTime = now;
3203
3204         if (app.activities.size() > 0) {
3205             // Don't want to touch dependent processes that are hosting activities.
3206             return index;
3207         }
3208
3209         int lrui = mLruProcesses.lastIndexOf(app);
3210         if (lrui < 0) {
3211             Slog.wtf(TAG, "Adding dependent process " + app + " not on LRU list: "
3212                     + what + " " + obj + " from " + srcApp);
3213             return index;
3214         }
3215
3216         if (lrui >= index) {
3217             // Don't want to cause this to move dependent processes *back* in the
3218             // list as if they were less frequently used.
3219             return index;
3220         }
3221
3222         if (lrui >= mLruProcessActivityStart) {
3223             // Don't want to touch dependent processes that are hosting activities.
3224             return index;
3225         }
3226
3227         mLruProcesses.remove(lrui);
3228         if (index > 0) {
3229             index--;
3230         }
3231         if (DEBUG_LRU) Slog.d(TAG_LRU, "Moving dep from " + lrui + " to " + index
3232                 + " in LRU list: " + app);
3233         mLruProcesses.add(index, app);
3234         return index;
3235     }
3236
3237     static void killProcessGroup(int uid, int pid) {
3238         if (sKillHandler != null) {
3239             sKillHandler.sendMessage(
3240                     sKillHandler.obtainMessage(KillHandler.KILL_PROCESS_GROUP_MSG, uid, pid));
3241         } else {
3242             Slog.w(TAG, "Asked to kill process group before system bringup!");
3243             Process.killProcessGroup(uid, pid);
3244         }
3245     }
3246
3247     final void removeLruProcessLocked(ProcessRecord app) {
3248         int lrui = mLruProcesses.lastIndexOf(app);
3249         if (lrui >= 0) {
3250             if (!app.killed) {
3251                 Slog.wtfStack(TAG, "Removing process that hasn't been killed: " + app);
3252                 Process.killProcessQuiet(app.pid);
3253                 killProcessGroup(app.uid, app.pid);
3254             }
3255             if (lrui <= mLruProcessActivityStart) {
3256                 mLruProcessActivityStart--;
3257             }
3258             if (lrui <= mLruProcessServiceStart) {
3259                 mLruProcessServiceStart--;
3260             }
3261             mLruProcesses.remove(lrui);
3262         }
3263     }
3264
3265     final void updateLruProcessLocked(ProcessRecord app, boolean activityChange,
3266             ProcessRecord client) {
3267         final boolean hasActivity = app.activities.size() > 0 || app.hasClientActivities
3268                 || app.treatLikeActivity;
3269         final boolean hasService = false; // not impl yet. app.services.size() > 0;
3270         if (!activityChange && hasActivity) {
3271             // The process has activities, so we are only allowing activity-based adjustments
3272             // to move it.  It should be kept in the front of the list with other
3273             // processes that have activities, and we don't want those to change their
3274             // order except due to activity operations.
3275             return;
3276         }
3277
3278         mLruSeq++;
3279         final long now = SystemClock.uptimeMillis();
3280         app.lastActivityTime = now;
3281
3282         // First a quick reject: if the app is already at the position we will
3283         // put it, then there is nothing to do.
3284         if (hasActivity) {
3285             final int N = mLruProcesses.size();
3286             if (N > 0 && mLruProcesses.get(N-1) == app) {
3287                 if (DEBUG_LRU) Slog.d(TAG_LRU, "Not moving, already top activity: " + app);
3288                 return;
3289             }
3290         } else {
3291             if (mLruProcessServiceStart > 0
3292                     && mLruProcesses.get(mLruProcessServiceStart-1) == app) {
3293                 if (DEBUG_LRU) Slog.d(TAG_LRU, "Not moving, already top other: " + app);
3294                 return;
3295             }
3296         }
3297
3298         int lrui = mLruProcesses.lastIndexOf(app);
3299
3300         if (app.persistent && lrui >= 0) {
3301             // We don't care about the position of persistent processes, as long as
3302             // they are in the list.
3303             if (DEBUG_LRU) Slog.d(TAG_LRU, "Not moving, persistent: " + app);
3304             return;
3305         }
3306
3307         /* In progress: compute new position first, so we can avoid doing work
3308            if the process is not actually going to move.  Not yet working.
3309         int addIndex;
3310         int nextIndex;
3311         boolean inActivity = false, inService = false;
3312         if (hasActivity) {
3313             // Process has activities, put it at the very tipsy-top.
3314             addIndex = mLruProcesses.size();
3315             nextIndex = mLruProcessServiceStart;
3316             inActivity = true;
3317         } else if (hasService) {
3318             // Process has services, put it at the top of the service list.
3319             addIndex = mLruProcessActivityStart;
3320             nextIndex = mLruProcessServiceStart;
3321             inActivity = true;
3322             inService = true;
3323         } else  {
3324             // Process not otherwise of interest, it goes to the top of the non-service area.
3325             addIndex = mLruProcessServiceStart;
3326             if (client != null) {
3327                 int clientIndex = mLruProcesses.lastIndexOf(client);
3328                 if (clientIndex < 0) Slog.d(TAG, "Unknown client " + client + " when updating "
3329                         + app);
3330                 if (clientIndex >= 0 && addIndex > clientIndex) {
3331                     addIndex = clientIndex;
3332                 }
3333             }
3334             nextIndex = addIndex > 0 ? addIndex-1 : addIndex;
3335         }
3336
3337         Slog.d(TAG, "Update LRU at " + lrui + " to " + addIndex + " (act="
3338                 + mLruProcessActivityStart + "): " + app);
3339         */
3340
3341         if (lrui >= 0) {
3342             if (lrui < mLruProcessActivityStart) {
3343                 mLruProcessActivityStart--;
3344             }
3345             if (lrui < mLruProcessServiceStart) {
3346                 mLruProcessServiceStart--;
3347             }
3348             /*
3349             if (addIndex > lrui) {
3350                 addIndex--;
3351             }
3352             if (nextIndex > lrui) {
3353                 nextIndex--;
3354             }
3355             */
3356             mLruProcesses.remove(lrui);
3357         }
3358
3359         /*
3360         mLruProcesses.add(addIndex, app);
3361         if (inActivity) {
3362             mLruProcessActivityStart++;
3363         }
3364         if (inService) {
3365             mLruProcessActivityStart++;
3366         }
3367         */
3368
3369         int nextIndex;
3370         if (hasActivity) {
3371             final int N = mLruProcesses.size();
3372             if (app.activities.size() == 0 && mLruProcessActivityStart < (N - 1)) {
3373                 // Process doesn't have activities, but has clients with
3374                 // activities...  move it up, but one below the top (the top
3375                 // should always have a real activity).
3376                 if (DEBUG_LRU) Slog.d(TAG_LRU,
3377                         "Adding to second-top of LRU activity list: " + app);
3378                 mLruProcesses.add(N - 1, app);
3379                 // To keep it from spamming the LRU list (by making a bunch of clients),
3380                 // we will push down any other entries owned by the app.
3381                 final int uid = app.info.uid;
3382                 for (int i = N - 2; i > mLruProcessActivityStart; i--) {
3383                     ProcessRecord subProc = mLruProcesses.get(i);
3384                     if (subProc.info.uid == uid) {
3385                         // We want to push this one down the list.  If the process after
3386                         // it is for the same uid, however, don't do so, because we don't
3387                         // want them internally to be re-ordered.
3388                         if (mLruProcesses.get(i - 1).info.uid != uid) {
3389                             if (DEBUG_LRU) Slog.d(TAG_LRU,
3390                                     "Pushing uid " + uid + " swapping at " + i + ": "
3391                                     + mLruProcesses.get(i) + " : " + mLruProcesses.get(i - 1));
3392                             ProcessRecord tmp = mLruProcesses.get(i);
3393                             mLruProcesses.set(i, mLruProcesses.get(i - 1));
3394                             mLruProcesses.set(i - 1, tmp);
3395                             i--;
3396                         }
3397                     } else {
3398                         // A gap, we can stop here.
3399                         break;
3400                     }
3401                 }
3402             } else {
3403                 // Process has activities, put it at the very tipsy-top.
3404                 if (DEBUG_LRU) Slog.d(TAG_LRU, "Adding to top of LRU activity list: " + app);
3405                 mLruProcesses.add(app);
3406             }
3407             nextIndex = mLruProcessServiceStart;
3408         } else if (hasService) {
3409             // Process has services, put it at the top of the service list.
3410             if (DEBUG_LRU) Slog.d(TAG_LRU, "Adding to top of LRU service list: " + app);
3411             mLruProcesses.add(mLruProcessActivityStart, app);
3412             nextIndex = mLruProcessServiceStart;
3413             mLruProcessActivityStart++;
3414         } else  {
3415             // Process not otherwise of interest, it goes to the top of the non-service area.
3416             int index = mLruProcessServiceStart;
3417             if (client != null) {
3418                 // If there is a client, don't allow the process to be moved up higher
3419                 // in the list than that client.
3420                 int clientIndex = mLruProcesses.lastIndexOf(client);
3421                 if (DEBUG_LRU && clientIndex < 0) Slog.d(TAG_LRU, "Unknown client " + client
3422                         + " when updating " + app);
3423                 if (clientIndex <= lrui) {
3424                     // Don't allow the client index restriction to push it down farther in the
3425                     // list than it already is.
3426                     clientIndex = lrui;
3427                 }
3428                 if (clientIndex >= 0 && index > clientIndex) {
3429                     index = clientIndex;
3430                 }
3431             }
3432             if (DEBUG_LRU) Slog.d(TAG_LRU, "Adding at " + index + " of LRU list: " + app);
3433             mLruProcesses.add(index, app);
3434             nextIndex = index-1;
3435             mLruProcessActivityStart++;
3436             mLruProcessServiceStart++;
3437         }
3438
3439         // If the app is currently using a content provider or service,
3440         // bump those processes as well.
3441         for (int j=app.connections.size()-1; j>=0; j--) {
3442             ConnectionRecord cr = app.connections.valueAt(j);
3443             if (cr.binding != null && !cr.serviceDead && cr.binding.service != null
3444                     && cr.binding.service.app != null
3445                     && cr.binding.service.app.lruSeq != mLruSeq
3446                     && !cr.binding.service.app.persistent) {
3447                 nextIndex = updateLruProcessInternalLocked(cr.binding.service.app, now, nextIndex,
3448                         "service connection", cr, app);
3449             }
3450         }
3451         for (int j=app.conProviders.size()-1; j>=0; j--) {
3452             ContentProviderRecord cpr = app.conProviders.get(j).provider;
3453             if (cpr.proc != null && cpr.proc.lruSeq != mLruSeq && !cpr.proc.persistent) {
3454                 nextIndex = updateLruProcessInternalLocked(cpr.proc, now, nextIndex,
3455                         "provider reference", cpr, app);
3456             }
3457         }
3458     }
3459
3460     final ProcessRecord getProcessRecordLocked(String processName, int uid, boolean keepIfLarge) {
3461         if (uid == Process.SYSTEM_UID) {
3462             // The system gets to run in any process.  If there are multiple
3463             // processes with the same uid, just pick the first (this
3464             // should never happen).
3465             SparseArray<ProcessRecord> procs = mProcessNames.getMap().get(processName);
3466             if (procs == null) return null;
3467             final int procCount = procs.size();
3468             for (int i = 0; i < procCount; i++) {
3469                 final int procUid = procs.keyAt(i);
3470                 if (UserHandle.isApp(procUid) || !UserHandle.isSameUser(procUid, uid)) {
3471                     // Don't use an app process or different user process for system component.
3472                     continue;
3473                 }
3474                 return procs.valueAt(i);
3475             }
3476         }
3477         ProcessRecord proc = mProcessNames.get(processName, uid);
3478         if (false && proc != null && !keepIfLarge
3479                 && proc.setProcState >= ActivityManager.PROCESS_STATE_CACHED_EMPTY
3480                 && proc.lastCachedPss >= 4000) {
3481             // Turn this condition on to cause killing to happen regularly, for testing.
3482             if (proc.baseProcessTracker != null) {
3483                 proc.baseProcessTracker.reportCachedKill(proc.pkgList, proc.lastCachedPss);
3484             }
3485             proc.kill(Long.toString(proc.lastCachedPss) + "k from cached", true);
3486         } else if (proc != null && !keepIfLarge
3487                 && mLastMemoryLevel > ProcessStats.ADJ_MEM_FACTOR_NORMAL
3488                 && proc.setProcState >= ActivityManager.PROCESS_STATE_CACHED_EMPTY) {
3489             if (DEBUG_PSS) Slog.d(TAG_PSS, "May not keep " + proc + ": pss=" + proc.lastCachedPss);
3490             if (proc.lastCachedPss >= mProcessList.getCachedRestoreThresholdKb()) {
3491                 if (proc.baseProcessTracker != null) {
3492                     proc.baseProcessTracker.reportCachedKill(proc.pkgList, proc.lastCachedPss);
3493                 }
3494                 proc.kill(Long.toString(proc.lastCachedPss) + "k from cached", true);
3495             }
3496         }
3497         return proc;
3498     }
3499
3500     void notifyPackageUse(String packageName, int reason) {
3501         IPackageManager pm = AppGlobals.getPackageManager();
3502         try {
3503             pm.notifyPackageUse(packageName, reason);
3504         } catch (RemoteException e) {
3505         }
3506     }
3507
3508     boolean isNextTransitionForward() {
3509         int transit = mWindowManager.getPendingAppTransition();
3510         return transit == TRANSIT_ACTIVITY_OPEN
3511                 || transit == TRANSIT_TASK_OPEN
3512                 || transit == TRANSIT_TASK_TO_FRONT;
3513     }
3514
3515     int startIsolatedProcess(String entryPoint, String[] entryPointArgs,
3516             String processName, String abiOverride, int uid, Runnable crashHandler) {
3517         synchronized(this) {
3518             ApplicationInfo info = new ApplicationInfo();
3519             // In general the ApplicationInfo.uid isn't neccesarily equal to ProcessRecord.uid.
3520             // For isolated processes, the former contains the parent's uid and the latter the
3521             // actual uid of the isolated process.
3522             // In the special case introduced by this method (which is, starting an isolated
3523             // process directly from the SystemServer without an actual parent app process) the
3524             // closest thing to a parent's uid is SYSTEM_UID.
3525             // The only important thing here is to keep AI.uid != PR.uid, in order to trigger
3526             // the |isolated| logic in the ProcessRecord constructor.
3527             info.uid = Process.SYSTEM_UID;
3528             info.processName = processName;
3529             info.className = entryPoint;
3530             info.packageName = "android";
3531             ProcessRecord proc = startProcessLocked(processName, info /* info */,
3532                     false /* knownToBeDead */, 0 /* intentFlags */, ""  /* hostingType */,
3533                     null /* hostingName */, true /* allowWhileBooting */, true /* isolated */,
3534                     uid, true /* keepIfLarge */, abiOverride, entryPoint, entryPointArgs,
3535                     crashHandler);
3536             return proc != null ? proc.pid : 0;
3537         }
3538     }
3539
3540     final ProcessRecord startProcessLocked(String processName,
3541             ApplicationInfo info, boolean knownToBeDead, int intentFlags,
3542             String hostingType, ComponentName hostingName, boolean allowWhileBooting,
3543             boolean isolated, boolean keepIfLarge) {
3544         return startProcessLocked(processName, info, knownToBeDead, intentFlags, hostingType,
3545                 hostingName, allowWhileBooting, isolated, 0 /* isolatedUid */, keepIfLarge,
3546                 null /* ABI override */, null /* entryPoint */, null /* entryPointArgs */,
3547                 null /* crashHandler */);
3548     }
3549
3550     final ProcessRecord startProcessLocked(String processName, ApplicationInfo info,
3551             boolean knownToBeDead, int intentFlags, String hostingType, ComponentName hostingName,
3552             boolean allowWhileBooting, boolean isolated, int isolatedUid, boolean keepIfLarge,
3553             String abiOverride, String entryPoint, String[] entryPointArgs, Runnable crashHandler) {
3554         long startTime = SystemClock.elapsedRealtime();
3555         ProcessRecord app;
3556         if (!isolated) {
3557             app = getProcessRecordLocked(processName, info.uid, keepIfLarge);
3558             checkTime(startTime, "startProcess: after getProcessRecord");
3559
3560             if ((intentFlags & Intent.FLAG_FROM_BACKGROUND) != 0) {
3561                 // If we are in the background, then check to see if this process
3562                 // is bad.  If so, we will just silently fail.
3563                 if (mAppErrors.isBadProcessLocked(info)) {
3564                     if (DEBUG_PROCESSES) Slog.v(TAG, "Bad process: " + info.uid
3565                             + "/" + info.processName);
3566                     return null;
3567                 }
3568             } else {
3569                 // When the user is explicitly starting a process, then clear its
3570                 // crash count so that we won't make it bad until they see at
3571                 // least one crash dialog again, and make the process good again
3572                 // if it had been bad.
3573                 if (DEBUG_PROCESSES) Slog.v(TAG, "Clearing bad process: " + info.uid
3574                         + "/" + info.processName);
3575                 mAppErrors.resetProcessCrashTimeLocked(info);
3576                 if (mAppErrors.isBadProcessLocked(info)) {
3577                     EventLog.writeEvent(EventLogTags.AM_PROC_GOOD,
3578                             UserHandle.getUserId(info.uid), info.uid,
3579                             info.processName);
3580                     mAppErrors.clearBadProcessLocked(info);
3581                     if (app != null) {
3582                         app.bad = false;
3583                     }
3584                 }
3585             }
3586         } else {
3587             // If this is an isolated process, it can't re-use an existing process.
3588             app = null;
3589         }
3590
3591         // app launch boost for big.little configurations
3592         // use cpusets to migrate freshly launched tasks to big cores
3593         nativeMigrateToBoost();
3594         mIsBoosted = true;
3595         mBoostStartTime = SystemClock.uptimeMillis();
3596         Message msg = mHandler.obtainMessage(APP_BOOST_DEACTIVATE_MSG);
3597         mHandler.sendMessageDelayed(msg, APP_BOOST_MESSAGE_DELAY);
3598
3599         // We don't have to do anything more if:
3600         // (1) There is an existing application record; and
3601         // (2) The caller doesn't think it is dead, OR there is no thread
3602         //     object attached to it so we know it couldn't have crashed; and
3603         // (3) There is a pid assigned to it, so it is either starting or
3604         //     already running.
3605         if (DEBUG_PROCESSES) Slog.v(TAG_PROCESSES, "startProcess: name=" + processName
3606                 + " app=" + app + " knownToBeDead=" + knownToBeDead
3607                 + " thread=" + (app != null ? app.thread : null)
3608                 + " pid=" + (app != null ? app.pid : -1));
3609         if (app != null && app.pid > 0) {
3610             if ((!knownToBeDead && !app.killed) || app.thread == null) {
3611                 // We already have the app running, or are waiting for it to
3612                 // come up (we have a pid but not yet its thread), so keep it.
3613                 if (DEBUG_PROCESSES) Slog.v(TAG_PROCESSES, "App already running: " + app);
3614                 // If this is a new package in the process, add the package to the list
3615                 app.addPackage(info.packageName, info.versionCode, mProcessStats);
3616                 checkTime(startTime, "startProcess: done, added package to proc");
3617                 return app;
3618             }
3619
3620             // An application record is attached to a previous process,
3621             // clean it up now.
3622             if (DEBUG_PROCESSES || DEBUG_CLEANUP) Slog.v(TAG_PROCESSES, "App died: " + app);
3623             checkTime(startTime, "startProcess: bad proc running, killing");
3624             killProcessGroup(app.uid, app.pid);
3625             handleAppDiedLocked(app, true, true);
3626             checkTime(startTime, "startProcess: done killing old proc");
3627         }
3628
3629         String hostingNameStr = hostingName != null
3630                 ? hostingName.flattenToShortString() : null;
3631
3632         if (app == null) {
3633             checkTime(startTime, "startProcess: creating new process record");
3634             app = newProcessRecordLocked(info, processName, isolated, isolatedUid);
3635             if (app == null) {
3636                 Slog.w(TAG, "Failed making new process record for "
3637                         + processName + "/" + info.uid + " isolated=" + isolated);
3638                 return null;
3639             }
3640             app.crashHandler = crashHandler;
3641             checkTime(startTime, "startProcess: done creating new process record");
3642         } else {
3643             // If this is a new package in the process, add the package to the list
3644             app.addPackage(info.packageName, info.versionCode, mProcessStats);
3645             checkTime(startTime, "startProcess: added package to existing proc");
3646         }
3647
3648         // If the system is not ready yet, then hold off on starting this
3649         // process until it is.
3650         if (!mProcessesReady
3651                 && !isAllowedWhileBooting(info)
3652                 && !allowWhileBooting) {
3653             if (!mProcessesOnHold.contains(app)) {
3654                 mProcessesOnHold.add(app);
3655             }
3656             if (DEBUG_PROCESSES) Slog.v(TAG_PROCESSES,
3657                     "System not ready, putting on hold: " + app);
3658             checkTime(startTime, "startProcess: returning with proc on hold");
3659             return app;
3660         }
3661
3662         checkTime(startTime, "startProcess: stepping in to startProcess");
3663         startProcessLocked(
3664                 app, hostingType, hostingNameStr, abiOverride, entryPoint, entryPointArgs);
3665         checkTime(startTime, "startProcess: done starting proc!");
3666         return (app.pid != 0) ? app : null;
3667     }
3668
3669     boolean isAllowedWhileBooting(ApplicationInfo ai) {
3670         return (ai.flags&ApplicationInfo.FLAG_PERSISTENT) != 0;
3671     }
3672
3673     private final void startProcessLocked(ProcessRecord app,
3674             String hostingType, String hostingNameStr) {
3675         startProcessLocked(app, hostingType, hostingNameStr, null /* abiOverride */,
3676                 null /* entryPoint */, null /* entryPointArgs */);
3677     }
3678
3679     private final void startProcessLocked(ProcessRecord app, String hostingType,
3680             String hostingNameStr, String abiOverride, String entryPoint, String[] entryPointArgs) {
3681         long startTime = SystemClock.elapsedRealtime();
3682         if (app.pid > 0 && app.pid != MY_PID) {
3683             checkTime(startTime, "startProcess: removing from pids map");
3684             synchronized (mPidsSelfLocked) {
3685                 mPidsSelfLocked.remove(app.pid);
3686                 mHandler.removeMessages(PROC_START_TIMEOUT_MSG, app);
3687             }
3688             checkTime(startTime, "startProcess: done removing from pids map");
3689             app.setPid(0);
3690         }
3691
3692         if (DEBUG_PROCESSES && mProcessesOnHold.contains(app)) Slog.v(TAG_PROCESSES,
3693                 "startProcessLocked removing on hold: " + app);
3694         mProcessesOnHold.remove(app);
3695
3696         checkTime(startTime, "startProcess: starting to update cpu stats");
3697         updateCpuStats();
3698         checkTime(startTime, "startProcess: done updating cpu stats");
3699
3700         try {
3701             try {
3702                 final int userId = UserHandle.getUserId(app.uid);
3703                 AppGlobals.getPackageManager().checkPackageStartable(app.info.packageName, userId);
3704             } catch (RemoteException e) {
3705                 throw e.rethrowAsRuntimeException();
3706             }
3707
3708             int uid = app.uid;
3709             int[] gids = null;
3710             int mountExternal = Zygote.MOUNT_EXTERNAL_NONE;
3711             if (!app.isolated) {
3712                 int[] permGids = null;
3713                 try {
3714                     checkTime(startTime, "startProcess: getting gids from package manager");
3715                     final IPackageManager pm = AppGlobals.getPackageManager();
3716                     permGids = pm.getPackageGids(app.info.packageName,
3717                             MATCH_DEBUG_TRIAGED_MISSING, app.userId);
3718                     MountServiceInternal mountServiceInternal = LocalServices.getService(
3719                             MountServiceInternal.class);
3720                     mountExternal = mountServiceInternal.getExternalStorageMountMode(uid,
3721                             app.info.packageName);
3722                 } catch (RemoteException e) {
3723                     throw e.rethrowAsRuntimeException();
3724                 }
3725
3726                 /*
3727                  * Add shared application and profile GIDs so applications can share some
3728                  * resources like shared libraries and access user-wide resources
3729                  */
3730                 if (ArrayUtils.isEmpty(permGids)) {
3731                     gids = new int[2];
3732                 } else {
3733                     gids = new int[permGids.length + 2];
3734                     System.arraycopy(permGids, 0, gids, 2, permGids.length);
3735                 }
3736                 gids[0] = UserHandle.getSharedAppGid(UserHandle.getAppId(uid));
3737                 gids[1] = UserHandle.getUserGid(UserHandle.getUserId(uid));
3738             }
3739             checkTime(startTime, "startProcess: building args");
3740             if (mFactoryTest != FactoryTest.FACTORY_TEST_OFF) {
3741                 if (mFactoryTest == FactoryTest.FACTORY_TEST_LOW_LEVEL
3742                         && mTopComponent != null
3743                         && app.processName.equals(mTopComponent.getPackageName())) {
3744                     uid = 0;
3745                 }
3746                 if (mFactoryTest == FactoryTest.FACTORY_TEST_HIGH_LEVEL
3747                         && (app.info.flags&ApplicationInfo.FLAG_FACTORY_TEST) != 0) {
3748                     uid = 0;
3749                 }
3750             }
3751             int debugFlags = 0;
3752             if ((app.info.flags & ApplicationInfo.FLAG_DEBUGGABLE) != 0) {
3753                 debugFlags |= Zygote.DEBUG_ENABLE_DEBUGGER;
3754                 // Also turn on CheckJNI for debuggable apps. It's quite
3755                 // awkward to turn on otherwise.
3756                 debugFlags |= Zygote.DEBUG_ENABLE_CHECKJNI;
3757             }
3758             // Run the app in safe mode if its manifest requests so or the
3759             // system is booted in safe mode.
3760             if ((app.info.flags & ApplicationInfo.FLAG_VM_SAFE_MODE) != 0 ||
3761                 mSafeMode == true) {
3762                 debugFlags |= Zygote.DEBUG_ENABLE_SAFEMODE;
3763             }
3764             if ("1".equals(SystemProperties.get("debug.checkjni"))) {
3765                 debugFlags |= Zygote.DEBUG_ENABLE_CHECKJNI;
3766             }
3767             String genDebugInfoProperty = SystemProperties.get("debug.generate-debug-info");
3768             if ("true".equals(genDebugInfoProperty)) {
3769                 debugFlags |= Zygote.DEBUG_GENERATE_DEBUG_INFO;
3770             }
3771             if ("1".equals(SystemProperties.get("debug.jni.logging"))) {
3772                 debugFlags |= Zygote.DEBUG_ENABLE_JNI_LOGGING;
3773             }
3774             if ("1".equals(SystemProperties.get("debug.assert"))) {
3775                 debugFlags |= Zygote.DEBUG_ENABLE_ASSERT;
3776             }
3777             if (mNativeDebuggingApp != null && mNativeDebuggingApp.equals(app.processName)) {
3778                 // Enable all debug flags required by the native debugger.
3779                 debugFlags |= Zygote.DEBUG_ALWAYS_JIT;          // Don't interpret anything
3780                 debugFlags |= Zygote.DEBUG_GENERATE_DEBUG_INFO; // Generate debug info
3781                 debugFlags |= Zygote.DEBUG_NATIVE_DEBUGGABLE;   // Disbale optimizations
3782                 mNativeDebuggingApp = null;
3783             }
3784
3785             String requiredAbi = (abiOverride != null) ? abiOverride : app.info.primaryCpuAbi;
3786             if (requiredAbi == null) {
3787                 requiredAbi = Build.SUPPORTED_ABIS[0];
3788             }
3789
3790             String instructionSet = null;
3791             if (app.info.primaryCpuAbi != null) {
3792                 instructionSet = VMRuntime.getInstructionSet(app.info.primaryCpuAbi);
3793             }
3794
3795             app.gids = gids;
3796             app.requiredAbi = requiredAbi;
3797             app.instructionSet = instructionSet;
3798
3799             // Start the process.  It will either succeed and return a result containing
3800             // the PID of the new process, or else throw a RuntimeException.
3801             boolean isActivityProcess = (entryPoint == null);
3802             if (entryPoint == null) entryPoint = "android.app.ActivityThread";
3803             Trace.traceBegin(Trace.TRACE_TAG_ACTIVITY_MANAGER, "Start proc: " +
3804                     app.processName);
3805             checkTime(startTime, "startProcess: asking zygote to start proc");
3806             Process.ProcessStartResult startResult = Process.start(entryPoint,
3807                     app.processName, uid, uid, gids, debugFlags, mountExternal,
3808                     app.info.targetSdkVersion, app.info.seinfo, requiredAbi, instructionSet,
3809                     app.info.dataDir, entryPointArgs);
3810             checkTime(startTime, "startProcess: returned from zygote!");
3811             Trace.traceEnd(Trace.TRACE_TAG_ACTIVITY_MANAGER);
3812
3813             mBatteryStatsService.noteProcessStart(app.processName, app.info.uid);
3814             checkTime(startTime, "startProcess: done updating battery stats");
3815
3816             EventLog.writeEvent(EventLogTags.AM_PROC_START,
3817                     UserHandle.getUserId(uid), startResult.pid, uid,
3818                     app.processName, hostingType,
3819                     hostingNameStr != null ? hostingNameStr : "");
3820
3821             try {
3822                 AppGlobals.getPackageManager().logAppProcessStartIfNeeded(app.processName, app.uid,
3823                         app.info.seinfo, app.info.sourceDir, startResult.pid);
3824             } catch (RemoteException ex) {
3825                 // Ignore
3826             }
3827
3828             if (app.persistent) {
3829                 Watchdog.getInstance().processStarted(app.processName, startResult.pid);
3830             }
3831
3832             checkTime(startTime, "startProcess: building log message");
3833             StringBuilder buf = mStringBuilder;
3834             buf.setLength(0);
3835             buf.append("Start proc ");
3836             buf.append(startResult.pid);
3837             buf.append(':');
3838             buf.append(app.processName);
3839             buf.append('/');
3840             UserHandle.formatUid(buf, uid);
3841             if (!isActivityProcess) {
3842                 buf.append(" [");
3843                 buf.append(entryPoint);
3844                 buf.append("]");
3845             }
3846             buf.append(" for ");
3847             buf.append(hostingType);
3848             if (hostingNameStr != null) {
3849                 buf.append(" ");
3850                 buf.append(hostingNameStr);
3851             }
3852             Slog.i(TAG, buf.toString());
3853             app.setPid(startResult.pid);
3854             app.usingWrapper = startResult.usingWrapper;
3855             app.removed = false;
3856             app.killed = false;
3857             app.killedByAm = false;
3858             checkTime(startTime, "startProcess: starting to update pids map");
3859             ProcessRecord oldApp;
3860             synchronized (mPidsSelfLocked) {
3861                 oldApp = mPidsSelfLocked.get(startResult.pid);
3862             }
3863             // If there is already an app occupying that pid that hasn't been cleaned up
3864             if (oldApp != null && !app.isolated) {
3865                 // Clean up anything relating to this pid first
3866                 Slog.w(TAG, "Reusing pid " + startResult.pid
3867                         + " while app is still mapped to it");
3868                 cleanUpApplicationRecordLocked(oldApp, false, false, -1,
3869                         true /*replacingPid*/);
3870             }
3871             synchronized (mPidsSelfLocked) {
3872                 this.mPidsSelfLocked.put(startResult.pid, app);
3873                 if (isActivityProcess) {
3874                     Message msg = mHandler.obtainMessage(PROC_START_TIMEOUT_MSG);
3875                     msg.obj = app;
3876                     mHandler.sendMessageDelayed(msg, startResult.usingWrapper
3877                             ? PROC_START_TIMEOUT_WITH_WRAPPER : PROC_START_TIMEOUT);
3878                 }
3879             }
3880             checkTime(startTime, "startProcess: done updating pids map");
3881         } catch (RuntimeException e) {
3882             Slog.e(TAG, "Failure starting process " + app.processName, e);
3883
3884             // Something went very wrong while trying to start this process; one
3885             // common case is when the package is frozen due to an active
3886             // upgrade. To recover, clean up any active bookkeeping related to
3887             // starting this process. (We already invoked this method once when
3888             // the package was initially frozen through KILL_APPLICATION_MSG, so
3889             // it doesn't hurt to use it again.)
3890             forceStopPackageLocked(app.info.packageName, UserHandle.getAppId(app.uid), false,
3891                     false, true, false, false, UserHandle.getUserId(app.userId), "start failure");
3892         }
3893     }
3894
3895     void updateUsageStats(ActivityRecord component, boolean resumed) {
3896         if (DEBUG_SWITCH) Slog.d(TAG_SWITCH,
3897                 "updateUsageStats: comp=" + component + "res=" + resumed);
3898         final BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
3899         if (resumed) {
3900             if (mUsageStatsService != null) {
3901                 mUsageStatsService.reportEvent(component.realActivity, component.userId,
3902                         UsageEvents.Event.MOVE_TO_FOREGROUND);
3903             }
3904             synchronized (stats) {
3905                 stats.noteActivityResumedLocked(component.app.uid);
3906             }
3907         } else {
3908             if (mUsageStatsService != null) {
3909                 mUsageStatsService.reportEvent(component.realActivity, component.userId,
3910                         UsageEvents.Event.MOVE_TO_BACKGROUND);
3911             }
3912             synchronized (stats) {
3913                 stats.noteActivityPausedLocked(component.app.uid);
3914             }
3915         }
3916     }
3917
3918     Intent getHomeIntent() {
3919         Intent intent = new Intent(mTopAction, mTopData != null ? Uri.parse(mTopData) : null);
3920         intent.setComponent(mTopComponent);
3921         intent.addFlags(Intent.FLAG_DEBUG_TRIAGED_MISSING);
3922         if (mFactoryTest != FactoryTest.FACTORY_TEST_LOW_LEVEL) {
3923             intent.addCategory(Intent.CATEGORY_HOME);
3924         }
3925         return intent;
3926     }
3927
3928     boolean startHomeActivityLocked(int userId, String reason) {
3929         if (mFactoryTest == FactoryTest.FACTORY_TEST_LOW_LEVEL
3930                 && mTopAction == null) {
3931             // We are running in factory test mode, but unable to find
3932             // the factory test app, so just sit around displaying the
3933             // error message and don't try to start anything.
3934             return false;
3935         }
3936         Intent intent = getHomeIntent();
3937         ActivityInfo aInfo = resolveActivityInfo(intent, STOCK_PM_FLAGS, userId);
3938         if (aInfo != null) {
3939             intent.setComponent(new ComponentName(aInfo.applicationInfo.packageName, aInfo.name));
3940             // Don't do this if the home app is currently being
3941             // instrumented.
3942             aInfo = new ActivityInfo(aInfo);
3943             aInfo.applicationInfo = getAppInfoForUser(aInfo.applicationInfo, userId);
3944             ProcessRecord app = getProcessRecordLocked(aInfo.processName,
3945                     aInfo.applicationInfo.uid, true);
3946             if (app == null || app.instrumentationClass == null) {
3947                 intent.setFlags(intent.getFlags() | Intent.FLAG_ACTIVITY_NEW_TASK);
3948                 mActivityStarter.startHomeActivityLocked(intent, aInfo, reason);
3949             }
3950         } else {
3951             Slog.wtf(TAG, "No home screen found for " + intent, new Throwable());
3952         }
3953
3954         return true;
3955     }
3956
3957     private ActivityInfo resolveActivityInfo(Intent intent, int flags, int userId) {
3958         ActivityInfo ai = null;
3959         ComponentName comp = intent.getComponent();
3960         try {
3961             if (comp != null) {
3962                 // Factory test.
3963                 ai = AppGlobals.getPackageManager().getActivityInfo(comp, flags, userId);
3964             } else {
3965                 ResolveInfo info = AppGlobals.getPackageManager().resolveIntent(
3966                         intent,
3967                         intent.resolveTypeIfNeeded(mContext.getContentResolver()),
3968                         flags, userId);
3969
3970                 if (info != null) {
3971                     ai = info.activityInfo;
3972                 }
3973             }
3974         } catch (RemoteException e) {
3975             // ignore
3976         }
3977
3978         return ai;
3979     }
3980
3981     /**
3982      * Starts the "new version setup screen" if appropriate.
3983      */
3984     void startSetupActivityLocked() {
3985         // Only do this once per boot.
3986         if (mCheckedForSetup) {
3987             return;
3988         }
3989
3990         // We will show this screen if the current one is a different
3991         // version than the last one shown, and we are not running in
3992         // low-level factory test mode.
3993         final ContentResolver resolver = mContext.getContentResolver();
3994         if (mFactoryTest != FactoryTest.FACTORY_TEST_LOW_LEVEL &&
3995                 Settings.Global.getInt(resolver,
3996                         Settings.Global.DEVICE_PROVISIONED, 0) != 0) {
3997             mCheckedForSetup = true;
3998
3999             // See if we should be showing the platform update setup UI.
4000             final Intent intent = new Intent(Intent.ACTION_UPGRADE_SETUP);
4001             final List<ResolveInfo> ris = mContext.getPackageManager().queryIntentActivities(intent,
4002                     PackageManager.MATCH_SYSTEM_ONLY | PackageManager.GET_META_DATA);
4003             if (!ris.isEmpty()) {
4004                 final ResolveInfo ri = ris.get(0);
4005                 String vers = ri.activityInfo.metaData != null
4006                         ? ri.activityInfo.metaData.getString(Intent.METADATA_SETUP_VERSION)
4007                         : null;
4008                 if (vers == null && ri.activityInfo.applicationInfo.metaData != null) {
4009                     vers = ri.activityInfo.applicationInfo.metaData.getString(
4010                             Intent.METADATA_SETUP_VERSION);
4011                 }
4012                 String lastVers = Settings.Secure.getString(
4013                         resolver, Settings.Secure.LAST_SETUP_SHOWN);
4014                 if (vers != null && !vers.equals(lastVers)) {
4015                     intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
4016                     intent.setComponent(new ComponentName(
4017                             ri.activityInfo.packageName, ri.activityInfo.name));
4018                     mActivityStarter.startActivityLocked(null, intent, null /*ephemeralIntent*/,
4019                             null, ri.activityInfo, null /*rInfo*/, null, null, null, null, 0, 0, 0,
4020                             null, 0, 0, 0, null, false, false, null, null, null);
4021                 }
4022             }
4023         }
4024     }
4025
4026     CompatibilityInfo compatibilityInfoForPackageLocked(ApplicationInfo ai) {
4027         return mCompatModePackages.compatibilityInfoForPackageLocked(ai);
4028     }
4029
4030     void enforceNotIsolatedCaller(String caller) {
4031         if (UserHandle.isIsolated(Binder.getCallingUid())) {
4032             throw new SecurityException("Isolated process not allowed to call " + caller);
4033         }
4034     }
4035
4036     void enforceShellRestriction(String restriction, int userHandle) {
4037         if (Binder.getCallingUid() == Process.SHELL_UID) {
4038             if (userHandle < 0 || mUserController.hasUserRestriction(restriction, userHandle)) {
4039                 throw new SecurityException("Shell does not have permission to access user "
4040                         + userHandle);
4041             }
4042         }
4043     }
4044
4045     @Override
4046     public int getFrontActivityScreenCompatMode() {
4047         enforceNotIsolatedCaller("getFrontActivityScreenCompatMode");
4048         synchronized (this) {
4049             return mCompatModePackages.getFrontActivityScreenCompatModeLocked();
4050         }
4051     }
4052
4053     @Override
4054     public void setFrontActivityScreenCompatMode(int mode) {
4055         enforceCallingPermission(android.Manifest.permission.SET_SCREEN_COMPATIBILITY,
4056                 "setFrontActivityScreenCompatMode");
4057         synchronized (this) {
4058             mCompatModePackages.setFrontActivityScreenCompatModeLocked(mode);
4059         }
4060     }
4061
4062     @Override
4063     public int getPackageScreenCompatMode(String packageName) {
4064         enforceNotIsolatedCaller("getPackageScreenCompatMode");
4065         synchronized (this) {
4066             return mCompatModePackages.getPackageScreenCompatModeLocked(packageName);
4067         }
4068     }
4069
4070     @Override
4071     public void setPackageScreenCompatMode(String packageName, int mode) {
4072         enforceCallingPermission(android.Manifest.permission.SET_SCREEN_COMPATIBILITY,
4073                 "setPackageScreenCompatMode");
4074         synchronized (this) {
4075             mCompatModePackages.setPackageScreenCompatModeLocked(packageName, mode);
4076         }
4077     }
4078
4079     @Override
4080     public boolean getPackageAskScreenCompat(String packageName) {
4081         enforceNotIsolatedCaller("getPackageAskScreenCompat");
4082         synchronized (this) {
4083             return mCompatModePackages.getPackageAskCompatModeLocked(packageName);
4084         }
4085     }
4086
4087     @Override
4088     public void setPackageAskScreenCompat(String packageName, boolean ask) {
4089         enforceCallingPermission(android.Manifest.permission.SET_SCREEN_COMPATIBILITY,
4090                 "setPackageAskScreenCompat");
4091         synchronized (this) {
4092             mCompatModePackages.setPackageAskCompatModeLocked(packageName, ask);
4093         }
4094     }
4095
4096     private boolean hasUsageStatsPermission(String callingPackage) {
4097         final int mode = mAppOpsService.checkOperation(AppOpsManager.OP_GET_USAGE_STATS,
4098                 Binder.getCallingUid(), callingPackage);
4099         if (mode == AppOpsManager.MODE_DEFAULT) {
4100             return checkCallingPermission(Manifest.permission.PACKAGE_USAGE_STATS)
4101                     == PackageManager.PERMISSION_GRANTED;
4102         }
4103         return mode == AppOpsManager.MODE_ALLOWED;
4104     }
4105
4106     @Override
4107     public int getPackageProcessState(String packageName, String callingPackage) {
4108         if (!hasUsageStatsPermission(callingPackage)) {
4109             enforceCallingPermission(android.Manifest.permission.GET_PACKAGE_IMPORTANCE,
4110                     "getPackageProcessState");
4111         }
4112
4113         int procState = ActivityManager.PROCESS_STATE_NONEXISTENT;
4114         synchronized (this) {
4115             for (int i=mLruProcesses.size()-1; i>=0; i--) {
4116                 final ProcessRecord proc = mLruProcesses.get(i);
4117                 if (procState == ActivityManager.PROCESS_STATE_NONEXISTENT
4118                         || procState > proc.setProcState) {
4119                     boolean found = false;
4120                     for (int j=proc.pkgList.size()-1; j>=0 && !found; j--) {
4121                         if (proc.pkgList.keyAt(j).equals(packageName)) {
4122                             procState = proc.setProcState;
4123                             found = true;
4124                         }
4125                     }
4126                     if (proc.pkgDeps != null && !found) {
4127                         for (int j=proc.pkgDeps.size()-1; j>=0; j--) {
4128                             if (proc.pkgDeps.valueAt(j).equals(packageName)) {
4129                                 procState = proc.setProcState;
4130                                 break;
4131                             }
4132                         }
4133                     }
4134                 }
4135             }
4136         }
4137         return procState;
4138     }
4139
4140     @Override
4141     public boolean setProcessMemoryTrimLevel(String process, int userId, int level) {
4142         synchronized (this) {
4143             final ProcessRecord app = findProcessLocked(process, userId, "setProcessMemoryTrimLevel");
4144             if (app == null) {
4145                 return false;
4146             }
4147             if (app.trimMemoryLevel < level && app.thread != null &&
4148                     (level < ComponentCallbacks2.TRIM_MEMORY_UI_HIDDEN ||
4149                             app.curProcState >= ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND)) {
4150                 try {
4151                     app.thread.scheduleTrimMemory(level);
4152                     app.trimMemoryLevel = level;
4153                     return true;
4154                 } catch (RemoteException e) {
4155                     // Fallthrough to failure case.
4156                 }
4157             }
4158         }
4159         return false;
4160     }
4161
4162     private void dispatchProcessesChanged() {
4163         int N;
4164         synchronized (this) {
4165             N = mPendingProcessChanges.size();
4166             if (mActiveProcessChanges.length < N) {
4167                 mActiveProcessChanges = new ProcessChangeItem[N];
4168             }
4169             mPendingProcessChanges.toArray(mActiveProcessChanges);
4170             mPendingProcessChanges.clear();
4171             if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG_PROCESS_OBSERVERS,
4172                     "*** Delivering " + N + " process changes");
4173         }
4174
4175         int i = mProcessObservers.beginBroadcast();
4176         while (i > 0) {
4177             i--;
4178             final IProcessObserver observer = mProcessObservers.getBroadcastItem(i);
4179             if (observer != null) {
4180                 try {
4181                     for (int j=0; j<N; j++) {
4182                         ProcessChangeItem item = mActiveProcessChanges[j];
4183                         if ((item.changes&ProcessChangeItem.CHANGE_ACTIVITIES) != 0) {
4184                             if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG_PROCESS_OBSERVERS,
4185                                     "ACTIVITIES CHANGED pid=" + item.pid + " uid="
4186                                     + item.uid + ": " + item.foregroundActivities);
4187                             observer.onForegroundActivitiesChanged(item.pid, item.uid,
4188                                     item.foregroundActivities);
4189                         }
4190                         if ((item.changes&ProcessChangeItem.CHANGE_PROCESS_STATE) != 0) {
4191                             if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG_PROCESS_OBSERVERS,
4192                                     "PROCSTATE CHANGED pid=" + item.pid + " uid=" + item.uid
4193                                     + ": " + item.processState);
4194                             observer.onProcessStateChanged(item.pid, item.uid, item.processState);
4195                         }
4196                     }
4197                 } catch (RemoteException e) {
4198                 }
4199             }
4200         }
4201         mProcessObservers.finishBroadcast();
4202
4203         synchronized (this) {
4204             for (int j=0; j<N; j++) {
4205                 mAvailProcessChanges.add(mActiveProcessChanges[j]);
4206             }
4207         }
4208     }
4209
4210     private void dispatchProcessDied(int pid, int uid) {
4211         int i = mProcessObservers.beginBroadcast();
4212         while (i > 0) {
4213             i--;
4214             final IProcessObserver observer = mProcessObservers.getBroadcastItem(i);
4215             if (observer != null) {
4216                 try {
4217                     observer.onProcessDied(pid, uid);
4218                 } catch (RemoteException e) {
4219                 }
4220             }
4221         }
4222         mProcessObservers.finishBroadcast();
4223     }
4224
4225     private void dispatchUidsChanged() {
4226         int N;
4227         synchronized (this) {
4228             N = mPendingUidChanges.size();
4229             if (mActiveUidChanges.length < N) {
4230                 mActiveUidChanges = new UidRecord.ChangeItem[N];
4231             }
4232             for (int i=0; i<N; i++) {
4233                 final UidRecord.ChangeItem change = mPendingUidChanges.get(i);
4234                 mActiveUidChanges[i] = change;
4235                 if (change.uidRecord != null) {
4236                     change.uidRecord.pendingChange = null;
4237                     change.uidRecord = null;
4238                 }
4239             }
4240             mPendingUidChanges.clear();
4241             if (DEBUG_UID_OBSERVERS) Slog.i(TAG_UID_OBSERVERS,
4242                     "*** Delivering " + N + " uid changes");
4243         }
4244
4245         if (mLocalPowerManager != null) {
4246             for (int j=0; j<N; j++) {
4247                 UidRecord.ChangeItem item = mActiveUidChanges[j];
4248                 if (item.change == UidRecord.CHANGE_GONE
4249                         || item.change == UidRecord.CHANGE_GONE_IDLE) {
4250                     mLocalPowerManager.uidGone(item.uid);
4251                 } else {
4252                     mLocalPowerManager.updateUidProcState(item.uid, item.processState);
4253                 }
4254             }
4255         }
4256
4257         int i = mUidObservers.beginBroadcast();
4258         while (i > 0) {
4259             i--;
4260             final IUidObserver observer = mUidObservers.getBroadcastItem(i);
4261             final int which = (Integer)mUidObservers.getBroadcastCookie(i);
4262             if (observer != null) {
4263                 try {
4264                     for (int j=0; j<N; j++) {
4265                         UidRecord.ChangeItem item = mActiveUidChanges[j];
4266                         final int change = item.change;
4267                         UidRecord validateUid = null;
4268                         if (VALIDATE_UID_STATES && i == 0) {
4269                             validateUid = mValidateUids.get(item.uid);
4270                             if (validateUid == null && change != UidRecord.CHANGE_GONE
4271                                     && change != UidRecord.CHANGE_GONE_IDLE) {
4272                                 validateUid = new UidRecord(item.uid);
4273                                 mValidateUids.put(item.uid, validateUid);
4274                             }
4275                         }
4276                         if (change == UidRecord.CHANGE_IDLE
4277                                 || change == UidRecord.CHANGE_GONE_IDLE) {
4278                             if ((which & ActivityManager.UID_OBSERVER_IDLE) != 0) {
4279                                 if (DEBUG_UID_OBSERVERS) Slog.i(TAG_UID_OBSERVERS,
4280                                         "UID idle uid=" + item.uid);
4281                                 observer.onUidIdle(item.uid);
4282                             }
4283                             if (VALIDATE_UID_STATES && i == 0) {
4284                                 if (validateUid != null) {
4285                                     validateUid.idle = true;
4286                                 }
4287                             }
4288                         } else if (change == UidRecord.CHANGE_ACTIVE) {
4289                             if ((which & ActivityManager.UID_OBSERVER_ACTIVE) != 0) {
4290                                 if (DEBUG_UID_OBSERVERS) Slog.i(TAG_UID_OBSERVERS,
4291                                         "UID active uid=" + item.uid);
4292                                 observer.onUidActive(item.uid);
4293                             }
4294                             if (VALIDATE_UID_STATES && i == 0) {
4295                                 validateUid.idle = false;
4296                             }
4297                         }
4298                         if (change == UidRecord.CHANGE_GONE
4299                                 || change == UidRecord.CHANGE_GONE_IDLE) {
4300                             if ((which & ActivityManager.UID_OBSERVER_GONE) != 0) {
4301                                 if (DEBUG_UID_OBSERVERS) Slog.i(TAG_UID_OBSERVERS,
4302                                         "UID gone uid=" + item.uid);
4303                                 observer.onUidGone(item.uid);
4304                             }
4305                             if (VALIDATE_UID_STATES && i == 0) {
4306                                 if (validateUid != null) {
4307                                     mValidateUids.remove(item.uid);
4308                                 }
4309                             }
4310                         } else {
4311                             if ((which & ActivityManager.UID_OBSERVER_PROCSTATE) != 0) {
4312                                 if (DEBUG_UID_OBSERVERS) Slog.i(TAG_UID_OBSERVERS,
4313                                         "UID CHANGED uid=" + item.uid
4314                                                 + ": " + item.processState);
4315                                 observer.onUidStateChanged(item.uid, item.processState);
4316                             }
4317                             if (VALIDATE_UID_STATES && i == 0) {
4318                                 validateUid.curProcState = validateUid.setProcState
4319                                         = item.processState;
4320                             }
4321                         }
4322                     }
4323                 } catch (RemoteException e) {
4324                 }
4325             }
4326         }
4327         mUidObservers.finishBroadcast();
4328
4329         synchronized (this) {
4330             for (int j=0; j<N; j++) {
4331                 mAvailUidChanges.add(mActiveUidChanges[j]);
4332             }
4333         }
4334     }
4335
4336     @Override
4337     public final int startActivity(IApplicationThread caller, String callingPackage,
4338             Intent intent, String resolvedType, IBinder resultTo, String resultWho, int requestCode,
4339             int startFlags, ProfilerInfo profilerInfo, Bundle bOptions) {
4340         return startActivityAsUser(caller, callingPackage, intent, resolvedType, resultTo,
4341                 resultWho, requestCode, startFlags, profilerInfo, bOptions,
4342                 UserHandle.getCallingUserId());
4343     }
4344
4345     final int startActivity(Intent intent, ActivityStackSupervisor.ActivityContainer container) {
4346         enforceNotIsolatedCaller("ActivityContainer.startActivity");
4347         final int userId = mUserController.handleIncomingUser(Binder.getCallingPid(),
4348                 Binder.getCallingUid(), mStackSupervisor.mCurrentUser, false,
4349                 ActivityManagerService.ALLOW_FULL_ONLY, "ActivityContainer", null);
4350
4351         // TODO: Switch to user app stacks here.
4352         String mimeType = intent.getType();
4353         final Uri data = intent.getData();
4354         if (mimeType == null && data != null && "content".equals(data.getScheme())) {
4355             mimeType = getProviderMimeType(data, userId);
4356         }
4357         container.checkEmbeddedAllowedInner(userId, intent, mimeType);
4358
4359         intent.addFlags(FORCE_NEW_TASK_FLAGS);
4360         return mActivityStarter.startActivityMayWait(null, -1, null, intent, mimeType, null, null, null,
4361                 null, 0, 0, null, null, null, null, false, userId, container, null);
4362     }
4363
4364     @Override
4365     public final int startActivityAsUser(IApplicationThread caller, String callingPackage,
4366             Intent intent, String resolvedType, IBinder resultTo, String resultWho, int requestCode,
4367             int startFlags, ProfilerInfo profilerInfo, Bundle bOptions, int userId) {
4368         enforceNotIsolatedCaller("startActivity");
4369         userId = mUserController.handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(),
4370                 userId, false, ALLOW_FULL_ONLY, "startActivity", null);
4371         // TODO: Switch to user app stacks here.
4372         return mActivityStarter.startActivityMayWait(caller, -1, callingPackage, intent,
4373                 resolvedType, null, null, resultTo, resultWho, requestCode, startFlags,
4374                 profilerInfo, null, null, bOptions, false, userId, null, null);
4375     }
4376
4377     @Override
4378     public final int startActivityAsCaller(IApplicationThread caller, String callingPackage,
4379             Intent intent, String resolvedType, IBinder resultTo, String resultWho, int requestCode,
4380             int startFlags, ProfilerInfo profilerInfo, Bundle bOptions, boolean ignoreTargetSecurity,
4381             int userId) {
4382
4383         // This is very dangerous -- it allows you to perform a start activity (including
4384         // permission grants) as any app that may launch one of your own activities.  So
4385         // we will only allow this to be done from activities that are part of the core framework,
4386         // and then only when they are running as the system.
4387         final ActivityRecord sourceRecord;
4388         final int targetUid;
4389         final String targetPackage;
4390         synchronized (this) {
4391             if (resultTo == null) {
4392                 throw new SecurityException("Must be called from an activity");
4393             }
4394             sourceRecord = mStackSupervisor.isInAnyStackLocked(resultTo);
4395             if (sourceRecord == null) {
4396                 throw new SecurityException("Called with bad activity token: " + resultTo);
4397             }
4398             if (!sourceRecord.info.packageName.equals("android")) {
4399                 throw new SecurityException(
4400                         "Must be called from an activity that is declared in the android package");
4401             }
4402             if (sourceRecord.app == null) {
4403                 throw new SecurityException("Called without a process attached to activity");
4404             }
4405             if (UserHandle.getAppId(sourceRecord.app.uid) != Process.SYSTEM_UID) {
4406                 // This is still okay, as long as this activity is running under the
4407                 // uid of the original calling activity.
4408                 if (sourceRecord.app.uid != sourceRecord.launchedFromUid) {
4409                     throw new SecurityException(
4410                             "Calling activity in uid " + sourceRecord.app.uid
4411                                     + " must be system uid or original calling uid "
4412                                     + sourceRecord.launchedFromUid);
4413                 }
4414             }
4415             if (ignoreTargetSecurity) {
4416                 if (intent.getComponent() == null) {
4417                     throw new SecurityException(
4418                             "Component must be specified with ignoreTargetSecurity");
4419                 }
4420                 if (intent.getSelector() != null) {
4421                     throw new SecurityException(
4422                             "Selector not allowed with ignoreTargetSecurity");
4423                 }
4424             }
4425             targetUid = sourceRecord.launchedFromUid;
4426             targetPackage = sourceRecord.launchedFromPackage;
4427         }
4428
4429         if (userId == UserHandle.USER_NULL) {
4430             userId = UserHandle.getUserId(sourceRecord.app.uid);
4431         }
4432
4433         // TODO: Switch to user app stacks here.
4434         try {
4435             int ret = mActivityStarter.startActivityMayWait(null, targetUid, targetPackage, intent,
4436                     resolvedType, null, null, resultTo, resultWho, requestCode, startFlags, null,
4437                     null, null, bOptions, ignoreTargetSecurity, userId, null, null);
4438             return ret;
4439         } catch (SecurityException e) {
4440             // XXX need to figure out how to propagate to original app.
4441             // A SecurityException here is generally actually a fault of the original
4442             // calling activity (such as a fairly granting permissions), so propagate it
4443             // back to them.
4444             /*
4445             StringBuilder msg = new StringBuilder();
4446             msg.append("While launching");
4447             msg.append(intent.toString());
4448             msg.append(": ");
4449             msg.append(e.getMessage());
4450             */
4451             throw e;
4452         }
4453     }
4454
4455     @Override
4456     public final WaitResult startActivityAndWait(IApplicationThread caller, String callingPackage,
4457             Intent intent, String resolvedType, IBinder resultTo, String resultWho, int requestCode,
4458             int startFlags, ProfilerInfo profilerInfo, Bundle bOptions, int userId) {
4459         enforceNotIsolatedCaller("startActivityAndWait");
4460         userId = mUserController.handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(),
4461                 userId, false, ALLOW_FULL_ONLY, "startActivityAndWait", null);
4462         WaitResult res = new WaitResult();
4463         // TODO: Switch to user app stacks here.
4464         mActivityStarter.startActivityMayWait(caller, -1, callingPackage, intent, resolvedType,
4465                 null, null, resultTo, resultWho, requestCode, startFlags, profilerInfo, res, null,
4466                 bOptions, false, userId, null, null);
4467         return res;
4468     }
4469
4470     @Override
4471     public final int startActivityWithConfig(IApplicationThread caller, String callingPackage,
4472             Intent intent, String resolvedType, IBinder resultTo, String resultWho, int requestCode,
4473             int startFlags, Configuration config, Bundle bOptions, int userId) {
4474         enforceNotIsolatedCaller("startActivityWithConfig");
4475         userId = mUserController.handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(),
4476                 userId, false, ALLOW_FULL_ONLY, "startActivityWithConfig", null);
4477         // TODO: Switch to user app stacks here.
4478         int ret = mActivityStarter.startActivityMayWait(caller, -1, callingPackage, intent,
4479                 resolvedType, null, null, resultTo, resultWho, requestCode, startFlags,
4480                 null, null, config, bOptions, false, userId, null, null);
4481         return ret;
4482     }
4483
4484     @Override
4485     public int startActivityIntentSender(IApplicationThread caller, IntentSender intent,
4486             Intent fillInIntent, String resolvedType, IBinder resultTo, String resultWho,
4487             int requestCode, int flagsMask, int flagsValues, Bundle bOptions)
4488             throws TransactionTooLargeException {
4489         enforceNotIsolatedCaller("startActivityIntentSender");
4490         // Refuse possible leaked file descriptors
4491         if (fillInIntent != null && fillInIntent.hasFileDescriptors()) {
4492             throw new IllegalArgumentException("File descriptors passed in Intent");
4493         }
4494
4495         IIntentSender sender = intent.getTarget();
4496         if (!(sender instanceof PendingIntentRecord)) {
4497             throw new IllegalArgumentException("Bad PendingIntent object");
4498         }
4499
4500         PendingIntentRecord pir = (PendingIntentRecord)sender;
4501
4502         synchronized (this) {
4503             // If this is coming from the currently resumed activity, it is
4504             // effectively saying that app switches are allowed at this point.
4505             final ActivityStack stack = getFocusedStack();
4506             if (stack.mResumedActivity != null &&
4507                     stack.mResumedActivity.info.applicationInfo.uid == Binder.getCallingUid()) {
4508                 mAppSwitchesAllowedTime = 0;
4509             }
4510         }
4511         int ret = pir.sendInner(0, fillInIntent, resolvedType, null, null,
4512                 resultTo, resultWho, requestCode, flagsMask, flagsValues, bOptions, null);
4513         return ret;
4514     }
4515
4516     @Override
4517     public int startVoiceActivity(String callingPackage, int callingPid, int callingUid,
4518             Intent intent, String resolvedType, IVoiceInteractionSession session,
4519             IVoiceInteractor interactor, int startFlags, ProfilerInfo profilerInfo,
4520             Bundle bOptions, int userId) {
4521         if (checkCallingPermission(Manifest.permission.BIND_VOICE_INTERACTION)
4522                 != PackageManager.PERMISSION_GRANTED) {
4523             String msg = "Permission Denial: startVoiceActivity() from pid="
4524                     + Binder.getCallingPid()
4525                     + ", uid=" + Binder.getCallingUid()
4526                     + " requires " + android.Manifest.permission.BIND_VOICE_INTERACTION;
4527             Slog.w(TAG, msg);
4528             throw new SecurityException(msg);
4529         }
4530         if (session == null || interactor == null) {
4531             throw new NullPointerException("null session or interactor");
4532         }
4533         userId = mUserController.handleIncomingUser(callingPid, callingUid, userId, false,
4534                 ALLOW_FULL_ONLY, "startVoiceActivity", null);
4535         // TODO: Switch to user app stacks here.
4536         return mActivityStarter.startActivityMayWait(null, callingUid, callingPackage, intent,
4537                 resolvedType, session, interactor, null, null, 0, startFlags, profilerInfo, null,
4538                 null, bOptions, false, userId, null, null);
4539     }
4540
4541     @Override
4542     public void startLocalVoiceInteraction(IBinder callingActivity, Bundle options)
4543             throws RemoteException {
4544         Slog.i(TAG, "Activity tried to startVoiceInteraction");
4545         synchronized (this) {
4546             ActivityRecord activity = getFocusedStack().topActivity();
4547             if (ActivityRecord.forTokenLocked(callingActivity) != activity) {
4548                 throw new SecurityException("Only focused activity can call startVoiceInteraction");
4549             }
4550             if (mRunningVoice != null || activity.task.voiceSession != null
4551                     || activity.voiceSession != null) {
4552                 Slog.w(TAG, "Already in a voice interaction, cannot start new voice interaction");
4553                 return;
4554             }
4555             if (activity.pendingVoiceInteractionStart) {
4556                 Slog.w(TAG, "Pending start of voice interaction already.");
4557                 return;
4558             }
4559             activity.pendingVoiceInteractionStart = true;
4560         }
4561         LocalServices.getService(VoiceInteractionManagerInternal.class)
4562                 .startLocalVoiceInteraction(callingActivity, options);
4563     }
4564
4565     @Override
4566     public void stopLocalVoiceInteraction(IBinder callingActivity) throws RemoteException {
4567         LocalServices.getService(VoiceInteractionManagerInternal.class)
4568                 .stopLocalVoiceInteraction(callingActivity);
4569     }
4570
4571     @Override
4572     public boolean supportsLocalVoiceInteraction() throws RemoteException {
4573         return LocalServices.getService(VoiceInteractionManagerInternal.class)
4574                 .supportsLocalVoiceInteraction();
4575     }
4576
4577     void onLocalVoiceInteractionStartedLocked(IBinder activity,
4578             IVoiceInteractionSession voiceSession, IVoiceInteractor voiceInteractor) {
4579         ActivityRecord activityToCallback = ActivityRecord.forTokenLocked(activity);
4580         if (activityToCallback == null) return;
4581         activityToCallback.setVoiceSessionLocked(voiceSession);
4582
4583         // Inform the activity
4584         try {
4585             activityToCallback.app.thread.scheduleLocalVoiceInteractionStarted(activity,
4586                     voiceInteractor);
4587             long token = Binder.clearCallingIdentity();
4588             try {
4589                 startRunningVoiceLocked(voiceSession, activityToCallback.appInfo.uid);
4590             } finally {
4591                 Binder.restoreCallingIdentity(token);
4592             }
4593             // TODO: VI Should we cache the activity so that it's easier to find later
4594             // rather than scan through all the stacks and activities?
4595         } catch (RemoteException re) {
4596             activityToCallback.clearVoiceSessionLocked();
4597             // TODO: VI Should this terminate the voice session?
4598         }
4599     }
4600
4601     @Override
4602     public void setVoiceKeepAwake(IVoiceInteractionSession session, boolean keepAwake) {
4603         synchronized (this) {
4604             if (mRunningVoice != null && mRunningVoice.asBinder() == session.asBinder()) {
4605                 if (keepAwake) {
4606                     mVoiceWakeLock.acquire();
4607                 } else {
4608                     mVoiceWakeLock.release();
4609                 }
4610             }
4611         }
4612     }
4613
4614     @Override
4615     public boolean startNextMatchingActivity(IBinder callingActivity,
4616             Intent intent, Bundle bOptions) {
4617         // Refuse possible leaked file descriptors
4618         if (intent != null && intent.hasFileDescriptors() == true) {
4619             throw new IllegalArgumentException("File descriptors passed in Intent");
4620         }
4621         ActivityOptions options = ActivityOptions.fromBundle(bOptions);
4622
4623         synchronized (this) {
4624             final ActivityRecord r = ActivityRecord.isInStackLocked(callingActivity);
4625             if (r == null) {
4626                 ActivityOptions.abort(options);
4627                 return false;
4628             }
4629             if (r.app == null || r.app.thread == null) {
4630                 // The caller is not running...  d'oh!
4631                 ActivityOptions.abort(options);
4632                 return false;
4633             }
4634             intent = new Intent(intent);
4635             // The caller is not allowed to change the data.
4636             intent.setDataAndType(r.intent.getData(), r.intent.getType());
4637             // And we are resetting to find the next component...
4638             intent.setComponent(null);
4639
4640             final boolean debug = ((intent.getFlags() & Intent.FLAG_DEBUG_LOG_RESOLUTION) != 0);
4641
4642             ActivityInfo aInfo = null;
4643             try {
4644                 List<ResolveInfo> resolves =
4645                     AppGlobals.getPackageManager().queryIntentActivities(
4646                             intent, r.resolvedType,
4647                             PackageManager.MATCH_DEFAULT_ONLY | STOCK_PM_FLAGS,
4648                             UserHandle.getCallingUserId()).getList();
4649
4650                 // Look for the original activity in the list...
4651                 final int N = resolves != null ? resolves.size() : 0;
4652                 for (int i=0; i<N; i++) {
4653                     ResolveInfo rInfo = resolves.get(i);
4654                     if (rInfo.activityInfo.packageName.equals(r.packageName)
4655                             && rInfo.activityInfo.name.equals(r.info.name)) {
4656                         // We found the current one...  the next matching is
4657                         // after it.
4658                         i++;
4659                         if (i<N) {
4660                             aInfo = resolves.get(i).activityInfo;
4661                         }
4662                         if (debug) {
4663                             Slog.v(TAG, "Next matching activity: found current " + r.packageName
4664                                     + "/" + r.info.name);
4665                             Slog.v(TAG, "Next matching activity: next is " + ((aInfo == null)
4666                                     ? "null" : aInfo.packageName + "/" + aInfo.name));
4667                         }
4668                         break;
4669                     }
4670                 }
4671             } catch (RemoteException e) {
4672             }
4673
4674             if (aInfo == null) {
4675                 // Nobody who is next!
4676                 ActivityOptions.abort(options);
4677                 if (debug) Slog.d(TAG, "Next matching activity: nothing found");
4678                 return false;
4679             }
4680
4681             intent.setComponent(new ComponentName(
4682                     aInfo.applicationInfo.packageName, aInfo.name));
4683             intent.setFlags(intent.getFlags()&~(
4684                     Intent.FLAG_ACTIVITY_FORWARD_RESULT|
4685                     Intent.FLAG_ACTIVITY_CLEAR_TOP|
4686                     Intent.FLAG_ACTIVITY_MULTIPLE_TASK|
4687                     Intent.FLAG_ACTIVITY_NEW_TASK));
4688
4689             // Okay now we need to start the new activity, replacing the
4690             // currently running activity.  This is a little tricky because
4691             // we want to start the new one as if the current one is finished,
4692             // but not finish the current one first so that there is no flicker.
4693             // And thus...
4694             final boolean wasFinishing = r.finishing;
4695             r.finishing = true;
4696
4697             // Propagate reply information over to the new activity.
4698             final ActivityRecord resultTo = r.resultTo;
4699             final String resultWho = r.resultWho;
4700             final int requestCode = r.requestCode;
4701             r.resultTo = null;
4702             if (resultTo != null) {
4703                 resultTo.removeResultsLocked(r, resultWho, requestCode);
4704             }
4705
4706             final long origId = Binder.clearCallingIdentity();
4707             int res = mActivityStarter.startActivityLocked(r.app.thread, intent,
4708                     null /*ephemeralIntent*/, r.resolvedType, aInfo, null /*rInfo*/, null,
4709                     null, resultTo != null ? resultTo.appToken : null, resultWho, requestCode, -1,
4710                     r.launchedFromUid, r.launchedFromPackage, -1, r.launchedFromUid, 0, options,
4711                     false, false, null, null, null);
4712             Binder.restoreCallingIdentity(origId);
4713
4714             r.finishing = wasFinishing;
4715             if (res != ActivityManager.START_SUCCESS) {
4716                 return false;
4717             }
4718             return true;
4719         }
4720     }
4721
4722     @Override
4723     public final int startActivityFromRecents(int taskId, Bundle bOptions) {
4724         if (checkCallingPermission(START_TASKS_FROM_RECENTS) != PackageManager.PERMISSION_GRANTED) {
4725             String msg = "Permission Denial: startActivityFromRecents called without " +
4726                     START_TASKS_FROM_RECENTS;
4727             Slog.w(TAG, msg);
4728             throw new SecurityException(msg);
4729         }
4730         final long origId = Binder.clearCallingIdentity();
4731         try {
4732             synchronized (this) {
4733                 return mStackSupervisor.startActivityFromRecentsInner(taskId, bOptions);
4734             }
4735         } finally {
4736             Binder.restoreCallingIdentity(origId);
4737         }
4738     }
4739
4740     final int startActivityInPackage(int uid, String callingPackage,
4741             Intent intent, String resolvedType, IBinder resultTo,
4742             String resultWho, int requestCode, int startFlags, Bundle bOptions, int userId,
4743             IActivityContainer container, TaskRecord inTask) {
4744
4745         userId = mUserController.handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(),
4746                 userId, false, ALLOW_FULL_ONLY, "startActivityInPackage", null);
4747
4748         // TODO: Switch to user app stacks here.
4749         int ret = mActivityStarter.startActivityMayWait(null, uid, callingPackage, intent,
4750                 resolvedType, null, null, resultTo, resultWho, requestCode, startFlags,
4751                 null, null, null, bOptions, false, userId, container, inTask);
4752         return ret;
4753     }
4754
4755     @Override
4756     public final int startActivities(IApplicationThread caller, String callingPackage,
4757             Intent[] intents, String[] resolvedTypes, IBinder resultTo, Bundle bOptions,
4758             int userId) {
4759         enforceNotIsolatedCaller("startActivities");
4760         userId = mUserController.handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(),
4761                 userId, false, ALLOW_FULL_ONLY, "startActivity", null);
4762         // TODO: Switch to user app stacks here.
4763         int ret = mActivityStarter.startActivities(caller, -1, callingPackage, intents,
4764                 resolvedTypes, resultTo, bOptions, userId);
4765         return ret;
4766     }
4767
4768     final int startActivitiesInPackage(int uid, String callingPackage,
4769             Intent[] intents, String[] resolvedTypes, IBinder resultTo,
4770             Bundle bOptions, int userId) {
4771
4772         userId = mUserController.handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(),
4773                 userId, false, ALLOW_FULL_ONLY, "startActivityInPackage", null);
4774         // TODO: Switch to user app stacks here.
4775         int ret = mActivityStarter.startActivities(null, uid, callingPackage, intents, resolvedTypes,
4776                 resultTo, bOptions, userId);
4777         return ret;
4778     }
4779
4780     @Override
4781     public void reportActivityFullyDrawn(IBinder token) {
4782         synchronized (this) {
4783             ActivityRecord r = ActivityRecord.isInStackLocked(token);
4784             if (r == null) {
4785                 return;
4786             }
4787             r.reportFullyDrawnLocked();
4788         }
4789     }
4790
4791     @Override
4792     public void setRequestedOrientation(IBinder token, int requestedOrientation) {
4793         synchronized (this) {
4794             ActivityRecord r = ActivityRecord.isInStackLocked(token);
4795             if (r == null) {
4796                 return;
4797             }
4798             TaskRecord task = r.task;
4799             if (task != null && (!task.mFullscreen || !task.stack.mFullscreen)) {
4800                 // Fixed screen orientation isn't supported when activities aren't in full screen
4801                 // mode.
4802                 return;
4803             }
4804             final long origId = Binder.clearCallingIdentity();
4805             mWindowManager.setAppOrientation(r.appToken, requestedOrientation);
4806             Configuration config = mWindowManager.updateOrientationFromAppTokens(
4807                     mConfiguration, r.mayFreezeScreenLocked(r.app) ? r.appToken : null);
4808             if (config != null) {
4809                 r.frozenBeforeDestroy = true;
4810                 if (!updateConfigurationLocked(config, r, false)) {
4811                     mStackSupervisor.resumeFocusedStackTopActivityLocked();
4812                 }
4813             }
4814             Binder.restoreCallingIdentity(origId);
4815         }
4816     }
4817
4818     @Override
4819     public int getRequestedOrientation(IBinder token) {
4820         synchronized (this) {
4821             ActivityRecord r = ActivityRecord.isInStackLocked(token);
4822             if (r == null) {
4823                 return ActivityInfo.SCREEN_ORIENTATION_UNSPECIFIED;
4824             }
4825             return mWindowManager.getAppOrientation(r.appToken);
4826         }
4827     }
4828
4829     /**
4830      * This is the internal entry point for handling Activity.finish().
4831      *
4832      * @param token The Binder token referencing the Activity we want to finish.
4833      * @param resultCode Result code, if any, from this Activity.
4834      * @param resultData Result data (Intent), if any, from this Activity.
4835      * @param finishTask Whether to finish the task associated with this Activity.
4836      *
4837      * @return Returns true if the activity successfully finished, or false if it is still running.
4838      */
4839     @Override
4840     public final boolean finishActivity(IBinder token, int resultCode, Intent resultData,
4841             int finishTask) {
4842         // Refuse possible leaked file descriptors
4843         if (resultData != null && resultData.hasFileDescriptors() == true) {
4844             throw new IllegalArgumentException("File descriptors passed in Intent");
4845         }
4846
4847         synchronized(this) {
4848             ActivityRecord r = ActivityRecord.isInStackLocked(token);
4849             if (r == null) {
4850                 return true;
4851             }
4852             // Keep track of the root activity of the task before we finish it
4853             TaskRecord tr = r.task;
4854             ActivityRecord rootR = tr.getRootActivity();
4855             if (rootR == null) {
4856                 Slog.w(TAG, "Finishing task with all activities already finished");
4857             }
4858             // Do not allow task to finish if last task in lockTask mode. Launchable priv-apps can
4859             // finish.
4860             if (tr.mLockTaskAuth != LOCK_TASK_AUTH_LAUNCHABLE_PRIV && rootR == r &&
4861                     mStackSupervisor.isLastLockedTask(tr)) {
4862                 Slog.i(TAG, "Not finishing task in lock task mode");
4863                 mStackSupervisor.showLockTaskToast();
4864                 return false;
4865             }
4866             if (mController != null) {
4867                 // Find the first activity that is not finishing.
4868                 ActivityRecord next = r.task.stack.topRunningActivityLocked(token, 0);
4869                 if (next != null) {
4870                     // ask watcher if this is allowed
4871                     boolean resumeOK = true;
4872                     try {
4873                         resumeOK = mController.activityResuming(next.packageName);
4874                     } catch (RemoteException e) {
4875                         mController = null;
4876                         Watchdog.getInstance().setActivityController(null);
4877                     }
4878
4879                     if (!resumeOK) {
4880                         Slog.i(TAG, "Not finishing activity because controller resumed");
4881                         return false;
4882                     }
4883                 }
4884             }
4885             final long origId = Binder.clearCallingIdentity();
4886             try {
4887                 boolean res;
4888                 final boolean finishWithRootActivity =
4889                         finishTask == Activity.FINISH_TASK_WITH_ROOT_ACTIVITY;
4890                 if (finishTask == Activity.FINISH_TASK_WITH_ACTIVITY
4891                         || (finishWithRootActivity && r == rootR)) {
4892                     // If requested, remove the task that is associated to this activity only if it
4893                     // was the root activity in the task. The result code and data is ignored
4894                     // because we don't support returning them across task boundaries. Also, to
4895                     // keep backwards compatibility we remove the task from recents when finishing
4896                     // task with root activity.
4897                     res = removeTaskByIdLocked(tr.taskId, false, finishWithRootActivity);
4898                     if (!res) {
4899                         Slog.i(TAG, "Removing task failed to finish activity");
4900                     }
4901                 } else {
4902                     res = tr.stack.requestFinishActivityLocked(token, resultCode,
4903                             resultData, "app-request", true);
4904                     if (!res) {
4905                         Slog.i(TAG, "Failed to finish by app-request");
4906                     }
4907                 }
4908                 return res;
4909             } finally {
4910                 Binder.restoreCallingIdentity(origId);
4911             }
4912         }
4913     }
4914
4915     @Override
4916     public final void finishHeavyWeightApp() {
4917         if (checkCallingPermission(android.Manifest.permission.FORCE_STOP_PACKAGES)
4918                 != PackageManager.PERMISSION_GRANTED) {
4919             String msg = "Permission Denial: finishHeavyWeightApp() from pid="
4920                     + Binder.getCallingPid()
4921                     + ", uid=" + Binder.getCallingUid()
4922                     + " requires " + android.Manifest.permission.FORCE_STOP_PACKAGES;
4923             Slog.w(TAG, msg);
4924             throw new SecurityException(msg);
4925         }
4926
4927         synchronized(this) {
4928             if (mHeavyWeightProcess == null) {
4929                 return;
4930             }
4931
4932             ArrayList<ActivityRecord> activities = new ArrayList<>(mHeavyWeightProcess.activities);
4933             for (int i = 0; i < activities.size(); i++) {
4934                 ActivityRecord r = activities.get(i);
4935                 if (!r.finishing && r.isInStackLocked()) {
4936                     r.task.stack.finishActivityLocked(r, Activity.RESULT_CANCELED,
4937                             null, "finish-heavy", true);
4938                 }
4939             }
4940
4941             mHandler.sendMessage(mHandler.obtainMessage(CANCEL_HEAVY_NOTIFICATION_MSG,
4942                     mHeavyWeightProcess.userId, 0));
4943             mHeavyWeightProcess = null;
4944         }
4945     }
4946
4947     @Override
4948     public void crashApplication(int uid, int initialPid, String packageName,
4949             String message) {
4950         if (checkCallingPermission(android.Manifest.permission.FORCE_STOP_PACKAGES)
4951                 != PackageManager.PERMISSION_GRANTED) {
4952             String msg = "Permission Denial: crashApplication() from pid="
4953                     + Binder.getCallingPid()
4954                     + ", uid=" + Binder.getCallingUid()
4955                     + " requires " + android.Manifest.permission.FORCE_STOP_PACKAGES;
4956             Slog.w(TAG, msg);
4957             throw new SecurityException(msg);
4958         }
4959
4960         synchronized(this) {
4961             mAppErrors.scheduleAppCrashLocked(uid, initialPid, packageName, message);
4962         }
4963     }
4964
4965     @Override
4966     public final void finishSubActivity(IBinder token, String resultWho,
4967             int requestCode) {
4968         synchronized(this) {
4969             final long origId = Binder.clearCallingIdentity();
4970             ActivityRecord r = ActivityRecord.isInStackLocked(token);
4971             if (r != null) {
4972                 r.task.stack.finishSubActivityLocked(r, resultWho, requestCode);
4973             }
4974             Binder.restoreCallingIdentity(origId);
4975         }
4976     }
4977
4978     @Override
4979     public boolean finishActivityAffinity(IBinder token) {
4980         synchronized(this) {
4981             final long origId = Binder.clearCallingIdentity();
4982             try {
4983                 ActivityRecord r = ActivityRecord.isInStackLocked(token);
4984                 if (r == null) {
4985                     return false;
4986                 }
4987
4988                 // Do not allow task to finish if last task in lockTask mode. Launchable priv-apps
4989                 // can finish.
4990                 final TaskRecord task = r.task;
4991                 if (task.mLockTaskAuth != LOCK_TASK_AUTH_LAUNCHABLE_PRIV &&
4992                         mStackSupervisor.isLastLockedTask(task) && task.getRootActivity() == r) {
4993                     mStackSupervisor.showLockTaskToast();
4994                     return false;
4995                 }
4996                 return task.stack.finishActivityAffinityLocked(r);
4997             } finally {
4998                 Binder.restoreCallingIdentity(origId);
4999             }
5000         }
5001     }
5002
5003     @Override
5004     public void finishVoiceTask(IVoiceInteractionSession session) {
5005         synchronized (this) {
5006             final long origId = Binder.clearCallingIdentity();
5007             try {
5008                 // TODO: VI Consider treating local voice interactions and voice tasks
5009                 // differently here
5010                 mStackSupervisor.finishVoiceTask(session);
5011             } finally {
5012                 Binder.restoreCallingIdentity(origId);
5013             }
5014         }
5015
5016     }
5017
5018     @Override
5019     public boolean releaseActivityInstance(IBinder token) {
5020         synchronized(this) {
5021             final long origId = Binder.clearCallingIdentity();
5022             try {
5023                 ActivityRecord r = ActivityRecord.isInStackLocked(token);
5024                 if (r == null) {
5025                     return false;
5026                 }
5027                 return r.task.stack.safelyDestroyActivityLocked(r, "app-req");
5028             } finally {
5029                 Binder.restoreCallingIdentity(origId);
5030             }
5031         }
5032     }
5033
5034     @Override
5035     public void releaseSomeActivities(IApplicationThread appInt) {
5036         synchronized(this) {
5037             final long origId = Binder.clearCallingIdentity();
5038             try {
5039                 ProcessRecord app = getRecordForAppLocked(appInt);
5040                 mStackSupervisor.releaseSomeActivitiesLocked(app, "low-mem");
5041             } finally {
5042                 Binder.restoreCallingIdentity(origId);
5043             }
5044         }
5045     }
5046
5047     @Override
5048     public boolean willActivityBeVisible(IBinder token) {
5049         synchronized(this) {
5050             ActivityStack stack = ActivityRecord.getStackLocked(token);
5051             if (stack != null) {
5052                 return stack.willActivityBeVisibleLocked(token);
5053             }
5054             return false;
5055         }
5056     }
5057
5058     @Override
5059     public void overridePendingTransition(IBinder token, String packageName,
5060             int enterAnim, int exitAnim) {
5061         synchronized(this) {
5062             ActivityRecord self = ActivityRecord.isInStackLocked(token);
5063             if (self == null) {
5064                 return;
5065             }
5066
5067             final long origId = Binder.clearCallingIdentity();
5068
5069             if (self.state == ActivityState.RESUMED
5070                     || self.state == ActivityState.PAUSING) {
5071                 mWindowManager.overridePendingAppTransition(packageName,
5072                         enterAnim, exitAnim, null);
5073             }
5074
5075             Binder.restoreCallingIdentity(origId);
5076         }
5077     }
5078
5079     /**
5080      * Main function for removing an existing process from the activity manager
5081      * as a result of that process going away.  Clears out all connections
5082      * to the process.
5083      */
5084     private final void handleAppDiedLocked(ProcessRecord app,
5085             boolean restarting, boolean allowRestart) {
5086         int pid = app.pid;
5087         boolean kept = cleanUpApplicationRecordLocked(app, restarting, allowRestart, -1,
5088                 false /*replacingPid*/);
5089         if (!kept && !restarting) {
5090             removeLruProcessLocked(app);
5091             if (pid > 0) {
5092                 ProcessList.remove(pid);
5093             }
5094         }
5095
5096         if (mProfileProc == app) {
5097             clearProfilerLocked();
5098         }
5099
5100         // Remove this application's activities from active lists.
5101         boolean hasVisibleActivities = mStackSupervisor.handleAppDiedLocked(app);
5102
5103         app.activities.clear();
5104
5105         if (app.instrumentationClass != null) {
5106             Slog.w(TAG, "Crash of app " + app.processName
5107                   + " running instrumentation " + app.instrumentationClass);
5108             Bundle info = new Bundle();
5109             info.putString("shortMsg", "Process crashed.");
5110             finishInstrumentationLocked(app, Activity.RESULT_CANCELED, info);
5111         }
5112
5113         if (!restarting && hasVisibleActivities
5114                 && !mStackSupervisor.resumeFocusedStackTopActivityLocked()) {
5115             // If there was nothing to resume, and we are not already restarting this process, but
5116             // there is a visible activity that is hosted by the process...  then make sure all
5117             // visible activities are running, taking care of restarting this process.
5118             mStackSupervisor.ensureActivitiesVisibleLocked(null, 0, !PRESERVE_WINDOWS);
5119         }
5120     }
5121
5122     private final int getLRURecordIndexForAppLocked(IApplicationThread thread) {
5123         IBinder threadBinder = thread.asBinder();
5124         // Find the application record.
5125         for (int i=mLruProcesses.size()-1; i>=0; i--) {
5126             ProcessRecord rec = mLruProcesses.get(i);
5127             if (rec.thread != null && rec.thread.asBinder() == threadBinder) {
5128                 return i;
5129             }
5130         }
5131         return -1;
5132     }
5133
5134     final ProcessRecord getRecordForAppLocked(
5135             IApplicationThread thread) {
5136         if (thread == null) {
5137             return null;
5138         }
5139
5140         int appIndex = getLRURecordIndexForAppLocked(thread);
5141         return appIndex >= 0 ? mLruProcesses.get(appIndex) : null;
5142     }
5143
5144     final void doLowMemReportIfNeededLocked(ProcessRecord dyingProc) {
5145         // If there are no longer any background processes running,
5146         // and the app that died was not running instrumentation,
5147         // then tell everyone we are now low on memory.
5148         boolean haveBg = false;
5149         for (int i=mLruProcesses.size()-1; i>=0; i--) {
5150             ProcessRecord rec = mLruProcesses.get(i);
5151             if (rec.thread != null
5152                     && rec.setProcState >= ActivityManager.PROCESS_STATE_CACHED_ACTIVITY) {
5153                 haveBg = true;
5154                 break;
5155             }
5156         }
5157
5158         if (!haveBg) {
5159             boolean doReport = "1".equals(SystemProperties.get(SYSTEM_DEBUGGABLE, "0"));
5160             if (doReport) {
5161                 long now = SystemClock.uptimeMillis();
5162                 if (now < (mLastMemUsageReportTime+5*60*1000)) {
5163                     doReport = false;
5164                 } else {
5165                     mLastMemUsageReportTime = now;
5166                 }
5167             }
5168             final ArrayList<ProcessMemInfo> memInfos
5169                     = doReport ? new ArrayList<ProcessMemInfo>(mLruProcesses.size()) : null;
5170             EventLog.writeEvent(EventLogTags.AM_LOW_MEMORY, mLruProcesses.size());
5171             long now = SystemClock.uptimeMillis();
5172             for (int i=mLruProcesses.size()-1; i>=0; i--) {
5173                 ProcessRecord rec = mLruProcesses.get(i);
5174                 if (rec == dyingProc || rec.thread == null) {
5175                     continue;
5176                 }
5177                 if (doReport) {
5178                     memInfos.add(new ProcessMemInfo(rec.processName, rec.pid, rec.setAdj,
5179                             rec.setProcState, rec.adjType, rec.makeAdjReason()));
5180                 }
5181                 if ((rec.lastLowMemory+GC_MIN_INTERVAL) <= now) {
5182                     // The low memory report is overriding any current
5183                     // state for a GC request.  Make sure to do
5184                     // heavy/important/visible/foreground processes first.
5185                     if (rec.setAdj <= ProcessList.HEAVY_WEIGHT_APP_ADJ) {
5186                         rec.lastRequestedGc = 0;
5187                     } else {
5188                         rec.lastRequestedGc = rec.lastLowMemory;
5189                     }
5190                     rec.reportLowMemory = true;
5191                     rec.lastLowMemory = now;
5192                     mProcessesToGc.remove(rec);
5193                     addProcessToGcListLocked(rec);
5194                 }
5195             }
5196             if (doReport) {
5197                 Message msg = mHandler.obtainMessage(REPORT_MEM_USAGE_MSG, memInfos);
5198                 mHandler.sendMessage(msg);
5199             }
5200             scheduleAppGcsLocked();
5201         }
5202     }
5203
5204     final void appDiedLocked(ProcessRecord app) {
5205        appDiedLocked(app, app.pid, app.thread, false);
5206     }
5207
5208     final void appDiedLocked(ProcessRecord app, int pid, IApplicationThread thread,
5209             boolean fromBinderDied) {
5210         // First check if this ProcessRecord is actually active for the pid.
5211         synchronized (mPidsSelfLocked) {
5212             ProcessRecord curProc = mPidsSelfLocked.get(pid);
5213             if (curProc != app) {
5214                 Slog.w(TAG, "Spurious death for " + app + ", curProc for " + pid + ": " + curProc);
5215                 return;
5216             }
5217         }
5218
5219         BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
5220         synchronized (stats) {
5221             stats.noteProcessDiedLocked(app.info.uid, pid);
5222         }
5223
5224         if (!app.killed) {
5225             if (!fromBinderDied) {
5226                 Process.killProcessQuiet(pid);
5227             }
5228             killProcessGroup(app.uid, pid);
5229             app.killed = true;
5230         }
5231
5232         // Clean up already done if the process has been re-started.
5233         if (app.pid == pid && app.thread != null &&
5234                 app.thread.asBinder() == thread.asBinder()) {
5235             boolean doLowMem = app.instrumentationClass == null;
5236             boolean doOomAdj = doLowMem;
5237             if (!app.killedByAm) {
5238                 Slog.i(TAG, "Process " + app.processName + " (pid " + pid
5239                         + ") has died");
5240                 mAllowLowerMemLevel = true;
5241             } else {
5242                 // Note that we always want to do oom adj to update our state with the
5243                 // new number of procs.
5244                 mAllowLowerMemLevel = false;
5245                 doLowMem = false;
5246             }
5247             EventLog.writeEvent(EventLogTags.AM_PROC_DIED, app.userId, app.pid, app.processName);
5248             if (DEBUG_CLEANUP) Slog.v(TAG_CLEANUP,
5249                 "Dying app: " + app + ", pid: " + pid + ", thread: " + thread.asBinder());
5250             handleAppDiedLocked(app, false, true);
5251
5252             if (doOomAdj) {
5253                 updateOomAdjLocked();
5254             }
5255             if (doLowMem) {
5256                 doLowMemReportIfNeededLocked(app);
5257             }
5258         } else if (app.pid != pid) {
5259             // A new process has already been started.
5260             Slog.i(TAG, "Process " + app.processName + " (pid " + pid
5261                     + ") has died and restarted (pid " + app.pid + ").");
5262             EventLog.writeEvent(EventLogTags.AM_PROC_DIED, app.userId, app.pid, app.processName);
5263         } else if (DEBUG_PROCESSES) {
5264             Slog.d(TAG_PROCESSES, "Received spurious death notification for thread "
5265                     + thread.asBinder());
5266         }
5267     }
5268
5269     /**
5270      * If a stack trace dump file is configured, dump process stack traces.
5271      * @param clearTraces causes the dump file to be erased prior to the new
5272      *    traces being written, if true; when false, the new traces will be
5273      *    appended to any existing file content.
5274      * @param firstPids of dalvik VM processes to dump stack traces for first
5275      * @param lastPids of dalvik VM processes to dump stack traces for last
5276      * @param nativeProcs optional list of native process names to dump stack crawls
5277      * @return file containing stack traces, or null if no dump file is configured
5278      */
5279     public static File dumpStackTraces(boolean clearTraces, ArrayList<Integer> firstPids,
5280             ProcessCpuTracker processCpuTracker, SparseArray<Boolean> lastPids, String[] nativeProcs) {
5281         String tracesPath = SystemProperties.get("dalvik.vm.stack-trace-file", null);
5282         if (tracesPath == null || tracesPath.length() == 0) {
5283             return null;
5284         }
5285
5286         File tracesFile = new File(tracesPath);
5287         try {
5288             if (clearTraces && tracesFile.exists()) tracesFile.delete();
5289             tracesFile.createNewFile();
5290             FileUtils.setPermissions(tracesFile.getPath(), 0666, -1, -1); // -rw-rw-rw-
5291         } catch (IOException e) {
5292             Slog.w(TAG, "Unable to prepare ANR traces file: " + tracesPath, e);
5293             return null;
5294         }
5295
5296         dumpStackTraces(tracesPath, firstPids, processCpuTracker, lastPids, nativeProcs);
5297         return tracesFile;
5298     }
5299
5300     private static void dumpStackTraces(String tracesPath, ArrayList<Integer> firstPids,
5301             ProcessCpuTracker processCpuTracker, SparseArray<Boolean> lastPids, String[] nativeProcs) {
5302         // Use a FileObserver to detect when traces finish writing.
5303         // The order of traces is considered important to maintain for legibility.
5304         FileObserver observer = new FileObserver(tracesPath, FileObserver.CLOSE_WRITE) {
5305             @Override
5306             public synchronized void onEvent(int event, String path) { notify(); }
5307         };
5308
5309         try {
5310             observer.startWatching();
5311
5312             // First collect all of the stacks of the most important pids.
5313             if (firstPids != null) {
5314                 try {
5315                     int num = firstPids.size();
5316                     for (int i = 0; i < num; i++) {
5317                         synchronized (observer) {
5318                             if (DEBUG_ANR) Slog.d(TAG, "Collecting stacks for pid "
5319                                     + firstPids.get(i));
5320                             final long sime = SystemClock.elapsedRealtime();
5321                             Process.sendSignal(firstPids.get(i), Process.SIGNAL_QUIT);
5322                             observer.wait(1000);  // Wait for write-close, give up after 1 sec
5323                             if (DEBUG_ANR) Slog.d(TAG, "Done with pid " + firstPids.get(i)
5324                                     + " in " + (SystemClock.elapsedRealtime()-sime) + "ms");
5325                         }
5326                     }
5327                 } catch (InterruptedException e) {
5328                     Slog.wtf(TAG, e);
5329                 }
5330             }
5331
5332             // Next collect the stacks of the native pids
5333             if (nativeProcs != null) {
5334                 int[] pids = Process.getPidsForCommands(nativeProcs);
5335                 if (pids != null) {
5336                     for (int pid : pids) {
5337                         if (DEBUG_ANR) Slog.d(TAG, "Collecting stacks for native pid " + pid);
5338                         final long sime = SystemClock.elapsedRealtime();
5339                         Debug.dumpNativeBacktraceToFile(pid, tracesPath);
5340                         if (DEBUG_ANR) Slog.d(TAG, "Done with native pid " + pid
5341                                 + " in " + (SystemClock.elapsedRealtime()-sime) + "ms");
5342                     }
5343                 }
5344             }
5345
5346             // Lastly, measure CPU usage.
5347             if (processCpuTracker != null) {
5348                 processCpuTracker.init();
5349                 System.gc();
5350                 processCpuTracker.update();
5351                 try {
5352                     synchronized (processCpuTracker) {
5353                         processCpuTracker.wait(500); // measure over 1/2 second.
5354                     }
5355                 } catch (InterruptedException e) {
5356                 }
5357                 processCpuTracker.update();
5358
5359                 // We'll take the stack crawls of just the top apps using CPU.
5360                 final int N = processCpuTracker.countWorkingStats();
5361                 int numProcs = 0;
5362                 for (int i=0; i<N && numProcs<5; i++) {
5363                     ProcessCpuTracker.Stats stats = processCpuTracker.getWorkingStats(i);
5364                     if (lastPids.indexOfKey(stats.pid) >= 0) {
5365                         numProcs++;
5366                         try {
5367                             synchronized (observer) {
5368                                 if (DEBUG_ANR) Slog.d(TAG, "Collecting stacks for extra pid "
5369                                         + stats.pid);
5370                                 final long stime = SystemClock.elapsedRealtime();
5371                                 Process.sendSignal(stats.pid, Process.SIGNAL_QUIT);
5372                                 observer.wait(1000);  // Wait for write-close, give up after 1 sec
5373                                 if (DEBUG_ANR) Slog.d(TAG, "Done with extra pid " + stats.pid
5374                                         + " in " + (SystemClock.elapsedRealtime()-stime) + "ms");
5375                             }
5376                         } catch (InterruptedException e) {
5377                             Slog.wtf(TAG, e);
5378                         }
5379                     } else if (DEBUG_ANR) {
5380                         Slog.d(TAG, "Skipping next CPU consuming process, not a java proc: "
5381                                 + stats.pid);
5382                     }
5383                 }
5384             }
5385         } finally {
5386             observer.stopWatching();
5387         }
5388     }
5389
5390     final void logAppTooSlow(ProcessRecord app, long startTime, String msg) {
5391         if (true || IS_USER_BUILD) {
5392             return;
5393         }
5394         String tracesPath = SystemProperties.get("dalvik.vm.stack-trace-file", null);
5395         if (tracesPath == null || tracesPath.length() == 0) {
5396             return;
5397         }
5398
5399         StrictMode.ThreadPolicy oldPolicy = StrictMode.allowThreadDiskReads();
5400         StrictMode.allowThreadDiskWrites();
5401         try {
5402             final File tracesFile = new File(tracesPath);
5403             final File tracesDir = tracesFile.getParentFile();
5404             final File tracesTmp = new File(tracesDir, "__tmp__");
5405             try {
5406                 if (tracesFile.exists()) {
5407                     tracesTmp.delete();
5408                     tracesFile.renameTo(tracesTmp);
5409                 }
5410                 StringBuilder sb = new StringBuilder();
5411                 Time tobj = new Time();
5412                 tobj.set(System.currentTimeMillis());
5413                 sb.append(tobj.format("%Y-%m-%d %H:%M:%S"));
5414                 sb.append(": ");
5415                 TimeUtils.formatDuration(SystemClock.uptimeMillis()-startTime, sb);
5416                 sb.append(" since ");
5417                 sb.append(msg);
5418                 FileOutputStream fos = new FileOutputStream(tracesFile);
5419                 fos.write(sb.toString().getBytes());
5420                 if (app == null) {
5421                     fos.write("\n*** No application process!".getBytes());
5422                 }
5423                 fos.close();
5424                 FileUtils.setPermissions(tracesFile.getPath(), 0666, -1, -1); // -rw-rw-rw-
5425             } catch (IOException e) {
5426                 Slog.w(TAG, "Unable to prepare slow app traces file: " + tracesPath, e);
5427                 return;
5428             }
5429
5430             if (app != null) {
5431                 ArrayList<Integer> firstPids = new ArrayList<Integer>();
5432                 firstPids.add(app.pid);
5433                 dumpStackTraces(tracesPath, firstPids, null, null, null);
5434             }
5435
5436             File lastTracesFile = null;
5437             File curTracesFile = null;
5438             for (int i=9; i>=0; i--) {
5439                 String name = String.format(Locale.US, "slow%02d.txt", i);
5440                 curTracesFile = new File(tracesDir, name);
5441                 if (curTracesFile.exists()) {
5442                     if (lastTracesFile != null) {
5443                         curTracesFile.renameTo(lastTracesFile);
5444                     } else {
5445                         curTracesFile.delete();
5446                     }
5447                 }
5448                 lastTracesFile = curTracesFile;
5449             }
5450             tracesFile.renameTo(curTracesFile);
5451             if (tracesTmp.exists()) {
5452                 tracesTmp.renameTo(tracesFile);
5453             }
5454         } finally {
5455             StrictMode.setThreadPolicy(oldPolicy);
5456         }
5457     }
5458
5459     final void showLaunchWarningLocked(final ActivityRecord cur, final ActivityRecord next) {
5460         if (!mLaunchWarningShown) {
5461             mLaunchWarningShown = true;
5462             mUiHandler.post(new Runnable() {
5463                 @Override
5464                 public void run() {
5465                     synchronized (ActivityManagerService.this) {
5466                         final Dialog d = new LaunchWarningWindow(mContext, cur, next);
5467                         d.show();
5468                         mUiHandler.postDelayed(new Runnable() {
5469                             @Override
5470                             public void run() {
5471                                 synchronized (ActivityManagerService.this) {
5472                                     d.dismiss();
5473                                     mLaunchWarningShown = false;
5474                                 }
5475                             }
5476                         }, 4000);
5477                     }
5478                 }
5479             });
5480         }
5481     }
5482
5483     @Override
5484     public boolean clearApplicationUserData(final String packageName,
5485             final IPackageDataObserver observer, int userId) {
5486         enforceNotIsolatedCaller("clearApplicationUserData");
5487         int uid = Binder.getCallingUid();
5488         int pid = Binder.getCallingPid();
5489         userId = mUserController.handleIncomingUser(pid, uid, userId, false,
5490                 ALLOW_FULL_ONLY, "clearApplicationUserData", null);
5491
5492
5493         long callingId = Binder.clearCallingIdentity();
5494         try {
5495             IPackageManager pm = AppGlobals.getPackageManager();
5496             int pkgUid = -1;
5497             synchronized(this) {
5498                 if (getPackageManagerInternalLocked().isPackageDataProtected(
5499                         userId, packageName)) {
5500                     throw new SecurityException(
5501                             "Cannot clear data for a protected package: " + packageName);
5502                 }
5503
5504                 try {
5505                     pkgUid = pm.getPackageUid(packageName, MATCH_UNINSTALLED_PACKAGES, userId);
5506                 } catch (RemoteException e) {
5507                 }
5508                 if (pkgUid == -1) {
5509                     Slog.w(TAG, "Invalid packageName: " + packageName);
5510                     if (observer != null) {
5511                         try {
5512                             observer.onRemoveCompleted(packageName, false);
5513                         } catch (RemoteException e) {
5514                             Slog.i(TAG, "Observer no longer exists.");
5515                         }
5516                     }
5517                     return false;
5518                 }
5519                 if (uid == pkgUid || checkComponentPermission(
5520                         android.Manifest.permission.CLEAR_APP_USER_DATA,
5521                         pid, uid, -1, true)
5522                         == PackageManager.PERMISSION_GRANTED) {
5523                     forceStopPackageLocked(packageName, pkgUid, "clear data");
5524                 } else {
5525                     throw new SecurityException("PID " + pid + " does not have permission "
5526                             + android.Manifest.permission.CLEAR_APP_USER_DATA + " to clear data"
5527                                     + " of package " + packageName);
5528                 }
5529
5530                 // Remove all tasks match the cleared application package and user
5531                 for (int i = mRecentTasks.size() - 1; i >= 0; i--) {
5532                     final TaskRecord tr = mRecentTasks.get(i);
5533                     final String taskPackageName =
5534                             tr.getBaseIntent().getComponent().getPackageName();
5535                     if (tr.userId != userId) continue;
5536                     if (!taskPackageName.equals(packageName)) continue;
5537                     removeTaskByIdLocked(tr.taskId, false, REMOVE_FROM_RECENTS);
5538                 }
5539             }
5540
5541             final int pkgUidF = pkgUid;
5542             final int userIdF = userId;
5543             final IPackageDataObserver localObserver = new IPackageDataObserver.Stub() {
5544                 @Override
5545                 public void onRemoveCompleted(String packageName, boolean succeeded)
5546                         throws RemoteException {
5547                     synchronized (ActivityManagerService.this) {
5548                         finishForceStopPackageLocked(packageName, pkgUidF);
5549                     }
5550
5551                     final Intent intent = new Intent(Intent.ACTION_PACKAGE_DATA_CLEARED,
5552                             Uri.fromParts("package", packageName, null));
5553                     intent.putExtra(Intent.EXTRA_UID, pkgUidF);
5554                     intent.putExtra(Intent.EXTRA_USER_HANDLE, UserHandle.getUserId(pkgUidF));
5555                     broadcastIntentInPackage("android", Process.SYSTEM_UID, intent,
5556                             null, null, 0, null, null, null, null, false, false, userIdF);
5557
5558                     if (observer != null) {
5559                         observer.onRemoveCompleted(packageName, succeeded);
5560                     }
5561                 }
5562             };
5563
5564             try {
5565                 // Clear application user data
5566                 pm.clearApplicationUserData(packageName, localObserver, userId);
5567
5568                 synchronized(this) {
5569                     // Remove all permissions granted from/to this package
5570                     removeUriPermissionsForPackageLocked(packageName, userId, true);
5571                 }
5572
5573                 // Remove all zen rules created by this package; revoke it's zen access.
5574                 INotificationManager inm = NotificationManager.getService();
5575                 inm.removeAutomaticZenRules(packageName);
5576                 inm.setNotificationPolicyAccessGranted(packageName, false);
5577
5578             } catch (RemoteException e) {
5579             }
5580         } finally {
5581             Binder.restoreCallingIdentity(callingId);
5582         }
5583         return true;
5584     }
5585
5586     @Override
5587     public void killBackgroundProcesses(final String packageName, int userId) {
5588         if (checkCallingPermission(android.Manifest.permission.KILL_BACKGROUND_PROCESSES)
5589                 != PackageManager.PERMISSION_GRANTED &&
5590                 checkCallingPermission(android.Manifest.permission.RESTART_PACKAGES)
5591                         != PackageManager.PERMISSION_GRANTED) {
5592             String msg = "Permission Denial: killBackgroundProcesses() from pid="
5593                     + Binder.getCallingPid()
5594                     + ", uid=" + Binder.getCallingUid()
5595                     + " requires " + android.Manifest.permission.KILL_BACKGROUND_PROCESSES;
5596             Slog.w(TAG, msg);
5597             throw new SecurityException(msg);
5598         }
5599
5600         userId = mUserController.handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(),
5601                 userId, true, ALLOW_FULL_ONLY, "killBackgroundProcesses", null);
5602         long callingId = Binder.clearCallingIdentity();
5603         try {
5604             IPackageManager pm = AppGlobals.getPackageManager();
5605             synchronized(this) {
5606                 int appId = -1;
5607                 try {
5608                     appId = UserHandle.getAppId(
5609                             pm.getPackageUid(packageName, MATCH_DEBUG_TRIAGED_MISSING, userId));
5610                 } catch (RemoteException e) {
5611                 }
5612                 if (appId == -1) {
5613                     Slog.w(TAG, "Invalid packageName: " + packageName);
5614                     return;
5615                 }
5616                 killPackageProcessesLocked(packageName, appId, userId,
5617                         ProcessList.SERVICE_ADJ, false, true, true, false, "kill background");
5618             }
5619         } finally {
5620             Binder.restoreCallingIdentity(callingId);
5621         }
5622     }
5623
5624     @Override
5625     public void killAllBackgroundProcesses() {
5626         if (checkCallingPermission(android.Manifest.permission.KILL_BACKGROUND_PROCESSES)
5627                 != PackageManager.PERMISSION_GRANTED) {
5628             final String msg = "Permission Denial: killAllBackgroundProcesses() from pid="
5629                     + Binder.getCallingPid() + ", uid=" + Binder.getCallingUid()
5630                     + " requires " + android.Manifest.permission.KILL_BACKGROUND_PROCESSES;
5631             Slog.w(TAG, msg);
5632             throw new SecurityException(msg);
5633         }
5634
5635         final long callingId = Binder.clearCallingIdentity();
5636         try {
5637             synchronized (this) {
5638                 final ArrayList<ProcessRecord> procs = new ArrayList<>();
5639                 final int NP = mProcessNames.getMap().size();
5640                 for (int ip = 0; ip < NP; ip++) {
5641                     final SparseArray<ProcessRecord> apps = mProcessNames.getMap().valueAt(ip);
5642                     final int NA = apps.size();
5643                     for (int ia = 0; ia < NA; ia++) {
5644                         final ProcessRecord app = apps.valueAt(ia);
5645                         if (app.persistent) {
5646                             // We don't kill persistent processes.
5647                             continue;
5648                         }
5649                         if (app.removed) {
5650                             procs.add(app);
5651                         } else if (app.setAdj >= ProcessList.CACHED_APP_MIN_ADJ) {
5652                             app.removed = true;
5653                             procs.add(app);
5654                         }
5655                     }
5656                 }
5657
5658                 final int N = procs.size();
5659                 for (int i = 0; i < N; i++) {
5660                     removeProcessLocked(procs.get(i), false, true, "kill all background");
5661                 }
5662
5663                 mAllowLowerMemLevel = true;
5664
5665                 updateOomAdjLocked();
5666                 doLowMemReportIfNeededLocked(null);
5667             }
5668         } finally {
5669             Binder.restoreCallingIdentity(callingId);
5670         }
5671     }
5672
5673     /**
5674      * Kills all background processes, except those matching any of the
5675      * specified properties.
5676      *
5677      * @param minTargetSdk the target SDK version at or above which to preserve
5678      *                     processes, or {@code -1} to ignore the target SDK
5679      * @param maxProcState the process state at or below which to preserve
5680      *                     processes, or {@code -1} to ignore the process state
5681      */
5682     private void killAllBackgroundProcessesExcept(int minTargetSdk, int maxProcState) {
5683         if (checkCallingPermission(android.Manifest.permission.KILL_BACKGROUND_PROCESSES)
5684                 != PackageManager.PERMISSION_GRANTED) {
5685             final String msg = "Permission Denial: killAllBackgroundProcessesExcept() from pid="
5686                     + Binder.getCallingPid() + ", uid=" + Binder.getCallingUid()
5687                     + " requires " + android.Manifest.permission.KILL_BACKGROUND_PROCESSES;
5688             Slog.w(TAG, msg);
5689             throw new SecurityException(msg);
5690         }
5691
5692         final long callingId = Binder.clearCallingIdentity();
5693         try {
5694             synchronized (this) {
5695                 final ArrayList<ProcessRecord> procs = new ArrayList<>();
5696                 final int NP = mProcessNames.getMap().size();
5697                 for (int ip = 0; ip < NP; ip++) {
5698                     final SparseArray<ProcessRecord> apps = mProcessNames.getMap().valueAt(ip);
5699                     final int NA = apps.size();
5700                     for (int ia = 0; ia < NA; ia++) {
5701                         final ProcessRecord app = apps.valueAt(ia);
5702                         if (app.removed) {
5703                             procs.add(app);
5704                         } else if ((minTargetSdk < 0 || app.info.targetSdkVersion < minTargetSdk)
5705                                 && (maxProcState < 0 || app.setProcState > maxProcState)) {
5706                             app.removed = true;
5707                             procs.add(app);
5708                         }
5709                     }
5710                 }
5711
5712                 final int N = procs.size();
5713                 for (int i = 0; i < N; i++) {
5714                     removeProcessLocked(procs.get(i), false, true, "kill all background except");
5715                 }
5716             }
5717         } finally {
5718             Binder.restoreCallingIdentity(callingId);
5719         }
5720     }
5721
5722     @Override
5723     public void forceStopPackage(final String packageName, int userId) {
5724         if (checkCallingPermission(android.Manifest.permission.FORCE_STOP_PACKAGES)
5725                 != PackageManager.PERMISSION_GRANTED) {
5726             String msg = "Permission Denial: forceStopPackage() from pid="
5727                     + Binder.getCallingPid()
5728                     + ", uid=" + Binder.getCallingUid()
5729                     + " requires " + android.Manifest.permission.FORCE_STOP_PACKAGES;
5730             Slog.w(TAG, msg);
5731             throw new SecurityException(msg);
5732         }
5733         final int callingPid = Binder.getCallingPid();
5734         userId = mUserController.handleIncomingUser(callingPid, Binder.getCallingUid(),
5735                 userId, true, ALLOW_FULL_ONLY, "forceStopPackage", null);
5736         long callingId = Binder.clearCallingIdentity();
5737         try {
5738             IPackageManager pm = AppGlobals.getPackageManager();
5739             synchronized(this) {
5740                 int[] users = userId == UserHandle.USER_ALL
5741                         ? mUserController.getUsers() : new int[] { userId };
5742                 for (int user : users) {
5743                     int pkgUid = -1;
5744                     try {
5745                         pkgUid = pm.getPackageUid(packageName, MATCH_DEBUG_TRIAGED_MISSING,
5746                                 user);
5747                     } catch (RemoteException e) {
5748                     }
5749                     if (pkgUid == -1) {
5750                         Slog.w(TAG, "Invalid packageName: " + packageName);
5751                         continue;
5752                     }
5753                     try {
5754                         pm.setPackageStoppedState(packageName, true, user);
5755                     } catch (RemoteException e) {
5756                     } catch (IllegalArgumentException e) {
5757                         Slog.w(TAG, "Failed trying to unstop package "
5758                                 + packageName + ": " + e);
5759                     }
5760                     if (mUserController.isUserRunningLocked(user, 0)) {
5761                         forceStopPackageLocked(packageName, pkgUid, "from pid " + callingPid);
5762                         finishForceStopPackageLocked(packageName, pkgUid);
5763                     }
5764                 }
5765             }
5766         } finally {
5767             Binder.restoreCallingIdentity(callingId);
5768         }
5769     }
5770
5771     @Override
5772     public void addPackageDependency(String packageName) {
5773         synchronized (this) {
5774             int callingPid = Binder.getCallingPid();
5775             if (callingPid == Process.myPid()) {
5776                 //  Yeah, um, no.
5777                 return;
5778             }
5779             ProcessRecord proc;
5780             synchronized (mPidsSelfLocked) {
5781                 proc = mPidsSelfLocked.get(Binder.getCallingPid());
5782             }
5783             if (proc != null) {
5784                 if (proc.pkgDeps == null) {
5785                     proc.pkgDeps = new ArraySet<String>(1);
5786                 }
5787                 proc.pkgDeps.add(packageName);
5788             }
5789         }
5790     }
5791
5792     /*
5793      * The pkg name and app id have to be specified.
5794      */
5795     @Override
5796     public void killApplication(String pkg, int appId, int userId, String reason) {
5797         if (pkg == null) {
5798             return;
5799         }
5800         // Make sure the uid is valid.
5801         if (appId < 0) {
5802             Slog.w(TAG, "Invalid appid specified for pkg : " + pkg);
5803             return;
5804         }
5805         int callerUid = Binder.getCallingUid();
5806         // Only the system server can kill an application
5807         if (UserHandle.getAppId(callerUid) == Process.SYSTEM_UID) {
5808             // Post an aysnc message to kill the application
5809             Message msg = mHandler.obtainMessage(KILL_APPLICATION_MSG);
5810             msg.arg1 = appId;
5811             msg.arg2 = userId;
5812             Bundle bundle = new Bundle();
5813             bundle.putString("pkg", pkg);
5814             bundle.putString("reason", reason);
5815             msg.obj = bundle;
5816             mHandler.sendMessage(msg);
5817         } else {
5818             throw new SecurityException(callerUid + " cannot kill pkg: " +
5819                     pkg);
5820         }
5821     }
5822
5823     @Override
5824     public void closeSystemDialogs(String reason) {
5825         enforceNotIsolatedCaller("closeSystemDialogs");
5826
5827         final int pid = Binder.getCallingPid();
5828         final int uid = Binder.getCallingUid();
5829         final long origId = Binder.clearCallingIdentity();
5830         try {
5831             synchronized (this) {
5832                 // Only allow this from foreground processes, so that background
5833                 // applications can't abuse it to prevent system UI from being shown.
5834                 if (uid >= Process.FIRST_APPLICATION_UID) {
5835                     ProcessRecord proc;
5836                     synchronized (mPidsSelfLocked) {
5837                         proc = mPidsSelfLocked.get(pid);
5838                     }
5839                     if (proc.curRawAdj > ProcessList.PERCEPTIBLE_APP_ADJ) {
5840                         Slog.w(TAG, "Ignoring closeSystemDialogs " + reason
5841                                 + " from background process " + proc);
5842                         return;
5843                     }
5844                 }
5845                 closeSystemDialogsLocked(reason);
5846             }
5847         } finally {
5848             Binder.restoreCallingIdentity(origId);
5849         }
5850     }
5851
5852     void closeSystemDialogsLocked(String reason) {
5853         Intent intent = new Intent(Intent.ACTION_CLOSE_SYSTEM_DIALOGS);
5854         intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY
5855                 | Intent.FLAG_RECEIVER_FOREGROUND);
5856         if (reason != null) {
5857             intent.putExtra("reason", reason);
5858         }
5859         mWindowManager.closeSystemDialogs(reason);
5860
5861         mStackSupervisor.closeSystemDialogsLocked();
5862
5863         broadcastIntentLocked(null, null, intent, null, null, 0, null, null, null,
5864                 AppOpsManager.OP_NONE, null, false, false,
5865                 -1, Process.SYSTEM_UID, UserHandle.USER_ALL);
5866     }
5867
5868     @Override
5869     public Debug.MemoryInfo[] getProcessMemoryInfo(int[] pids) {
5870         enforceNotIsolatedCaller("getProcessMemoryInfo");
5871         Debug.MemoryInfo[] infos = new Debug.MemoryInfo[pids.length];
5872         for (int i=pids.length-1; i>=0; i--) {
5873             ProcessRecord proc;
5874             int oomAdj;
5875             synchronized (this) {
5876                 synchronized (mPidsSelfLocked) {
5877                     proc = mPidsSelfLocked.get(pids[i]);
5878                     oomAdj = proc != null ? proc.setAdj : 0;
5879                 }
5880             }
5881             infos[i] = new Debug.MemoryInfo();
5882             Debug.getMemoryInfo(pids[i], infos[i]);
5883             if (proc != null) {
5884                 synchronized (this) {
5885                     if (proc.thread != null && proc.setAdj == oomAdj) {
5886                         // Record this for posterity if the process has been stable.
5887                         proc.baseProcessTracker.addPss(infos[i].getTotalPss(),
5888                                 infos[i].getTotalUss(), false, proc.pkgList);
5889                     }
5890                 }
5891             }
5892         }
5893         return infos;
5894     }
5895
5896     @Override
5897     public long[] getProcessPss(int[] pids) {
5898         enforceNotIsolatedCaller("getProcessPss");
5899         long[] pss = new long[pids.length];
5900         for (int i=pids.length-1; i>=0; i--) {
5901             ProcessRecord proc;
5902             int oomAdj;
5903             synchronized (this) {
5904                 synchronized (mPidsSelfLocked) {
5905                     proc = mPidsSelfLocked.get(pids[i]);
5906                     oomAdj = proc != null ? proc.setAdj : 0;
5907                 }
5908             }
5909             long[] tmpUss = new long[1];
5910             pss[i] = Debug.getPss(pids[i], tmpUss, null);
5911             if (proc != null) {
5912                 synchronized (this) {
5913                     if (proc.thread != null && proc.setAdj == oomAdj) {
5914                         // Record this for posterity if the process has been stable.
5915                         proc.baseProcessTracker.addPss(pss[i], tmpUss[0], false, proc.pkgList);
5916                     }
5917                 }
5918             }
5919         }
5920         return pss;
5921     }
5922
5923     @Override
5924     public void killApplicationProcess(String processName, int uid) {
5925         if (processName == null) {
5926             return;
5927         }
5928
5929         int callerUid = Binder.getCallingUid();
5930         // Only the system server can kill an application
5931         if (callerUid == Process.SYSTEM_UID) {
5932             synchronized (this) {
5933                 ProcessRecord app = getProcessRecordLocked(processName, uid, true);
5934                 if (app != null && app.thread != null) {
5935                     try {
5936                         app.thread.scheduleSuicide();
5937                     } catch (RemoteException e) {
5938                         // If the other end already died, then our work here is done.
5939                     }
5940                 } else {
5941                     Slog.w(TAG, "Process/uid not found attempting kill of "
5942                             + processName + " / " + uid);
5943                 }
5944             }
5945         } else {
5946             throw new SecurityException(callerUid + " cannot kill app process: " +
5947                     processName);
5948         }
5949     }
5950
5951     private void forceStopPackageLocked(final String packageName, int uid, String reason) {
5952         forceStopPackageLocked(packageName, UserHandle.getAppId(uid), false,
5953                 false, true, false, false, UserHandle.getUserId(uid), reason);
5954     }
5955
5956     private void finishForceStopPackageLocked(final String packageName, int uid) {
5957         Intent intent = new Intent(Intent.ACTION_PACKAGE_RESTARTED,
5958                 Uri.fromParts("package", packageName, null));
5959         if (!mProcessesReady) {
5960             intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY
5961                     | Intent.FLAG_RECEIVER_FOREGROUND);
5962         }
5963         intent.putExtra(Intent.EXTRA_UID, uid);
5964         intent.putExtra(Intent.EXTRA_USER_HANDLE, UserHandle.getUserId(uid));
5965         broadcastIntentLocked(null, null, intent,
5966                 null, null, 0, null, null, null, AppOpsManager.OP_NONE,
5967                 null, false, false, MY_PID, Process.SYSTEM_UID, UserHandle.getUserId(uid));
5968     }
5969
5970
5971     private final boolean killPackageProcessesLocked(String packageName, int appId,
5972             int userId, int minOomAdj, boolean callerWillRestart, boolean allowRestart,
5973             boolean doit, boolean evenPersistent, String reason) {
5974         ArrayList<ProcessRecord> procs = new ArrayList<>();
5975
5976         // Remove all processes this package may have touched: all with the
5977         // same UID (except for the system or root user), and all whose name
5978         // matches the package name.
5979         final int NP = mProcessNames.getMap().size();
5980         for (int ip=0; ip<NP; ip++) {
5981             SparseArray<ProcessRecord> apps = mProcessNames.getMap().valueAt(ip);
5982             final int NA = apps.size();
5983             for (int ia=0; ia<NA; ia++) {
5984                 ProcessRecord app = apps.valueAt(ia);
5985                 if (app.persistent && !evenPersistent) {
5986                     // we don't kill persistent processes
5987                     continue;
5988                 }
5989                 if (app.removed) {
5990                     if (doit) {
5991                         procs.add(app);
5992                     }
5993                     continue;
5994                 }
5995
5996                 // Skip process if it doesn't meet our oom adj requirement.
5997                 if (app.setAdj < minOomAdj) {
5998                     continue;
5999                 }
6000
6001                 // If no package is specified, we call all processes under the
6002                 // give user id.
6003                 if (packageName == null) {
6004                     if (userId != UserHandle.USER_ALL && app.userId != userId) {
6005                         continue;
6006                     }
6007                     if (appId >= 0 && UserHandle.getAppId(app.uid) != appId) {
6008                         continue;
6009                     }
6010                 // Package has been specified, we want to hit all processes
6011                 // that match it.  We need to qualify this by the processes
6012                 // that are running under the specified app and user ID.
6013                 } else {
6014                     final boolean isDep = app.pkgDeps != null
6015                             && app.pkgDeps.contains(packageName);
6016                     if (!isDep && UserHandle.getAppId(app.uid) != appId) {
6017                         continue;
6018                     }
6019                     if (userId != UserHandle.USER_ALL && app.userId != userId) {
6020                         continue;
6021                     }
6022                     if (!app.pkgList.containsKey(packageName) && !isDep) {
6023                         continue;
6024                     }
6025                 }
6026
6027                 // Process has passed all conditions, kill it!
6028                 if (!doit) {
6029                     return true;
6030                 }
6031                 app.removed = true;
6032                 procs.add(app);
6033             }
6034         }
6035
6036         int N = procs.size();
6037         for (int i=0; i<N; i++) {
6038             removeProcessLocked(procs.get(i), callerWillRestart, allowRestart, reason);
6039         }
6040         updateOomAdjLocked();
6041         return N > 0;
6042     }
6043
6044     private void cleanupDisabledPackageComponentsLocked(
6045             String packageName, int userId, boolean killProcess, String[] changedClasses) {
6046
6047         Set<String> disabledClasses = null;
6048         boolean packageDisabled = false;
6049         IPackageManager pm = AppGlobals.getPackageManager();
6050
6051         if (changedClasses == null) {
6052             // Nothing changed...
6053             return;
6054         }
6055
6056         // Determine enable/disable state of the package and its components.
6057         int enabled = PackageManager.COMPONENT_ENABLED_STATE_DEFAULT;
6058         for (int i = changedClasses.length - 1; i >= 0; i--) {
6059             final String changedClass = changedClasses[i];
6060
6061             if (changedClass.equals(packageName)) {
6062                 try {
6063                     // Entire package setting changed
6064                     enabled = pm.getApplicationEnabledSetting(packageName,
6065                             (userId != UserHandle.USER_ALL) ? userId : UserHandle.USER_SYSTEM);
6066                 } catch (Exception e) {
6067                     // No such package/component; probably racing with uninstall.  In any
6068                     // event it means we have nothing further to do here.
6069                     return;
6070                 }
6071                 packageDisabled = enabled != PackageManager.COMPONENT_ENABLED_STATE_ENABLED
6072                         && enabled != PackageManager.COMPONENT_ENABLED_STATE_DEFAULT;
6073                 if (packageDisabled) {
6074                     // Entire package is disabled.
6075                     // No need to continue to check component states.
6076                     disabledClasses = null;
6077                     break;
6078                 }
6079             } else {
6080                 try {
6081                     enabled = pm.getComponentEnabledSetting(
6082                             new ComponentName(packageName, changedClass),
6083                             (userId != UserHandle.USER_ALL) ? userId : UserHandle.USER_SYSTEM);
6084                 } catch (Exception e) {
6085                     // As above, probably racing with uninstall.
6086                     return;
6087                 }
6088                 if (enabled != PackageManager.COMPONENT_ENABLED_STATE_ENABLED
6089                         && enabled != PackageManager.COMPONENT_ENABLED_STATE_DEFAULT) {
6090                     if (disabledClasses == null) {
6091                         disabledClasses = new ArraySet<>(changedClasses.length);
6092                     }
6093                     disabledClasses.add(changedClass);
6094                 }
6095             }
6096         }
6097
6098         if (!packageDisabled && disabledClasses == null) {
6099             // Nothing to do here...
6100             return;
6101         }
6102
6103         // Clean-up disabled activities.
6104         if (mStackSupervisor.finishDisabledPackageActivitiesLocked(
6105                 packageName, disabledClasses, true, false, userId) && mBooted) {
6106             mStackSupervisor.resumeFocusedStackTopActivityLocked();
6107             mStackSupervisor.scheduleIdleLocked();
6108         }
6109
6110         // Clean-up disabled tasks
6111         cleanupDisabledPackageTasksLocked(packageName, disabledClasses, userId);
6112
6113         // Clean-up disabled services.
6114         mServices.bringDownDisabledPackageServicesLocked(
6115                 packageName, disabledClasses, userId, false, killProcess, true);
6116
6117         // Clean-up disabled providers.
6118         ArrayList<ContentProviderRecord> providers = new ArrayList<>();
6119         mProviderMap.collectPackageProvidersLocked(
6120                 packageName, disabledClasses, true, false, userId, providers);
6121         for (int i = providers.size() - 1; i >= 0; i--) {
6122             removeDyingProviderLocked(null, providers.get(i), true);
6123         }
6124
6125         // Clean-up disabled broadcast receivers.
6126         for (int i = mBroadcastQueues.length - 1; i >= 0; i--) {
6127             mBroadcastQueues[i].cleanupDisabledPackageReceiversLocked(
6128                     packageName, disabledClasses, userId, true);
6129         }
6130
6131     }
6132
6133     final boolean clearBroadcastQueueForUserLocked(int userId) {
6134         boolean didSomething = false;
6135         for (int i = mBroadcastQueues.length - 1; i >= 0; i--) {
6136             didSomething |= mBroadcastQueues[i].cleanupDisabledPackageReceiversLocked(
6137                     null, null, userId, true);
6138         }
6139         return didSomething;
6140     }
6141
6142     final boolean forceStopPackageLocked(String packageName, int appId,
6143             boolean callerWillRestart, boolean purgeCache, boolean doit,
6144             boolean evenPersistent, boolean uninstalling, int userId, String reason) {
6145         int i;
6146
6147         if (userId == UserHandle.USER_ALL && packageName == null) {
6148             Slog.w(TAG, "Can't force stop all processes of all users, that is insane!");
6149         }
6150
6151         if (appId < 0 && packageName != null) {
6152             try {
6153                 appId = UserHandle.getAppId(AppGlobals.getPackageManager()
6154                         .getPackageUid(packageName, MATCH_DEBUG_TRIAGED_MISSING, 0));
6155             } catch (RemoteException e) {
6156             }
6157         }
6158
6159         if (doit) {
6160             if (packageName != null) {
6161                 Slog.i(TAG, "Force stopping " + packageName + " appid=" + appId
6162                         + " user=" + userId + ": " + reason);
6163             } else {
6164                 Slog.i(TAG, "Force stopping u" + userId + ": " + reason);
6165             }
6166
6167             mAppErrors.resetProcessCrashTimeLocked(packageName == null, appId, userId);
6168         }
6169
6170         boolean didSomething = killPackageProcessesLocked(packageName, appId, userId,
6171                 ProcessList.INVALID_ADJ, callerWillRestart, true, doit, evenPersistent,
6172                 packageName == null ? ("stop user " + userId) : ("stop " + packageName));
6173
6174         if (mStackSupervisor.finishDisabledPackageActivitiesLocked(
6175                 packageName, null, doit, evenPersistent, userId)) {
6176             if (!doit) {
6177                 return true;
6178             }
6179             didSomething = true;
6180         }
6181
6182         if (mServices.bringDownDisabledPackageServicesLocked(
6183                 packageName, null, userId, evenPersistent, true, doit)) {
6184             if (!doit) {
6185                 return true;
6186             }
6187             didSomething = true;
6188         }
6189
6190         if (packageName == null) {
6191             // Remove all sticky broadcasts from this user.
6192             mStickyBroadcasts.remove(userId);
6193         }
6194
6195         ArrayList<ContentProviderRecord> providers = new ArrayList<>();
6196         if (mProviderMap.collectPackageProvidersLocked(packageName, null, doit, evenPersistent,
6197                 userId, providers)) {
6198             if (!doit) {
6199                 return true;
6200             }
6201             didSomething = true;
6202         }
6203         for (i = providers.size() - 1; i >= 0; i--) {
6204             removeDyingProviderLocked(null, providers.get(i), true);
6205         }
6206
6207         // Remove transient permissions granted from/to this package/user
6208         removeUriPermissionsForPackageLocked(packageName, userId, false);
6209
6210         if (doit) {
6211             for (i = mBroadcastQueues.length - 1; i >= 0; i--) {
6212                 didSomething |= mBroadcastQueues[i].cleanupDisabledPackageReceiversLocked(
6213                         packageName, null, userId, doit);
6214             }
6215         }
6216
6217         if (packageName == null || uninstalling) {
6218             // Remove pending intents.  For now we only do this when force
6219             // stopping users, because we have some problems when doing this
6220             // for packages -- app widgets are not currently cleaned up for
6221             // such packages, so they can be left with bad pending intents.
6222             if (mIntentSenderRecords.size() > 0) {
6223                 Iterator<WeakReference<PendingIntentRecord>> it
6224                         = mIntentSenderRecords.values().iterator();
6225                 while (it.hasNext()) {
6226                     WeakReference<PendingIntentRecord> wpir = it.next();
6227                     if (wpir == null) {
6228                         it.remove();
6229                         continue;
6230                     }
6231                     PendingIntentRecord pir = wpir.get();
6232                     if (pir == null) {
6233                         it.remove();
6234                         continue;
6235                     }
6236                     if (packageName == null) {
6237                         // Stopping user, remove all objects for the user.
6238                         if (pir.key.userId != userId) {
6239                             // Not the same user, skip it.
6240                             continue;
6241                         }
6242                     } else {
6243                         if (UserHandle.getAppId(pir.uid) != appId) {
6244                             // Different app id, skip it.
6245                             continue;
6246                         }
6247                         if (userId != UserHandle.USER_ALL && pir.key.userId != userId) {
6248                             // Different user, skip it.
6249                             continue;
6250                         }
6251                         if (!pir.key.packageName.equals(packageName)) {
6252                             // Different package, skip it.
6253                             continue;
6254                         }
6255                     }
6256                     if (!doit) {
6257                         return true;
6258                     }
6259                     didSomething = true;
6260                     it.remove();
6261                     pir.canceled = true;
6262                     if (pir.key.activity != null && pir.key.activity.pendingResults != null) {
6263                         pir.key.activity.pendingResults.remove(pir.ref);
6264                     }
6265                 }
6266             }
6267         }
6268
6269         if (doit) {
6270             if (purgeCache && packageName != null) {
6271                 AttributeCache ac = AttributeCache.instance();
6272                 if (ac != null) {
6273                     ac.removePackage(packageName);
6274                 }
6275             }
6276             if (mBooted) {
6277                 mStackSupervisor.resumeFocusedStackTopActivityLocked();
6278                 mStackSupervisor.scheduleIdleLocked();
6279             }
6280         }
6281
6282         return didSomething;
6283     }
6284
6285     private final ProcessRecord removeProcessNameLocked(final String name, final int uid) {
6286         return removeProcessNameLocked(name, uid, null);
6287     }
6288
6289     private final ProcessRecord removeProcessNameLocked(final String name, final int uid,
6290             final ProcessRecord expecting) {
6291         ProcessRecord old = mProcessNames.get(name, uid);
6292         // Only actually remove when the currently recorded value matches the
6293         // record that we expected; if it doesn't match then we raced with a
6294         // newly created process and we don't want to destroy the new one.
6295         if ((expecting == null) || (old == expecting)) {
6296             mProcessNames.remove(name, uid);
6297         }
6298         if (old != null && old.uidRecord != null) {
6299             old.uidRecord.numProcs--;
6300             if (old.uidRecord.numProcs == 0) {
6301                 // No more processes using this uid, tell clients it is gone.
6302                 if (DEBUG_UID_OBSERVERS) Slog.i(TAG_UID_OBSERVERS,
6303                         "No more processes in " + old.uidRecord);
6304                 enqueueUidChangeLocked(old.uidRecord, -1, UidRecord.CHANGE_GONE);
6305                 mActiveUids.remove(uid);
6306                 noteUidProcessState(uid, ActivityManager.PROCESS_STATE_NONEXISTENT);
6307             }
6308             old.uidRecord = null;
6309         }
6310         mIsolatedProcesses.remove(uid);
6311         return old;
6312     }
6313
6314     private final void addProcessNameLocked(ProcessRecord proc) {
6315         // We shouldn't already have a process under this name, but just in case we
6316         // need to clean up whatever may be there now.
6317         ProcessRecord old = removeProcessNameLocked(proc.processName, proc.uid);
6318         if (old == proc && proc.persistent) {
6319             // We are re-adding a persistent process.  Whatevs!  Just leave it there.
6320             Slog.w(TAG, "Re-adding persistent process " + proc);
6321         } else if (old != null) {
6322             Slog.wtf(TAG, "Already have existing proc " + old + " when adding " + proc);
6323         }
6324         UidRecord uidRec = mActiveUids.get(proc.uid);
6325         if (uidRec == null) {
6326             uidRec = new UidRecord(proc.uid);
6327             // This is the first appearance of the uid, report it now!
6328             if (DEBUG_UID_OBSERVERS) Slog.i(TAG_UID_OBSERVERS,
6329                     "Creating new process uid: " + uidRec);
6330             mActiveUids.put(proc.uid, uidRec);
6331             noteUidProcessState(uidRec.uid, uidRec.curProcState);
6332             enqueueUidChangeLocked(uidRec, -1, UidRecord.CHANGE_ACTIVE);
6333         }
6334         proc.uidRecord = uidRec;
6335
6336         // Reset render thread tid if it was already set, so new process can set it again.
6337         proc.renderThreadTid = 0;
6338         uidRec.numProcs++;
6339         mProcessNames.put(proc.processName, proc.uid, proc);
6340         if (proc.isolated) {
6341             mIsolatedProcesses.put(proc.uid, proc);
6342         }
6343     }
6344
6345     boolean removeProcessLocked(ProcessRecord app,
6346             boolean callerWillRestart, boolean allowRestart, String reason) {
6347         final String name = app.processName;
6348         final int uid = app.uid;
6349         if (DEBUG_PROCESSES) Slog.d(TAG_PROCESSES,
6350             "Force removing proc " + app.toShortString() + " (" + name + "/" + uid + ")");
6351
6352         ProcessRecord old = mProcessNames.get(name, uid);
6353         if (old != app) {
6354             // This process is no longer active, so nothing to do.
6355             Slog.w(TAG, "Ignoring remove of inactive process: " + app);
6356             return false;
6357         }
6358         removeProcessNameLocked(name, uid);
6359         if (mHeavyWeightProcess == app) {
6360             mHandler.sendMessage(mHandler.obtainMessage(CANCEL_HEAVY_NOTIFICATION_MSG,
6361                     mHeavyWeightProcess.userId, 0));
6362             mHeavyWeightProcess = null;
6363         }
6364         boolean needRestart = false;
6365         if (app.pid > 0 && app.pid != MY_PID) {
6366             int pid = app.pid;
6367             synchronized (mPidsSelfLocked) {
6368                 mPidsSelfLocked.remove(pid);
6369                 mHandler.removeMessages(PROC_START_TIMEOUT_MSG, app);
6370             }
6371             mBatteryStatsService.noteProcessFinish(app.processName, app.info.uid);
6372             if (app.isolated) {
6373                 mBatteryStatsService.removeIsolatedUid(app.uid, app.info.uid);
6374             }
6375             boolean willRestart = false;
6376             if (app.persistent && !app.isolated) {
6377                 if (!callerWillRestart) {
6378                     willRestart = true;
6379                 } else {
6380                     needRestart = true;
6381                 }
6382             }
6383             app.kill(reason, true);
6384             handleAppDiedLocked(app, willRestart, allowRestart);
6385             if (willRestart) {
6386                 removeLruProcessLocked(app);
6387                 addAppLocked(app.info, false, null /* ABI override */);
6388             }
6389         } else {
6390             mRemovedProcesses.add(app);
6391         }
6392
6393         return needRestart;
6394     }
6395
6396     private final void processContentProviderPublishTimedOutLocked(ProcessRecord app) {
6397         cleanupAppInLaunchingProvidersLocked(app, true);
6398         removeProcessLocked(app, false, true, "timeout publishing content providers");
6399     }
6400
6401     private final void processStartTimedOutLocked(ProcessRecord app) {
6402         final int pid = app.pid;
6403         boolean gone = false;
6404         synchronized (mPidsSelfLocked) {
6405             ProcessRecord knownApp = mPidsSelfLocked.get(pid);
6406             if (knownApp != null && knownApp.thread == null) {
6407                 mPidsSelfLocked.remove(pid);
6408                 gone = true;
6409             }
6410         }
6411
6412         if (gone) {
6413             Slog.w(TAG, "Process " + app + " failed to attach");
6414             EventLog.writeEvent(EventLogTags.AM_PROCESS_START_TIMEOUT, app.userId,
6415                     pid, app.uid, app.processName);
6416             removeProcessNameLocked(app.processName, app.uid);
6417             if (mHeavyWeightProcess == app) {
6418                 mHandler.sendMessage(mHandler.obtainMessage(CANCEL_HEAVY_NOTIFICATION_MSG,
6419                         mHeavyWeightProcess.userId, 0));
6420                 mHeavyWeightProcess = null;
6421             }
6422             mBatteryStatsService.noteProcessFinish(app.processName, app.info.uid);
6423             if (app.isolated) {
6424                 mBatteryStatsService.removeIsolatedUid(app.uid, app.info.uid);
6425             }
6426             // Take care of any launching providers waiting for this process.
6427             cleanupAppInLaunchingProvidersLocked(app, true);
6428             // Take care of any services that are waiting for the process.
6429             mServices.processStartTimedOutLocked(app);
6430             app.kill("start timeout", true);
6431             removeLruProcessLocked(app);
6432             if (mBackupTarget != null && mBackupTarget.app.pid == pid) {
6433                 Slog.w(TAG, "Unattached app died before backup, skipping");
6434                 try {
6435                     IBackupManager bm = IBackupManager.Stub.asInterface(
6436                             ServiceManager.getService(Context.BACKUP_SERVICE));
6437                     bm.agentDisconnected(app.info.packageName);
6438                 } catch (RemoteException e) {
6439                     // Can't happen; the backup manager is local
6440                 }
6441             }
6442             if (isPendingBroadcastProcessLocked(pid)) {
6443                 Slog.w(TAG, "Unattached app died before broadcast acknowledged, skipping");
6444                 skipPendingBroadcastLocked(pid);
6445             }
6446         } else {
6447             Slog.w(TAG, "Spurious process start timeout - pid not known for " + app);
6448         }
6449     }
6450
6451     private final boolean attachApplicationLocked(IApplicationThread thread,
6452             int pid) {
6453
6454         // Find the application record that is being attached...  either via
6455         // the pid if we are running in multiple processes, or just pull the
6456         // next app record if we are emulating process with anonymous threads.
6457         ProcessRecord app;
6458         long startTime = SystemClock.uptimeMillis();
6459         if (pid != MY_PID && pid >= 0) {
6460             synchronized (mPidsSelfLocked) {
6461                 app = mPidsSelfLocked.get(pid);
6462             }
6463         } else {
6464             app = null;
6465         }
6466
6467         if (app == null) {
6468             Slog.w(TAG, "No pending application record for pid " + pid
6469                     + " (IApplicationThread " + thread + "); dropping process");
6470             EventLog.writeEvent(EventLogTags.AM_DROP_PROCESS, pid);
6471             if (pid > 0 && pid != MY_PID) {
6472                 Process.killProcessQuiet(pid);
6473                 //TODO: killProcessGroup(app.info.uid, pid);
6474             } else {
6475                 try {
6476                     thread.scheduleExit();
6477                 } catch (Exception e) {
6478                     // Ignore exceptions.
6479                 }
6480             }
6481             return false;
6482         }
6483
6484         // If this application record is still attached to a previous
6485         // process, clean it up now.
6486         if (app.thread != null) {
6487             handleAppDiedLocked(app, true, true);
6488         }
6489
6490         // Tell the process all about itself.
6491
6492         if (DEBUG_ALL) Slog.v(
6493                 TAG, "Binding process pid " + pid + " to record " + app);
6494
6495         final String processName = app.processName;
6496         try {
6497             AppDeathRecipient adr = new AppDeathRecipient(
6498                     app, pid, thread);
6499             thread.asBinder().linkToDeath(adr, 0);
6500             app.deathRecipient = adr;
6501         } catch (RemoteException e) {
6502             app.resetPackageList(mProcessStats);
6503             startProcessLocked(app, "link fail", processName);
6504             return false;
6505         }
6506
6507         EventLog.writeEvent(EventLogTags.AM_PROC_BOUND, app.userId, app.pid, app.processName);
6508
6509         app.makeActive(thread, mProcessStats);
6510         app.curAdj = app.setAdj = app.verifiedAdj = ProcessList.INVALID_ADJ;
6511         app.curSchedGroup = app.setSchedGroup = ProcessList.SCHED_GROUP_DEFAULT;
6512         app.forcingToForeground = null;
6513         updateProcessForegroundLocked(app, false, false);
6514         app.hasShownUi = false;
6515         app.debugging = false;
6516         app.cached = false;
6517         app.killedByAm = false;
6518
6519         // We carefully use the same state that PackageManager uses for
6520         // filtering, since we use this flag to decide if we need to install
6521         // providers when user is unlocked later
6522         app.unlocked = StorageManager.isUserKeyUnlocked(app.userId);
6523
6524         mHandler.removeMessages(PROC_START_TIMEOUT_MSG, app);
6525
6526         boolean normalMode = mProcessesReady || isAllowedWhileBooting(app.info);
6527         List<ProviderInfo> providers = normalMode ? generateApplicationProvidersLocked(app) : null;
6528
6529         if (providers != null && checkAppInLaunchingProvidersLocked(app)) {
6530             Message msg = mHandler.obtainMessage(CONTENT_PROVIDER_PUBLISH_TIMEOUT_MSG);
6531             msg.obj = app;
6532             mHandler.sendMessageDelayed(msg, CONTENT_PROVIDER_PUBLISH_TIMEOUT);
6533         }
6534
6535         checkTime(startTime, "attachApplicationLocked: before bindApplication");
6536         
6537         if (!normalMode) {
6538             Slog.i(TAG, "Launching preboot mode app: " + app);
6539         }
6540
6541         if (DEBUG_ALL) Slog.v(
6542             TAG, "New app record " + app
6543             + " thread=" + thread.asBinder() + " pid=" + pid);
6544         try {
6545             int testMode = IApplicationThread.DEBUG_OFF;
6546             if (mDebugApp != null && mDebugApp.equals(processName)) {
6547                 testMode = mWaitForDebugger
6548                     ? IApplicationThread.DEBUG_WAIT
6549                     : IApplicationThread.DEBUG_ON;
6550                 app.debugging = true;
6551                 if (mDebugTransient) {
6552                     mDebugApp = mOrigDebugApp;
6553                     mWaitForDebugger = mOrigWaitForDebugger;
6554                 }
6555             }
6556             String profileFile = app.instrumentationProfileFile;
6557             ParcelFileDescriptor profileFd = null;
6558             int samplingInterval = 0;
6559             boolean profileAutoStop = false;
6560             if (mProfileApp != null && mProfileApp.equals(processName)) {
6561                 mProfileProc = app;
6562                 profileFile = mProfileFile;
6563                 profileFd = mProfileFd;
6564                 samplingInterval = mSamplingInterval;
6565                 profileAutoStop = mAutoStopProfiler;
6566             }
6567             boolean enableTrackAllocation = false;
6568             if (mTrackAllocationApp != null && mTrackAllocationApp.equals(processName)) {
6569                 enableTrackAllocation = true;
6570                 mTrackAllocationApp = null;
6571             }
6572
6573             // If the app is being launched for restore or full backup, set it up specially
6574             boolean isRestrictedBackupMode = false;
6575             if (mBackupTarget != null && mBackupAppName.equals(processName)) {
6576                 isRestrictedBackupMode = mBackupTarget.appInfo.uid >= Process.FIRST_APPLICATION_UID
6577                         && ((mBackupTarget.backupMode == BackupRecord.RESTORE)
6578                                 || (mBackupTarget.backupMode == BackupRecord.RESTORE_FULL)
6579                                 || (mBackupTarget.backupMode == BackupRecord.BACKUP_FULL));
6580             }
6581
6582             if (app.instrumentationClass != null) {
6583                 notifyPackageUse(app.instrumentationClass.getPackageName(),
6584                                  PackageManager.NOTIFY_PACKAGE_USE_INSTRUMENTATION);
6585             }
6586             if (DEBUG_CONFIGURATION) Slog.v(TAG_CONFIGURATION, "Binding proc "
6587                     + processName + " with config " + mConfiguration);
6588             ApplicationInfo appInfo = app.instrumentationInfo != null
6589                     ? app.instrumentationInfo : app.info;
6590             app.compat = compatibilityInfoForPackageLocked(appInfo);
6591             if (profileFd != null) {
6592                 profileFd = profileFd.dup();
6593             }
6594             ProfilerInfo profilerInfo = profileFile == null ? null
6595                 : new ProfilerInfo(profileFile, profileFd, samplingInterval, profileAutoStop);
6596             checkTime(startTime, "attachApplicationLocked: immediately before bindApplication");
6597             thread.bindApplication(processName, appInfo, providers, app.instrumentationClass,
6598                     profilerInfo, app.instrumentationArguments, app.instrumentationWatcher,
6599                     app.instrumentationUiAutomationConnection, testMode,
6600                     mBinderTransactionTrackingEnabled, enableTrackAllocation,
6601                     isRestrictedBackupMode || !normalMode, app.persistent,
6602                     new Configuration(mConfiguration), app.compat,
6603                     getCommonServicesLocked(app.isolated),
6604                                    mCoreSettingsObserver.getCoreSettingsLocked());
6605             checkTime(startTime, "attachApplicationLocked: immediately after bindApplication");
6606             updateLruProcessLocked(app, false, null);
6607             checkTime(startTime, "attachApplicationLocked: after updateLruProcessLocked");
6608             app.lastRequestedGc = app.lastLowMemory = SystemClock.uptimeMillis();
6609         } catch (Exception e) {
6610             // todo: Yikes!  What should we do?  For now we will try to
6611             // start another process, but that could easily get us in
6612             // an infinite loop of restarting processes...
6613             Slog.wtf(TAG, "Exception thrown during bind of " + app, e);
6614
6615             app.resetPackageList(mProcessStats);
6616             app.unlinkDeathRecipient();
6617             startProcessLocked(app, "bind fail", processName);
6618             return false;
6619         }
6620
6621         // Remove this record from the list of starting applications.
6622         mPersistentStartingProcesses.remove(app);
6623         if (DEBUG_PROCESSES && mProcessesOnHold.contains(app)) Slog.v(TAG_PROCESSES,
6624                 "Attach application locked removing on hold: " + app);
6625         mProcessesOnHold.remove(app);
6626
6627         boolean badApp = false;
6628         boolean didSomething = false;
6629
6630         // See if the top visible activity is waiting to run in this process...
6631         if (normalMode) {
6632             try {
6633                 if (mStackSupervisor.attachApplicationLocked(app)) {
6634                     didSomething = true;
6635                 }
6636             } catch (Exception e) {
6637                 Slog.wtf(TAG, "Exception thrown launching activities in " + app, e);
6638                 badApp = true;
6639             }
6640         }
6641
6642         // Find any services that should be running in this process...
6643         if (!badApp) {
6644             try {
6645                 didSomething |= mServices.attachApplicationLocked(app, processName);
6646                 checkTime(startTime, "attachApplicationLocked: after mServices.attachApplicationLocked");
6647             } catch (Exception e) {
6648                 Slog.wtf(TAG, "Exception thrown starting services in " + app, e);
6649                 badApp = true;
6650             }
6651         }
6652
6653         // Check if a next-broadcast receiver is in this process...
6654         if (!badApp && isPendingBroadcastProcessLocked(pid)) {
6655             try {
6656                 didSomething |= sendPendingBroadcastsLocked(app);
6657                 checkTime(startTime, "attachApplicationLocked: after sendPendingBroadcastsLocked");
6658             } catch (Exception e) {
6659                 // If the app died trying to launch the receiver we declare it 'bad'
6660                 Slog.wtf(TAG, "Exception thrown dispatching broadcasts in " + app, e);
6661                 badApp = true;
6662             }
6663         }
6664
6665         // Check whether the next backup agent is in this process...
6666         if (!badApp && mBackupTarget != null && mBackupTarget.appInfo.uid == app.uid) {
6667             if (DEBUG_BACKUP) Slog.v(TAG_BACKUP,
6668                     "New app is backup target, launching agent for " + app);
6669             notifyPackageUse(mBackupTarget.appInfo.packageName,
6670                              PackageManager.NOTIFY_PACKAGE_USE_BACKUP);
6671             try {
6672                 thread.scheduleCreateBackupAgent(mBackupTarget.appInfo,
6673                         compatibilityInfoForPackageLocked(mBackupTarget.appInfo),
6674                         mBackupTarget.backupMode);
6675             } catch (Exception e) {
6676                 Slog.wtf(TAG, "Exception thrown creating backup agent in " + app, e);
6677                 badApp = true;
6678             }
6679         }
6680
6681         if (badApp) {
6682             app.kill("error during init", true);
6683             handleAppDiedLocked(app, false, true);
6684             return false;
6685         }
6686
6687         if (!didSomething) {
6688             updateOomAdjLocked();
6689             checkTime(startTime, "attachApplicationLocked: after updateOomAdjLocked");
6690         }
6691
6692         return true;
6693     }
6694
6695     @Override
6696     public final void attachApplication(IApplicationThread thread) {
6697         synchronized (this) {
6698             int callingPid = Binder.getCallingPid();
6699             final long origId = Binder.clearCallingIdentity();
6700             attachApplicationLocked(thread, callingPid);
6701             Binder.restoreCallingIdentity(origId);
6702         }
6703     }
6704
6705     @Override
6706     public final void activityIdle(IBinder token, Configuration config, boolean stopProfiling) {
6707         final long origId = Binder.clearCallingIdentity();
6708         synchronized (this) {
6709             ActivityStack stack = ActivityRecord.getStackLocked(token);
6710             if (stack != null) {
6711                 ActivityRecord r =
6712                         mStackSupervisor.activityIdleInternalLocked(token, false, config);
6713                 if (stopProfiling) {
6714                     if ((mProfileProc == r.app) && (mProfileFd != null)) {
6715                         try {
6716                             mProfileFd.close();
6717                         } catch (IOException e) {
6718                         }
6719                         clearProfilerLocked();
6720                     }
6721                 }
6722             }
6723         }
6724         Binder.restoreCallingIdentity(origId);
6725     }
6726
6727     void postFinishBooting(boolean finishBooting, boolean enableScreen) {
6728         mHandler.sendMessage(mHandler.obtainMessage(FINISH_BOOTING_MSG,
6729                 finishBooting ? 1 : 0, enableScreen ? 1 : 0));
6730     }
6731
6732     void enableScreenAfterBoot() {
6733         EventLog.writeEvent(EventLogTags.BOOT_PROGRESS_ENABLE_SCREEN,
6734                 SystemClock.uptimeMillis());
6735         mWindowManager.enableScreenAfterBoot();
6736
6737         synchronized (this) {
6738             updateEventDispatchingLocked();
6739         }
6740     }
6741
6742     @Override
6743     public void showBootMessage(final CharSequence msg, final boolean always) {
6744         if (Binder.getCallingUid() != Process.myUid()) {
6745             throw new SecurityException();
6746         }
6747         mWindowManager.showBootMessage(msg, always);
6748     }
6749
6750     @Override
6751     public void keyguardWaitingForActivityDrawn() {
6752         enforceNotIsolatedCaller("keyguardWaitingForActivityDrawn");
6753         final long token = Binder.clearCallingIdentity();
6754         try {
6755             synchronized (this) {
6756                 if (DEBUG_LOCKSCREEN) logLockScreen("");
6757                 mWindowManager.keyguardWaitingForActivityDrawn();
6758                 if (mLockScreenShown == LOCK_SCREEN_SHOWN) {
6759                     mLockScreenShown = LOCK_SCREEN_LEAVING;
6760                     updateSleepIfNeededLocked();
6761                 }
6762             }
6763         } finally {
6764             Binder.restoreCallingIdentity(token);
6765         }
6766     }
6767
6768     @Override
6769     public void keyguardGoingAway(int flags) {
6770         enforceNotIsolatedCaller("keyguardGoingAway");
6771         final long token = Binder.clearCallingIdentity();
6772         try {
6773             synchronized (this) {
6774                 if (DEBUG_LOCKSCREEN) logLockScreen("");
6775                 mWindowManager.keyguardGoingAway(flags);
6776                 if (mLockScreenShown == LOCK_SCREEN_SHOWN) {
6777                     mLockScreenShown = LOCK_SCREEN_HIDDEN;
6778                     updateSleepIfNeededLocked();
6779
6780                     // Some stack visibility might change (e.g. docked stack)
6781                     mStackSupervisor.ensureActivitiesVisibleLocked(null, 0, !PRESERVE_WINDOWS);
6782                 }
6783             }
6784         } finally {
6785             Binder.restoreCallingIdentity(token);
6786         }
6787     }
6788
6789     final void finishBooting() {
6790         synchronized (this) {
6791             if (!mBootAnimationComplete) {
6792                 mCallFinishBooting = true;
6793                 return;
6794             }
6795             mCallFinishBooting = false;
6796         }
6797
6798         ArraySet<String> completedIsas = new ArraySet<String>();
6799         for (String abi : Build.SUPPORTED_ABIS) {
6800             Process.establishZygoteConnectionForAbi(abi);
6801             final String instructionSet = VMRuntime.getInstructionSet(abi);
6802             if (!completedIsas.contains(instructionSet)) {
6803                 try {
6804                     mInstaller.markBootComplete(VMRuntime.getInstructionSet(abi));
6805                 } catch (InstallerException e) {
6806                     Slog.w(TAG, "Unable to mark boot complete for abi: " + abi + " (" +
6807                             e.getMessage() +")");
6808                 }
6809                 completedIsas.add(instructionSet);
6810             }
6811         }
6812
6813         IntentFilter pkgFilter = new IntentFilter();
6814         pkgFilter.addAction(Intent.ACTION_QUERY_PACKAGE_RESTART);
6815         pkgFilter.addDataScheme("package");
6816         mContext.registerReceiver(new BroadcastReceiver() {
6817             @Override
6818             public void onReceive(Context context, Intent intent) {
6819                 String[] pkgs = intent.getStringArrayExtra(Intent.EXTRA_PACKAGES);
6820                 if (pkgs != null) {
6821                     for (String pkg : pkgs) {
6822                         synchronized (ActivityManagerService.this) {
6823                             if (forceStopPackageLocked(pkg, -1, false, false, false, false, false,
6824                                     0, "query restart")) {
6825                                 setResultCode(Activity.RESULT_OK);
6826                                 return;
6827                             }
6828                         }
6829                     }
6830                 }
6831             }
6832         }, pkgFilter);
6833
6834         IntentFilter dumpheapFilter = new IntentFilter();
6835         dumpheapFilter.addAction(DumpHeapActivity.ACTION_DELETE_DUMPHEAP);
6836         mContext.registerReceiver(new BroadcastReceiver() {
6837             @Override
6838             public void onReceive(Context context, Intent intent) {
6839                 if (intent.getBooleanExtra(DumpHeapActivity.EXTRA_DELAY_DELETE, false)) {
6840                     mHandler.sendEmptyMessageDelayed(POST_DUMP_HEAP_NOTIFICATION_MSG, 5*60*1000);
6841                 } else {
6842                     mHandler.sendEmptyMessage(POST_DUMP_HEAP_NOTIFICATION_MSG);
6843                 }
6844             }
6845         }, dumpheapFilter);
6846
6847         // Let system services know.
6848         mSystemServiceManager.startBootPhase(SystemService.PHASE_BOOT_COMPLETED);
6849
6850         synchronized (this) {
6851             // Ensure that any processes we had put on hold are now started
6852             // up.
6853             final int NP = mProcessesOnHold.size();
6854             if (NP > 0) {
6855                 ArrayList<ProcessRecord> procs =
6856                     new ArrayList<ProcessRecord>(mProcessesOnHold);
6857                 for (int ip=0; ip<NP; ip++) {
6858                     if (DEBUG_PROCESSES) Slog.v(TAG_PROCESSES, "Starting process on hold: "
6859                             + procs.get(ip));
6860                     startProcessLocked(procs.get(ip), "on-hold", null);
6861                 }
6862             }
6863
6864             if (mFactoryTest != FactoryTest.FACTORY_TEST_LOW_LEVEL) {
6865                 // Start looking for apps that are abusing wake locks.
6866                 Message nmsg = mHandler.obtainMessage(CHECK_EXCESSIVE_WAKE_LOCKS_MSG);
6867                 mHandler.sendMessageDelayed(nmsg, POWER_CHECK_DELAY);
6868                 // Tell anyone interested that we are done booting!
6869                 SystemProperties.set("sys.boot_completed", "1");
6870
6871                 // And trigger dev.bootcomplete if we are not showing encryption progress
6872                 if (!"trigger_restart_min_framework".equals(SystemProperties.get("vold.decrypt"))
6873                     || "".equals(SystemProperties.get("vold.encrypt_progress"))) {
6874                     SystemProperties.set("dev.bootcomplete", "1");
6875                 }
6876                 mUserController.sendBootCompletedLocked(
6877                         new IIntentReceiver.Stub() {
6878                             @Override
6879                             public void performReceive(Intent intent, int resultCode,
6880                                     String data, Bundle extras, boolean ordered,
6881                                     boolean sticky, int sendingUser) {
6882                                 synchronized (ActivityManagerService.this) {
6883                                     requestPssAllProcsLocked(SystemClock.uptimeMillis(),
6884                                             true, false);
6885                                 }
6886                             }
6887                         });
6888                 scheduleStartProfilesLocked();
6889             }
6890         }
6891     }
6892
6893     @Override
6894     public void bootAnimationComplete() {
6895         final boolean callFinishBooting;
6896         synchronized (this) {
6897             callFinishBooting = mCallFinishBooting;
6898             mBootAnimationComplete = true;
6899         }
6900         if (callFinishBooting) {
6901             Trace.traceBegin(Trace.TRACE_TAG_ACTIVITY_MANAGER, "FinishBooting");
6902             finishBooting();
6903             Trace.traceEnd(Trace.TRACE_TAG_ACTIVITY_MANAGER);
6904         }
6905     }
6906
6907     final void ensureBootCompleted() {
6908         boolean booting;
6909         boolean enableScreen;
6910         synchronized (this) {
6911             booting = mBooting;
6912             mBooting = false;
6913             enableScreen = !mBooted;
6914             mBooted = true;
6915         }
6916
6917         if (booting) {
6918             Trace.traceBegin(Trace.TRACE_TAG_ACTIVITY_MANAGER, "FinishBooting");
6919             finishBooting();
6920             Trace.traceEnd(Trace.TRACE_TAG_ACTIVITY_MANAGER);
6921         }
6922
6923         if (enableScreen) {
6924             enableScreenAfterBoot();
6925         }
6926     }
6927
6928     @Override
6929     public final void activityResumed(IBinder token) {
6930         final long origId = Binder.clearCallingIdentity();
6931         synchronized(this) {
6932             ActivityStack stack = ActivityRecord.getStackLocked(token);
6933             if (stack != null) {
6934                 stack.activityResumedLocked(token);
6935             }
6936         }
6937         Binder.restoreCallingIdentity(origId);
6938     }
6939
6940     @Override
6941     public final void activityPaused(IBinder token) {
6942         final long origId = Binder.clearCallingIdentity();
6943         synchronized(this) {
6944             ActivityStack stack = ActivityRecord.getStackLocked(token);
6945             if (stack != null) {
6946                 stack.activityPausedLocked(token, false);
6947             }
6948         }
6949         Binder.restoreCallingIdentity(origId);
6950     }
6951
6952     @Override
6953     public final void activityStopped(IBinder token, Bundle icicle,
6954             PersistableBundle persistentState, CharSequence description) {
6955         if (DEBUG_ALL) Slog.v(TAG, "Activity stopped: token=" + token);
6956
6957         // Refuse possible leaked file descriptors
6958         if (icicle != null && icicle.hasFileDescriptors()) {
6959             throw new IllegalArgumentException("File descriptors passed in Bundle");
6960         }
6961
6962         final long origId = Binder.clearCallingIdentity();
6963
6964         synchronized (this) {
6965             ActivityRecord r = ActivityRecord.isInStackLocked(token);
6966             if (r != null) {
6967                 r.task.stack.activityStoppedLocked(r, icicle, persistentState, description);
6968             }
6969         }
6970
6971         trimApplications();
6972
6973         Binder.restoreCallingIdentity(origId);
6974     }
6975
6976     @Override
6977     public final void activityDestroyed(IBinder token) {
6978         if (DEBUG_SWITCH) Slog.v(TAG_SWITCH, "ACTIVITY DESTROYED: " + token);
6979         synchronized (this) {
6980             ActivityStack stack = ActivityRecord.getStackLocked(token);
6981             if (stack != null) {
6982                 stack.activityDestroyedLocked(token, "activityDestroyed");
6983             }
6984         }
6985     }
6986
6987     @Override
6988     public final void activityRelaunched(IBinder token) {
6989         final long origId = Binder.clearCallingIdentity();
6990         synchronized (this) {
6991             mStackSupervisor.activityRelaunchedLocked(token);
6992         }
6993         Binder.restoreCallingIdentity(origId);
6994     }
6995
6996     @Override
6997     public void reportSizeConfigurations(IBinder token, int[] horizontalSizeConfiguration,
6998             int[] verticalSizeConfigurations, int[] smallestSizeConfigurations) {
6999         if (DEBUG_CONFIGURATION) Slog.v(TAG, "Report configuration: " + token + " "
7000                 + horizontalSizeConfiguration + " " + verticalSizeConfigurations);
7001         synchronized (this) {
7002             ActivityRecord record = ActivityRecord.isInStackLocked(token);
7003             if (record == null) {
7004                 throw new IllegalArgumentException("reportSizeConfigurations: ActivityRecord not "
7005                         + "found for: " + token);
7006             }
7007             record.setSizeConfigurations(horizontalSizeConfiguration,
7008                     verticalSizeConfigurations, smallestSizeConfigurations);
7009         }
7010     }
7011
7012     @Override
7013     public final void backgroundResourcesReleased(IBinder token) {
7014         final long origId = Binder.clearCallingIdentity();
7015         try {
7016             synchronized (this) {
7017                 ActivityStack stack = ActivityRecord.getStackLocked(token);
7018                 if (stack != null) {
7019                     stack.backgroundResourcesReleased();
7020                 }
7021             }
7022         } finally {
7023             Binder.restoreCallingIdentity(origId);
7024         }
7025     }
7026
7027     @Override
7028     public final void notifyLaunchTaskBehindComplete(IBinder token) {
7029         mStackSupervisor.scheduleLaunchTaskBehindComplete(token);
7030     }
7031
7032     @Override
7033     public final void notifyEnterAnimationComplete(IBinder token) {
7034         mHandler.sendMessage(mHandler.obtainMessage(ENTER_ANIMATION_COMPLETE_MSG, token));
7035     }
7036
7037     @Override
7038     public String getCallingPackage(IBinder token) {
7039         synchronized (this) {
7040             ActivityRecord r = getCallingRecordLocked(token);
7041             return r != null ? r.info.packageName : null;
7042         }
7043     }
7044
7045     @Override
7046     public ComponentName getCallingActivity(IBinder token) {
7047         synchronized (this) {
7048             ActivityRecord r = getCallingRecordLocked(token);
7049             return r != null ? r.intent.getComponent() : null;
7050         }
7051     }
7052
7053     private ActivityRecord getCallingRecordLocked(IBinder token) {
7054         ActivityRecord r = ActivityRecord.isInStackLocked(token);
7055         if (r == null) {
7056             return null;
7057         }
7058         return r.resultTo;
7059     }
7060
7061     @Override
7062     public ComponentName getActivityClassForToken(IBinder token) {
7063         synchronized(this) {
7064             ActivityRecord r = ActivityRecord.isInStackLocked(token);
7065             if (r == null) {
7066                 return null;
7067             }
7068             return r.intent.getComponent();
7069         }
7070     }
7071
7072     @Override
7073     public String getPackageForToken(IBinder token) {
7074         synchronized(this) {
7075             ActivityRecord r = ActivityRecord.isInStackLocked(token);
7076             if (r == null) {
7077                 return null;
7078             }
7079             return r.packageName;
7080         }
7081     }
7082
7083     @Override
7084     public boolean isRootVoiceInteraction(IBinder token) {
7085         synchronized(this) {
7086             ActivityRecord r = ActivityRecord.isInStackLocked(token);
7087             if (r == null) {
7088                 return false;
7089             }
7090             return r.rootVoiceInteraction;
7091         }
7092     }
7093
7094     @Override
7095     public IIntentSender getIntentSender(int type,
7096             String packageName, IBinder token, String resultWho,
7097             int requestCode, Intent[] intents, String[] resolvedTypes,
7098             int flags, Bundle bOptions, int userId) {
7099         enforceNotIsolatedCaller("getIntentSender");
7100         // Refuse possible leaked file descriptors
7101         if (intents != null) {
7102             if (intents.length < 1) {
7103                 throw new IllegalArgumentException("Intents array length must be >= 1");
7104             }
7105             for (int i=0; i<intents.length; i++) {
7106                 Intent intent = intents[i];
7107                 if (intent != null) {
7108                     if (intent.hasFileDescriptors()) {
7109                         throw new IllegalArgumentException("File descriptors passed in Intent");
7110                     }
7111                     if (type == ActivityManager.INTENT_SENDER_BROADCAST &&
7112                             (intent.getFlags()&Intent.FLAG_RECEIVER_BOOT_UPGRADE) != 0) {
7113                         throw new IllegalArgumentException(
7114                                 "Can't use FLAG_RECEIVER_BOOT_UPGRADE here");
7115                     }
7116                     intents[i] = new Intent(intent);
7117                 }
7118             }
7119             if (resolvedTypes != null && resolvedTypes.length != intents.length) {
7120                 throw new IllegalArgumentException(
7121                         "Intent array length does not match resolvedTypes length");
7122             }
7123         }
7124         if (bOptions != null) {
7125             if (bOptions.hasFileDescriptors()) {
7126                 throw new IllegalArgumentException("File descriptors passed in options");
7127             }
7128         }
7129
7130         synchronized(this) {
7131             int callingUid = Binder.getCallingUid();
7132             int origUserId = userId;
7133             userId = mUserController.handleIncomingUser(Binder.getCallingPid(), callingUid, userId,
7134                     type == ActivityManager.INTENT_SENDER_BROADCAST,
7135                     ALLOW_NON_FULL, "getIntentSender", null);
7136             if (origUserId == UserHandle.USER_CURRENT) {
7137                 // We don't want to evaluate this until the pending intent is
7138                 // actually executed.  However, we do want to always do the
7139                 // security checking for it above.
7140                 userId = UserHandle.USER_CURRENT;
7141             }
7142             try {
7143                 if (callingUid != 0 && callingUid != Process.SYSTEM_UID) {
7144                     final int uid = AppGlobals.getPackageManager().getPackageUid(packageName,
7145                             MATCH_DEBUG_TRIAGED_MISSING, UserHandle.getUserId(callingUid));
7146                     if (!UserHandle.isSameApp(callingUid, uid)) {
7147                         String msg = "Permission Denial: getIntentSender() from pid="
7148                             + Binder.getCallingPid()
7149                             + ", uid=" + Binder.getCallingUid()
7150                             + ", (need uid=" + uid + ")"
7151                             + " is not allowed to send as package " + packageName;
7152                         Slog.w(TAG, msg);
7153                         throw new SecurityException(msg);
7154                     }
7155                 }
7156
7157                 return getIntentSenderLocked(type, packageName, callingUid, userId,
7158                         token, resultWho, requestCode, intents, resolvedTypes, flags, bOptions);
7159
7160             } catch (RemoteException e) {
7161                 throw new SecurityException(e);
7162             }
7163         }
7164     }
7165
7166     IIntentSender getIntentSenderLocked(int type, String packageName,
7167             int callingUid, int userId, IBinder token, String resultWho,
7168             int requestCode, Intent[] intents, String[] resolvedTypes, int flags,
7169             Bundle bOptions) {
7170         if (DEBUG_MU) Slog.v(TAG_MU, "getIntentSenderLocked(): uid=" + callingUid);
7171         ActivityRecord activity = null;
7172         if (type == ActivityManager.INTENT_SENDER_ACTIVITY_RESULT) {
7173             activity = ActivityRecord.isInStackLocked(token);
7174             if (activity == null) {
7175                 Slog.w(TAG, "Failed createPendingResult: activity " + token + " not in any stack");
7176                 return null;
7177             }
7178             if (activity.finishing) {
7179                 Slog.w(TAG, "Failed createPendingResult: activity " + activity + " is finishing");
7180                 return null;
7181             }
7182         }
7183
7184         // We're going to be splicing together extras before sending, so we're
7185         // okay poking into any contained extras.
7186         if (intents != null) {
7187             for (int i = 0; i < intents.length; i++) {
7188                 intents[i].setDefusable(true);
7189             }
7190         }
7191         Bundle.setDefusable(bOptions, true);
7192
7193         final boolean noCreate = (flags&PendingIntent.FLAG_NO_CREATE) != 0;
7194         final boolean cancelCurrent = (flags&PendingIntent.FLAG_CANCEL_CURRENT) != 0;
7195         final boolean updateCurrent = (flags&PendingIntent.FLAG_UPDATE_CURRENT) != 0;
7196         flags &= ~(PendingIntent.FLAG_NO_CREATE|PendingIntent.FLAG_CANCEL_CURRENT
7197                 |PendingIntent.FLAG_UPDATE_CURRENT);
7198
7199         PendingIntentRecord.Key key = new PendingIntentRecord.Key(
7200                 type, packageName, activity, resultWho,
7201                 requestCode, intents, resolvedTypes, flags, bOptions, userId);
7202         WeakReference<PendingIntentRecord> ref;
7203         ref = mIntentSenderRecords.get(key);
7204         PendingIntentRecord rec = ref != null ? ref.get() : null;
7205         if (rec != null) {
7206             if (!cancelCurrent) {
7207                 if (updateCurrent) {
7208                     if (rec.key.requestIntent != null) {
7209                         rec.key.requestIntent.replaceExtras(intents != null ?
7210                                 intents[intents.length - 1] : null);
7211                     }
7212                     if (intents != null) {
7213                         intents[intents.length-1] = rec.key.requestIntent;
7214                         rec.key.allIntents = intents;
7215                         rec.key.allResolvedTypes = resolvedTypes;
7216                     } else {
7217                         rec.key.allIntents = null;
7218                         rec.key.allResolvedTypes = null;
7219                     }
7220                 }
7221                 return rec;
7222             }
7223             rec.canceled = true;
7224             mIntentSenderRecords.remove(key);
7225         }
7226         if (noCreate) {
7227             return rec;
7228         }
7229         rec = new PendingIntentRecord(this, key, callingUid);
7230         mIntentSenderRecords.put(key, rec.ref);
7231         if (type == ActivityManager.INTENT_SENDER_ACTIVITY_RESULT) {
7232             if (activity.pendingResults == null) {
7233                 activity.pendingResults
7234                         = new HashSet<WeakReference<PendingIntentRecord>>();
7235             }
7236             activity.pendingResults.add(rec.ref);
7237         }
7238         return rec;
7239     }
7240
7241     @Override
7242     public int sendIntentSender(IIntentSender target, int code, Intent intent, String resolvedType,
7243             IIntentReceiver finishedReceiver, String requiredPermission, Bundle options) {
7244         if (target instanceof PendingIntentRecord) {
7245             return ((PendingIntentRecord)target).sendWithResult(code, intent, resolvedType,
7246                     finishedReceiver, requiredPermission, options);
7247         } else {
7248             if (intent == null) {
7249                 // Weird case: someone has given us their own custom IIntentSender, and now
7250                 // they have someone else trying to send to it but of course this isn't
7251                 // really a PendingIntent, so there is no base Intent, and the caller isn't
7252                 // supplying an Intent... but we never want to dispatch a null Intent to
7253                 // a receiver, so um...  let's make something up.
7254                 Slog.wtf(TAG, "Can't use null intent with direct IIntentSender call");
7255                 intent = new Intent(Intent.ACTION_MAIN);
7256             }
7257             try {
7258                 target.send(code, intent, resolvedType, null, requiredPermission, options);
7259             } catch (RemoteException e) {
7260             }
7261             // Platform code can rely on getting a result back when the send is done, but if
7262             // this intent sender is from outside of the system we can't rely on it doing that.
7263             // So instead we don't give it the result receiver, and instead just directly
7264             // report the finish immediately.
7265             if (finishedReceiver != null) {
7266                 try {
7267                     finishedReceiver.performReceive(intent, 0,
7268                             null, null, false, false, UserHandle.getCallingUserId());
7269                 } catch (RemoteException e) {
7270                 }
7271             }
7272             return 0;
7273         }
7274     }
7275
7276     /**
7277      * Whitelists {@code targetUid} to temporarily bypass Power Save mode.
7278      *
7279      * <p>{@code callerUid} must be allowed to request such whitelist by calling
7280      * {@link #addTempPowerSaveWhitelistGrantorUid(int)}.
7281      */
7282     void tempWhitelistAppForPowerSave(int callerPid, int callerUid, int targetUid, long duration) {
7283         if (DEBUG_WHITELISTS) {
7284             Slog.d(TAG, "tempWhitelistAppForPowerSave(" + callerPid + ", " + callerUid + ", "
7285                     + targetUid + ", " + duration + ")");
7286         }
7287         synchronized (mPidsSelfLocked) {
7288             final ProcessRecord pr = mPidsSelfLocked.get(callerPid);
7289             if (pr == null) {
7290                 Slog.w(TAG, "tempWhitelistAppForPowerSave() no ProcessRecord for pid " + callerPid);
7291                 return;
7292             }
7293             if (!pr.whitelistManager) {
7294                 if (DEBUG_WHITELISTS) {
7295                     Slog.d(TAG, "tempWhitelistAppForPowerSave() for target " + targetUid + ": pid "
7296                             + callerPid + " is not allowed");
7297                 }
7298                 return;
7299             }
7300         }
7301
7302         final long token = Binder.clearCallingIdentity();
7303         try {
7304             mLocalDeviceIdleController.addPowerSaveTempWhitelistAppDirect(targetUid, duration,
7305                     true, "pe from uid:" + callerUid);
7306         } finally {
7307             Binder.restoreCallingIdentity(token);
7308         }
7309     }
7310
7311     @Override
7312     public void cancelIntentSender(IIntentSender sender) {
7313         if (!(sender instanceof PendingIntentRecord)) {
7314             return;
7315         }
7316         synchronized(this) {
7317             PendingIntentRecord rec = (PendingIntentRecord)sender;
7318             try {
7319                 final int uid = AppGlobals.getPackageManager().getPackageUid(rec.key.packageName,
7320                         MATCH_DEBUG_TRIAGED_MISSING, UserHandle.getCallingUserId());
7321                 if (!UserHandle.isSameApp(uid, Binder.getCallingUid())) {
7322                     String msg = "Permission Denial: cancelIntentSender() from pid="
7323                         + Binder.getCallingPid()
7324                         + ", uid=" + Binder.getCallingUid()
7325                         + " is not allowed to cancel packges "
7326                         + rec.key.packageName;
7327                     Slog.w(TAG, msg);
7328                     throw new SecurityException(msg);
7329                 }
7330             } catch (RemoteException e) {
7331                 throw new SecurityException(e);
7332             }
7333             cancelIntentSenderLocked(rec, true);
7334         }
7335     }
7336
7337     void cancelIntentSenderLocked(PendingIntentRecord rec, boolean cleanActivity) {
7338         rec.canceled = true;
7339         mIntentSenderRecords.remove(rec.key);
7340         if (cleanActivity && rec.key.activity != null) {
7341             rec.key.activity.pendingResults.remove(rec.ref);
7342         }
7343     }
7344
7345     @Override
7346     public String getPackageForIntentSender(IIntentSender pendingResult) {
7347         if (!(pendingResult instanceof PendingIntentRecord)) {
7348             return null;
7349         }
7350         try {
7351             PendingIntentRecord res = (PendingIntentRecord)pendingResult;
7352             return res.key.packageName;
7353         } catch (ClassCastException e) {
7354         }
7355         return null;
7356     }
7357
7358     @Override
7359     public int getUidForIntentSender(IIntentSender sender) {
7360         if (sender instanceof PendingIntentRecord) {
7361             try {
7362                 PendingIntentRecord res = (PendingIntentRecord)sender;
7363                 return res.uid;
7364             } catch (ClassCastException e) {
7365             }
7366         }
7367         return -1;
7368     }
7369
7370     @Override
7371     public boolean isIntentSenderTargetedToPackage(IIntentSender pendingResult) {
7372         if (!(pendingResult instanceof PendingIntentRecord)) {
7373             return false;
7374         }
7375         try {
7376             PendingIntentRecord res = (PendingIntentRecord)pendingResult;
7377             if (res.key.allIntents == null) {
7378                 return false;
7379             }
7380             for (int i=0; i<res.key.allIntents.length; i++) {
7381                 Intent intent = res.key.allIntents[i];
7382                 if (intent.getPackage() != null && intent.getComponent() != null) {
7383                     return false;
7384                 }
7385             }
7386             return true;
7387         } catch (ClassCastException e) {
7388         }
7389         return false;
7390     }
7391
7392     @Override
7393     public boolean isIntentSenderAnActivity(IIntentSender pendingResult) {
7394         if (!(pendingResult instanceof PendingIntentRecord)) {
7395             return false;
7396         }
7397         try {
7398             PendingIntentRecord res = (PendingIntentRecord)pendingResult;
7399             if (res.key.type == ActivityManager.INTENT_SENDER_ACTIVITY) {
7400                 return true;
7401             }
7402             return false;
7403         } catch (ClassCastException e) {
7404         }
7405         return false;
7406     }
7407
7408     @Override
7409     public Intent getIntentForIntentSender(IIntentSender pendingResult) {
7410         enforceCallingPermission(Manifest.permission.GET_INTENT_SENDER_INTENT,
7411                 "getIntentForIntentSender()");
7412         if (!(pendingResult instanceof PendingIntentRecord)) {
7413             return null;
7414         }
7415         try {
7416             PendingIntentRecord res = (PendingIntentRecord)pendingResult;
7417             return res.key.requestIntent != null ? new Intent(res.key.requestIntent) : null;
7418         } catch (ClassCastException e) {
7419         }
7420         return null;
7421     }
7422
7423     @Override
7424     public String getTagForIntentSender(IIntentSender pendingResult, String prefix) {
7425         if (!(pendingResult instanceof PendingIntentRecord)) {
7426             return null;
7427         }
7428         try {
7429             PendingIntentRecord res = (PendingIntentRecord)pendingResult;
7430             synchronized (this) {
7431                 return getTagForIntentSenderLocked(res, prefix);
7432             }
7433         } catch (ClassCastException e) {
7434         }
7435         return null;
7436     }
7437
7438     String getTagForIntentSenderLocked(PendingIntentRecord res, String prefix) {
7439         final Intent intent = res.key.requestIntent;
7440         if (intent != null) {
7441             if (res.lastTag != null && res.lastTagPrefix == prefix && (res.lastTagPrefix == null
7442                     || res.lastTagPrefix.equals(prefix))) {
7443                 return res.lastTag;
7444             }
7445             res.lastTagPrefix = prefix;
7446             final StringBuilder sb = new StringBuilder(128);
7447             if (prefix != null) {
7448                 sb.append(prefix);
7449             }
7450             if (intent.getAction() != null) {
7451                 sb.append(intent.getAction());
7452             } else if (intent.getComponent() != null) {
7453                 intent.getComponent().appendShortString(sb);
7454             } else {
7455                 sb.append("?");
7456             }
7457             return res.lastTag = sb.toString();
7458         }
7459         return null;
7460     }
7461
7462     @Override
7463     public void setProcessLimit(int max) {
7464         enforceCallingPermission(android.Manifest.permission.SET_PROCESS_LIMIT,
7465                 "setProcessLimit()");
7466         synchronized (this) {
7467             mProcessLimit = max < 0 ? ProcessList.MAX_CACHED_APPS : max;
7468             mProcessLimitOverride = max;
7469         }
7470         trimApplications();
7471     }
7472
7473     @Override
7474     public int getProcessLimit() {
7475         synchronized (this) {
7476             return mProcessLimitOverride;
7477         }
7478     }
7479
7480     void foregroundTokenDied(ForegroundToken token) {
7481         synchronized (ActivityManagerService.this) {
7482             synchronized (mPidsSelfLocked) {
7483                 ForegroundToken cur
7484                     = mForegroundProcesses.get(token.pid);
7485                 if (cur != token) {
7486                     return;
7487                 }
7488                 mForegroundProcesses.remove(token.pid);
7489                 ProcessRecord pr = mPidsSelfLocked.get(token.pid);
7490                 if (pr == null) {
7491                     return;
7492                 }
7493                 pr.forcingToForeground = null;
7494                 updateProcessForegroundLocked(pr, false, false);
7495             }
7496             updateOomAdjLocked();
7497         }
7498     }
7499
7500     @Override
7501     public void setProcessForeground(IBinder token, int pid, boolean isForeground) {
7502         enforceCallingPermission(android.Manifest.permission.SET_PROCESS_LIMIT,
7503                 "setProcessForeground()");
7504         synchronized(this) {
7505             boolean changed = false;
7506
7507             synchronized (mPidsSelfLocked) {
7508                 ProcessRecord pr = mPidsSelfLocked.get(pid);
7509                 if (pr == null && isForeground) {
7510                     Slog.w(TAG, "setProcessForeground called on unknown pid: " + pid);
7511                     return;
7512                 }
7513                 ForegroundToken oldToken = mForegroundProcesses.get(pid);
7514                 if (oldToken != null) {
7515                     oldToken.token.unlinkToDeath(oldToken, 0);
7516                     mForegroundProcesses.remove(pid);
7517                     if (pr != null) {
7518                         pr.forcingToForeground = null;
7519                     }
7520                     changed = true;
7521                 }
7522                 if (isForeground && token != null) {
7523                     ForegroundToken newToken = new ForegroundToken() {
7524                         @Override
7525                         public void binderDied() {
7526                             foregroundTokenDied(this);
7527                         }
7528                     };
7529                     newToken.pid = pid;
7530                     newToken.token = token;
7531                     try {
7532                         token.linkToDeath(newToken, 0);
7533                         mForegroundProcesses.put(pid, newToken);
7534                         pr.forcingToForeground = token;
7535                         changed = true;
7536                     } catch (RemoteException e) {
7537                         // If the process died while doing this, we will later
7538                         // do the cleanup with the process death link.
7539                     }
7540                 }
7541             }
7542
7543             if (changed) {
7544                 updateOomAdjLocked();
7545             }
7546         }
7547     }
7548
7549     @Override
7550     public boolean isAppForeground(int uid) throws RemoteException {
7551         synchronized (this) {
7552             UidRecord uidRec = mActiveUids.get(uid);
7553             if (uidRec == null || uidRec.idle) {
7554                 return false;
7555             }
7556             return uidRec.curProcState <= ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND;
7557         }
7558     }
7559
7560     // NOTE: this is an internal method used by the OnShellCommand implementation only and should
7561     // be guarded by permission checking.
7562     int getUidState(int uid) {
7563         synchronized (this) {
7564             UidRecord uidRec = mActiveUids.get(uid);
7565             return uidRec == null ? ActivityManager.PROCESS_STATE_NONEXISTENT : uidRec.curProcState;
7566         }
7567     }
7568
7569     @Override
7570     public boolean isInMultiWindowMode(IBinder token) {
7571         final long origId = Binder.clearCallingIdentity();
7572         try {
7573             synchronized(this) {
7574                 final ActivityRecord r = ActivityRecord.isInStackLocked(token);
7575                 if (r == null) {
7576                     return false;
7577                 }
7578                 // An activity is consider to be in multi-window mode if its task isn't fullscreen.
7579                 return !r.task.mFullscreen;
7580             }
7581         } finally {
7582             Binder.restoreCallingIdentity(origId);
7583         }
7584     }
7585
7586     @Override
7587     public boolean isInPictureInPictureMode(IBinder token) {
7588         final long origId = Binder.clearCallingIdentity();
7589         try {
7590             synchronized(this) {
7591                 final ActivityStack stack = ActivityRecord.getStackLocked(token);
7592                 if (stack == null) {
7593                     return false;
7594                 }
7595                 return stack.mStackId == PINNED_STACK_ID;
7596             }
7597         } finally {
7598             Binder.restoreCallingIdentity(origId);
7599         }
7600     }
7601
7602     @Override
7603     public void enterPictureInPictureMode(IBinder token) {
7604         final long origId = Binder.clearCallingIdentity();
7605         try {
7606             synchronized(this) {
7607                 if (!mSupportsPictureInPicture) {
7608                     throw new IllegalStateException("enterPictureInPictureMode: "
7609                             + "Device doesn't support picture-in-picture mode.");
7610                 }
7611
7612                 final ActivityRecord r = ActivityRecord.forTokenLocked(token);
7613
7614                 if (r == null) {
7615                     throw new IllegalStateException("enterPictureInPictureMode: "
7616                             + "Can't find activity for token=" + token);
7617                 }
7618
7619                 if (!r.supportsPictureInPicture()) {
7620                     throw new IllegalArgumentException("enterPictureInPictureMode: "
7621                             + "Picture-In-Picture not supported for r=" + r);
7622                 }
7623
7624                 // Use the default launch bounds for pinned stack if it doesn't exist yet or use the
7625                 // current bounds.
7626                 final ActivityStack pinnedStack = mStackSupervisor.getStack(PINNED_STACK_ID);
7627                 final Rect bounds = (pinnedStack != null)
7628                         ? pinnedStack.mBounds : mDefaultPinnedStackBounds;
7629
7630                 mStackSupervisor.moveActivityToPinnedStackLocked(
7631                         r, "enterPictureInPictureMode", bounds);
7632             }
7633         } finally {
7634             Binder.restoreCallingIdentity(origId);
7635         }
7636     }
7637
7638     // =========================================================
7639     // PROCESS INFO
7640     // =========================================================
7641
7642     static class ProcessInfoService extends IProcessInfoService.Stub {
7643         final ActivityManagerService mActivityManagerService;
7644         ProcessInfoService(ActivityManagerService activityManagerService) {
7645             mActivityManagerService = activityManagerService;
7646         }
7647
7648         @Override
7649         public void getProcessStatesFromPids(/*in*/ int[] pids, /*out*/ int[] states) {
7650             mActivityManagerService.getProcessStatesAndOomScoresForPIDs(
7651                     /*in*/ pids, /*out*/ states, null);
7652         }
7653
7654         @Override
7655         public void getProcessStatesAndOomScoresFromPids(
7656                 /*in*/ int[] pids, /*out*/ int[] states, /*out*/ int[] scores) {
7657             mActivityManagerService.getProcessStatesAndOomScoresForPIDs(
7658                     /*in*/ pids, /*out*/ states, /*out*/ scores);
7659         }
7660     }
7661
7662     /**
7663      * For each PID in the given input array, write the current process state
7664      * for that process into the states array, or -1 to indicate that no
7665      * process with the given PID exists. If scores array is provided, write
7666      * the oom score for the process into the scores array, with INVALID_ADJ
7667      * indicating the PID doesn't exist.
7668      */
7669     public void getProcessStatesAndOomScoresForPIDs(
7670             /*in*/ int[] pids, /*out*/ int[] states, /*out*/ int[] scores) {
7671         if (scores != null) {
7672             enforceCallingPermission(android.Manifest.permission.GET_PROCESS_STATE_AND_OOM_SCORE,
7673                     "getProcessStatesAndOomScoresForPIDs()");
7674         }
7675
7676         if (pids == null) {
7677             throw new NullPointerException("pids");
7678         } else if (states == null) {
7679             throw new NullPointerException("states");
7680         } else if (pids.length != states.length) {
7681             throw new IllegalArgumentException("pids and states arrays have different lengths!");
7682         } else if (scores != null && pids.length != scores.length) {
7683             throw new IllegalArgumentException("pids and scores arrays have different lengths!");
7684         }
7685
7686         synchronized (mPidsSelfLocked) {
7687             for (int i = 0; i < pids.length; i++) {
7688                 ProcessRecord pr = mPidsSelfLocked.get(pids[i]);
7689                 states[i] = (pr == null) ? ActivityManager.PROCESS_STATE_NONEXISTENT :
7690                         pr.curProcState;
7691                 if (scores != null) {
7692                     scores[i] = (pr == null) ? ProcessList.INVALID_ADJ : pr.curAdj;
7693                 }
7694             }
7695         }
7696     }
7697
7698     // =========================================================
7699     // PERMISSIONS
7700     // =========================================================
7701
7702     static class PermissionController extends IPermissionController.Stub {
7703         ActivityManagerService mActivityManagerService;
7704         PermissionController(ActivityManagerService activityManagerService) {
7705             mActivityManagerService = activityManagerService;
7706         }
7707
7708         @Override
7709         public boolean checkPermission(String permission, int pid, int uid) {
7710             return mActivityManagerService.checkPermission(permission, pid,
7711                     uid) == PackageManager.PERMISSION_GRANTED;
7712         }
7713
7714         @Override
7715         public String[] getPackagesForUid(int uid) {
7716             return mActivityManagerService.mContext.getPackageManager()
7717                     .getPackagesForUid(uid);
7718         }
7719
7720         @Override
7721         public boolean isRuntimePermission(String permission) {
7722             try {
7723                 PermissionInfo info = mActivityManagerService.mContext.getPackageManager()
7724                         .getPermissionInfo(permission, 0);
7725                 return info.protectionLevel == PermissionInfo.PROTECTION_DANGEROUS;
7726             } catch (NameNotFoundException nnfe) {
7727                 Slog.e(TAG, "No such permission: "+ permission, nnfe);
7728             }
7729             return false;
7730         }
7731     }
7732
7733     class IntentFirewallInterface implements IntentFirewall.AMSInterface {
7734         @Override
7735         public int checkComponentPermission(String permission, int pid, int uid,
7736                 int owningUid, boolean exported) {
7737             return ActivityManagerService.this.checkComponentPermission(permission, pid, uid,
7738                     owningUid, exported);
7739         }
7740
7741         @Override
7742         public Object getAMSLock() {
7743             return ActivityManagerService.this;
7744         }
7745     }
7746
7747     /**
7748      * This can be called with or without the global lock held.
7749      */
7750     int checkComponentPermission(String permission, int pid, int uid,
7751             int owningUid, boolean exported) {
7752         if (pid == MY_PID) {
7753             return PackageManager.PERMISSION_GRANTED;
7754         }
7755         return ActivityManager.checkComponentPermission(permission, uid,
7756                 owningUid, exported);
7757     }
7758
7759     /**
7760      * As the only public entry point for permissions checking, this method
7761      * can enforce the semantic that requesting a check on a null global
7762      * permission is automatically denied.  (Internally a null permission
7763      * string is used when calling {@link #checkComponentPermission} in cases
7764      * when only uid-based security is needed.)
7765      *
7766      * This can be called with or without the global lock held.
7767      */
7768     @Override
7769     public int checkPermission(String permission, int pid, int uid) {
7770         if (permission == null) {
7771             return PackageManager.PERMISSION_DENIED;
7772         }
7773         return checkComponentPermission(permission, pid, uid, -1, true);
7774     }
7775
7776     @Override
7777     public int checkPermissionWithToken(String permission, int pid, int uid, IBinder callerToken) {
7778         if (permission == null) {
7779             return PackageManager.PERMISSION_DENIED;
7780         }
7781
7782         // We might be performing an operation on behalf of an indirect binder
7783         // invocation, e.g. via {@link #openContentUri}.  Check and adjust the
7784         // client identity accordingly before proceeding.
7785         Identity tlsIdentity = sCallerIdentity.get();
7786         if (tlsIdentity != null && tlsIdentity.token == callerToken) {
7787             Slog.d(TAG, "checkComponentPermission() adjusting {pid,uid} to {"
7788                     + tlsIdentity.pid + "," + tlsIdentity.uid + "}");
7789             uid = tlsIdentity.uid;
7790             pid = tlsIdentity.pid;
7791         }
7792
7793         return checkComponentPermission(permission, pid, uid, -1, true);
7794     }
7795
7796     /**
7797      * Binder IPC calls go through the public entry point.
7798      * This can be called with or without the global lock held.
7799      */
7800     int checkCallingPermission(String permission) {
7801         return checkPermission(permission,
7802                 Binder.getCallingPid(),
7803                 UserHandle.getAppId(Binder.getCallingUid()));
7804     }
7805
7806     /**
7807      * This can be called with or without the global lock held.
7808      */
7809     void enforceCallingPermission(String permission, String func) {
7810         if (checkCallingPermission(permission)
7811                 == PackageManager.PERMISSION_GRANTED) {
7812             return;
7813         }
7814
7815         String msg = "Permission Denial: " + func + " from pid="
7816                 + Binder.getCallingPid()
7817                 + ", uid=" + Binder.getCallingUid()
7818                 + " requires " + permission;
7819         Slog.w(TAG, msg);
7820         throw new SecurityException(msg);
7821     }
7822
7823     /**
7824      * Determine if UID is holding permissions required to access {@link Uri} in
7825      * the given {@link ProviderInfo}. Final permission checking is always done
7826      * in {@link ContentProvider}.
7827      */
7828     private final boolean checkHoldingPermissionsLocked(
7829             IPackageManager pm, ProviderInfo pi, GrantUri grantUri, int uid, final int modeFlags) {
7830         if (DEBUG_URI_PERMISSION) Slog.v(TAG_URI_PERMISSION,
7831                 "checkHoldingPermissionsLocked: uri=" + grantUri + " uid=" + uid);
7832         if (UserHandle.getUserId(uid) != grantUri.sourceUserId) {
7833             if (ActivityManager.checkComponentPermission(INTERACT_ACROSS_USERS, uid, -1, true)
7834                     != PERMISSION_GRANTED) {
7835                 return false;
7836             }
7837         }
7838         return checkHoldingPermissionsInternalLocked(pm, pi, grantUri, uid, modeFlags, true);
7839     }
7840
7841     private final boolean checkHoldingPermissionsInternalLocked(IPackageManager pm, ProviderInfo pi,
7842             GrantUri grantUri, int uid, final int modeFlags, boolean considerUidPermissions) {
7843         if (pi.applicationInfo.uid == uid) {
7844             return true;
7845         } else if (!pi.exported) {
7846             return false;
7847         }
7848
7849         boolean readMet = (modeFlags & Intent.FLAG_GRANT_READ_URI_PERMISSION) == 0;
7850         boolean writeMet = (modeFlags & Intent.FLAG_GRANT_WRITE_URI_PERMISSION) == 0;
7851         try {
7852             // check if target holds top-level <provider> permissions
7853             if (!readMet && pi.readPermission != null && considerUidPermissions
7854                     && (pm.checkUidPermission(pi.readPermission, uid) == PERMISSION_GRANTED)) {
7855                 readMet = true;
7856             }
7857             if (!writeMet && pi.writePermission != null && considerUidPermissions
7858                     && (pm.checkUidPermission(pi.writePermission, uid) == PERMISSION_GRANTED)) {
7859                 writeMet = true;
7860             }
7861
7862             // track if unprotected read/write is allowed; any denied
7863             // <path-permission> below removes this ability
7864             boolean allowDefaultRead = pi.readPermission == null;
7865             boolean allowDefaultWrite = pi.writePermission == null;
7866
7867             // check if target holds any <path-permission> that match uri
7868             final PathPermission[] pps = pi.pathPermissions;
7869             if (pps != null) {
7870                 final String path = grantUri.uri.getPath();
7871                 int i = pps.length;
7872                 while (i > 0 && (!readMet || !writeMet)) {
7873                     i--;
7874                     PathPermission pp = pps[i];
7875                     if (pp.match(path)) {
7876                         if (!readMet) {
7877                             final String pprperm = pp.getReadPermission();
7878                             if (DEBUG_URI_PERMISSION) Slog.v(TAG_URI_PERMISSION,
7879                                     "Checking read perm for " + pprperm + " for " + pp.getPath()
7880                                     + ": match=" + pp.match(path)
7881                                     + " check=" + pm.checkUidPermission(pprperm, uid));
7882                             if (pprperm != null) {
7883                                 if (considerUidPermissions && pm.checkUidPermission(pprperm, uid)
7884                                         == PERMISSION_GRANTED) {
7885                                     readMet = true;
7886                                 } else {
7887                                     allowDefaultRead = false;
7888                                 }
7889                             }
7890                         }
7891                         if (!writeMet) {
7892                             final String ppwperm = pp.getWritePermission();
7893                             if (DEBUG_URI_PERMISSION) Slog.v(TAG_URI_PERMISSION,
7894                                     "Checking write perm " + ppwperm + " for " + pp.getPath()
7895                                     + ": match=" + pp.match(path)
7896                                     + " check=" + pm.checkUidPermission(ppwperm, uid));
7897                             if (ppwperm != null) {
7898                                 if (considerUidPermissions && pm.checkUidPermission(ppwperm, uid)
7899                                         == PERMISSION_GRANTED) {
7900                                     writeMet = true;
7901                                 } else {
7902                                     allowDefaultWrite = false;
7903                                 }
7904                             }
7905                         }
7906                     }
7907                 }
7908             }
7909
7910             // grant unprotected <provider> read/write, if not blocked by
7911             // <path-permission> above
7912             if (allowDefaultRead) readMet = true;
7913             if (allowDefaultWrite) writeMet = true;
7914
7915         } catch (RemoteException e) {
7916             return false;
7917         }
7918
7919         return readMet && writeMet;
7920     }
7921
7922     public int getAppStartMode(int uid, String packageName) {
7923         synchronized (this) {
7924             return checkAllowBackgroundLocked(uid, packageName, -1, true);
7925         }
7926     }
7927
7928     int checkAllowBackgroundLocked(int uid, String packageName, int callingPid,
7929             boolean allowWhenForeground) {
7930         UidRecord uidRec = mActiveUids.get(uid);
7931         if (!mLenientBackgroundCheck) {
7932             if (!allowWhenForeground || uidRec == null
7933                     || uidRec.curProcState >= ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND) {
7934                 if (mAppOpsService.noteOperation(AppOpsManager.OP_RUN_IN_BACKGROUND, uid,
7935                         packageName) != AppOpsManager.MODE_ALLOWED) {
7936                     return ActivityManager.APP_START_MODE_DELAYED;
7937                 }
7938             }
7939
7940         } else if (uidRec == null || uidRec.idle) {
7941             if (callingPid >= 0) {
7942                 ProcessRecord proc;
7943                 synchronized (mPidsSelfLocked) {
7944                     proc = mPidsSelfLocked.get(callingPid);
7945                 }
7946                 if (proc != null && proc.curProcState < ActivityManager.PROCESS_STATE_RECEIVER) {
7947                     // Whoever is instigating this is in the foreground, so we will allow it
7948                     // to go through.
7949                     return ActivityManager.APP_START_MODE_NORMAL;
7950                 }
7951             }
7952             if (mAppOpsService.noteOperation(AppOpsManager.OP_RUN_IN_BACKGROUND, uid, packageName)
7953                     != AppOpsManager.MODE_ALLOWED) {
7954                 return ActivityManager.APP_START_MODE_DELAYED;
7955             }
7956         }
7957         return ActivityManager.APP_START_MODE_NORMAL;
7958     }
7959
7960     private ProviderInfo getProviderInfoLocked(String authority, int userHandle, int pmFlags) {
7961         ProviderInfo pi = null;
7962         ContentProviderRecord cpr = mProviderMap.getProviderByName(authority, userHandle);
7963         if (cpr != null) {
7964             pi = cpr.info;
7965         } else {
7966             try {
7967                 pi = AppGlobals.getPackageManager().resolveContentProvider(
7968                         authority, PackageManager.GET_URI_PERMISSION_PATTERNS | pmFlags,
7969                         userHandle);
7970             } catch (RemoteException ex) {
7971             }
7972         }
7973         return pi;
7974     }
7975
7976     private UriPermission findUriPermissionLocked(int targetUid, GrantUri grantUri) {
7977         final ArrayMap<GrantUri, UriPermission> targetUris = mGrantedUriPermissions.get(targetUid);
7978         if (targetUris != null) {
7979             return targetUris.get(grantUri);
7980         }
7981         return null;
7982     }
7983
7984     private UriPermission findOrCreateUriPermissionLocked(String sourcePkg,
7985             String targetPkg, int targetUid, GrantUri grantUri) {
7986         ArrayMap<GrantUri, UriPermission> targetUris = mGrantedUriPermissions.get(targetUid);
7987         if (targetUris == null) {
7988             targetUris = Maps.newArrayMap();
7989             mGrantedUriPermissions.put(targetUid, targetUris);
7990         }
7991
7992         UriPermission perm = targetUris.get(grantUri);
7993         if (perm == null) {
7994             perm = new UriPermission(sourcePkg, targetPkg, targetUid, grantUri);
7995             targetUris.put(grantUri, perm);
7996         }
7997
7998         return perm;
7999     }
8000
8001     private final boolean checkUriPermissionLocked(GrantUri grantUri, int uid,
8002             final int modeFlags) {
8003         final boolean persistable = (modeFlags & Intent.FLAG_GRANT_PERSISTABLE_URI_PERMISSION) != 0;
8004         final int minStrength = persistable ? UriPermission.STRENGTH_PERSISTABLE
8005                 : UriPermission.STRENGTH_OWNED;
8006
8007         // Root gets to do everything.
8008         if (uid == 0) {
8009             return true;
8010         }
8011
8012         final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.get(uid);
8013         if (perms == null) return false;
8014
8015         // First look for exact match
8016         final UriPermission exactPerm = perms.get(grantUri);
8017         if (exactPerm != null && exactPerm.getStrength(modeFlags) >= minStrength) {
8018             return true;
8019         }
8020
8021         // No exact match, look for prefixes
8022         final int N = perms.size();
8023         for (int i = 0; i < N; i++) {
8024             final UriPermission perm = perms.valueAt(i);
8025             if (perm.uri.prefix && grantUri.uri.isPathPrefixMatch(perm.uri.uri)
8026                     && perm.getStrength(modeFlags) >= minStrength) {
8027                 return true;
8028             }
8029         }
8030
8031         return false;
8032     }
8033
8034     /**
8035      * @param uri This uri must NOT contain an embedded userId.
8036      * @param userId The userId in which the uri is to be resolved.
8037      */
8038     @Override
8039     public int checkUriPermission(Uri uri, int pid, int uid,
8040             final int modeFlags, int userId, IBinder callerToken) {
8041         enforceNotIsolatedCaller("checkUriPermission");
8042
8043         // Another redirected-binder-call permissions check as in
8044         // {@link checkPermissionWithToken}.
8045         Identity tlsIdentity = sCallerIdentity.get();
8046         if (tlsIdentity != null && tlsIdentity.token == callerToken) {
8047             uid = tlsIdentity.uid;
8048             pid = tlsIdentity.pid;
8049         }
8050
8051         // Our own process gets to do everything.
8052         if (pid == MY_PID) {
8053             return PackageManager.PERMISSION_GRANTED;
8054         }
8055         synchronized (this) {
8056             return checkUriPermissionLocked(new GrantUri(userId, uri, false), uid, modeFlags)
8057                     ? PackageManager.PERMISSION_GRANTED
8058                     : PackageManager.PERMISSION_DENIED;
8059         }
8060     }
8061
8062     /**
8063      * Check if the targetPkg can be granted permission to access uri by
8064      * the callingUid using the given modeFlags.  Throws a security exception
8065      * if callingUid is not allowed to do this.  Returns the uid of the target
8066      * if the URI permission grant should be performed; returns -1 if it is not
8067      * needed (for example targetPkg already has permission to access the URI).
8068      * If you already know the uid of the target, you can supply it in
8069      * lastTargetUid else set that to -1.
8070      */
8071     int checkGrantUriPermissionLocked(int callingUid, String targetPkg, GrantUri grantUri,
8072             final int modeFlags, int lastTargetUid) {
8073         if (!Intent.isAccessUriMode(modeFlags)) {
8074             return -1;
8075         }
8076
8077         if (targetPkg != null) {
8078             if (DEBUG_URI_PERMISSION) Slog.v(TAG_URI_PERMISSION,
8079                     "Checking grant " + targetPkg + " permission to " + grantUri);
8080         }
8081
8082         final IPackageManager pm = AppGlobals.getPackageManager();
8083
8084         // If this is not a content: uri, we can't do anything with it.
8085         if (!ContentResolver.SCHEME_CONTENT.equals(grantUri.uri.getScheme())) {
8086             if (DEBUG_URI_PERMISSION) Slog.v(TAG_URI_PERMISSION,
8087                     "Can't grant URI permission for non-content URI: " + grantUri);
8088             return -1;
8089         }
8090
8091         final String authority = grantUri.uri.getAuthority();
8092         final ProviderInfo pi = getProviderInfoLocked(authority, grantUri.sourceUserId,
8093                 MATCH_DEBUG_TRIAGED_MISSING);
8094         if (pi == null) {
8095             Slog.w(TAG, "No content provider found for permission check: " +
8096                     grantUri.uri.toSafeString());
8097             return -1;
8098         }
8099
8100         int targetUid = lastTargetUid;
8101         if (targetUid < 0 && targetPkg != null) {
8102             try {
8103                 targetUid = pm.getPackageUid(targetPkg, MATCH_DEBUG_TRIAGED_MISSING,
8104                         UserHandle.getUserId(callingUid));
8105                 if (targetUid < 0) {
8106                     if (DEBUG_URI_PERMISSION) Slog.v(TAG_URI_PERMISSION,
8107                             "Can't grant URI permission no uid for: " + targetPkg);
8108                     return -1;
8109                 }
8110             } catch (RemoteException ex) {
8111                 return -1;
8112             }
8113         }
8114
8115         if (targetUid >= 0) {
8116             // First...  does the target actually need this permission?
8117             if (checkHoldingPermissionsLocked(pm, pi, grantUri, targetUid, modeFlags)) {
8118                 // No need to grant the target this permission.
8119                 if (DEBUG_URI_PERMISSION) Slog.v(TAG_URI_PERMISSION,
8120                         "Target " + targetPkg + " already has full permission to " + grantUri);
8121                 return -1;
8122             }
8123         } else {
8124             // First...  there is no target package, so can anyone access it?
8125             boolean allowed = pi.exported;
8126             if ((modeFlags&Intent.FLAG_GRANT_READ_URI_PERMISSION) != 0) {
8127                 if (pi.readPermission != null) {
8128                     allowed = false;
8129                 }
8130             }
8131             if ((modeFlags&Intent.FLAG_GRANT_WRITE_URI_PERMISSION) != 0) {
8132                 if (pi.writePermission != null) {
8133                     allowed = false;
8134                 }
8135             }
8136             if (allowed) {
8137                 return -1;
8138             }
8139         }
8140
8141         /* There is a special cross user grant if:
8142          * - The target is on another user.
8143          * - Apps on the current user can access the uri without any uid permissions.
8144          * In this case, we grant a uri permission, even if the ContentProvider does not normally
8145          * grant uri permissions.
8146          */
8147         boolean specialCrossUserGrant = UserHandle.getUserId(targetUid) != grantUri.sourceUserId
8148                 && checkHoldingPermissionsInternalLocked(pm, pi, grantUri, callingUid,
8149                 modeFlags, false /*without considering the uid permissions*/);
8150
8151         // Second...  is the provider allowing granting of URI permissions?
8152         if (!specialCrossUserGrant) {
8153             if (!pi.grantUriPermissions) {
8154                 throw new SecurityException("Provider " + pi.packageName
8155                         + "/" + pi.name
8156                         + " does not allow granting of Uri permissions (uri "
8157                         + grantUri + ")");
8158             }
8159             if (pi.uriPermissionPatterns != null) {
8160                 final int N = pi.uriPermissionPatterns.length;
8161                 boolean allowed = false;
8162                 for (int i=0; i<N; i++) {
8163                     if (pi.uriPermissionPatterns[i] != null
8164                             && pi.uriPermissionPatterns[i].match(grantUri.uri.getPath())) {
8165                         allowed = true;
8166                         break;
8167                     }
8168                 }
8169                 if (!allowed) {
8170                     throw new SecurityException("Provider " + pi.packageName
8171                             + "/" + pi.name
8172                             + " does not allow granting of permission to path of Uri "
8173                             + grantUri);
8174                 }
8175             }
8176         }
8177
8178         // Third...  does the caller itself have permission to access
8179         // this uri?
8180         final int callingAppId = UserHandle.getAppId(callingUid);
8181         if ((callingAppId == Process.SYSTEM_UID) || (callingAppId == Process.ROOT_UID)) {
8182             Slog.w(TAG, "For security reasons, the system cannot issue a Uri permission"
8183                     + " grant to " + grantUri + "; use startActivityAsCaller() instead");
8184             return -1;
8185         } else {
8186             if (!checkHoldingPermissionsLocked(pm, pi, grantUri, callingUid, modeFlags)) {
8187                 // Require they hold a strong enough Uri permission
8188                 if (!checkUriPermissionLocked(grantUri, callingUid, modeFlags)) {
8189                     throw new SecurityException("Uid " + callingUid
8190                             + " does not have permission to uri " + grantUri);
8191                 }
8192             }
8193         }
8194         return targetUid;
8195     }
8196
8197     /**
8198      * @param uri This uri must NOT contain an embedded userId.
8199      * @param userId The userId in which the uri is to be resolved.
8200      */
8201     @Override
8202     public int checkGrantUriPermission(int callingUid, String targetPkg, Uri uri,
8203             final int modeFlags, int userId) {
8204         enforceNotIsolatedCaller("checkGrantUriPermission");
8205         synchronized(this) {
8206             return checkGrantUriPermissionLocked(callingUid, targetPkg,
8207                     new GrantUri(userId, uri, false), modeFlags, -1);
8208         }
8209     }
8210
8211     void grantUriPermissionUncheckedLocked(int targetUid, String targetPkg, GrantUri grantUri,
8212             final int modeFlags, UriPermissionOwner owner) {
8213         if (!Intent.isAccessUriMode(modeFlags)) {
8214             return;
8215         }
8216
8217         // So here we are: the caller has the assumed permission
8218         // to the uri, and the target doesn't.  Let's now give this to
8219         // the target.
8220
8221         if (DEBUG_URI_PERMISSION) Slog.v(TAG_URI_PERMISSION,
8222                 "Granting " + targetPkg + "/" + targetUid + " permission to " + grantUri);
8223
8224         final String authority = grantUri.uri.getAuthority();
8225         final ProviderInfo pi = getProviderInfoLocked(authority, grantUri.sourceUserId,
8226                 MATCH_DEBUG_TRIAGED_MISSING);
8227         if (pi == null) {
8228             Slog.w(TAG, "No content provider found for grant: " + grantUri.toSafeString());
8229             return;
8230         }
8231
8232         if ((modeFlags & Intent.FLAG_GRANT_PREFIX_URI_PERMISSION) != 0) {
8233             grantUri.prefix = true;
8234         }
8235         final UriPermission perm = findOrCreateUriPermissionLocked(
8236                 pi.packageName, targetPkg, targetUid, grantUri);
8237         perm.grantModes(modeFlags, owner);
8238     }
8239
8240     void grantUriPermissionLocked(int callingUid, String targetPkg, GrantUri grantUri,
8241             final int modeFlags, UriPermissionOwner owner, int targetUserId) {
8242         if (targetPkg == null) {
8243             throw new NullPointerException("targetPkg");
8244         }
8245         int targetUid;
8246         final IPackageManager pm = AppGlobals.getPackageManager();
8247         try {
8248             targetUid = pm.getPackageUid(targetPkg, MATCH_DEBUG_TRIAGED_MISSING, targetUserId);
8249         } catch (RemoteException ex) {
8250             return;
8251         }
8252
8253         targetUid = checkGrantUriPermissionLocked(callingUid, targetPkg, grantUri, modeFlags,
8254                 targetUid);
8255         if (targetUid < 0) {
8256             return;
8257         }
8258
8259         grantUriPermissionUncheckedLocked(targetUid, targetPkg, grantUri, modeFlags,
8260                 owner);
8261     }
8262
8263     static class NeededUriGrants extends ArrayList<GrantUri> {
8264         final String targetPkg;
8265         final int targetUid;
8266         final int flags;
8267
8268         NeededUriGrants(String targetPkg, int targetUid, int flags) {
8269             this.targetPkg = targetPkg;
8270             this.targetUid = targetUid;
8271             this.flags = flags;
8272         }
8273     }
8274
8275     /**
8276      * Like checkGrantUriPermissionLocked, but takes an Intent.
8277      */
8278     NeededUriGrants checkGrantUriPermissionFromIntentLocked(int callingUid,
8279             String targetPkg, Intent intent, int mode, NeededUriGrants needed, int targetUserId) {
8280         if (DEBUG_URI_PERMISSION) Slog.v(TAG_URI_PERMISSION,
8281                 "Checking URI perm to data=" + (intent != null ? intent.getData() : null)
8282                 + " clip=" + (intent != null ? intent.getClipData() : null)
8283                 + " from " + intent + "; flags=0x"
8284                 + Integer.toHexString(intent != null ? intent.getFlags() : 0));
8285
8286         if (targetPkg == null) {
8287             throw new NullPointerException("targetPkg");
8288         }
8289
8290         if (intent == null) {
8291             return null;
8292         }
8293         Uri data = intent.getData();
8294         ClipData clip = intent.getClipData();
8295         if (data == null && clip == null) {
8296             return null;
8297         }
8298         // Default userId for uris in the intent (if they don't specify it themselves)
8299         int contentUserHint = intent.getContentUserHint();
8300         if (contentUserHint == UserHandle.USER_CURRENT) {
8301             contentUserHint = UserHandle.getUserId(callingUid);
8302         }
8303         final IPackageManager pm = AppGlobals.getPackageManager();
8304         int targetUid;
8305         if (needed != null) {
8306             targetUid = needed.targetUid;
8307         } else {
8308             try {
8309                 targetUid = pm.getPackageUid(targetPkg, MATCH_DEBUG_TRIAGED_MISSING,
8310                         targetUserId);
8311             } catch (RemoteException ex) {
8312                 return null;
8313             }
8314             if (targetUid < 0) {
8315                 if (DEBUG_URI_PERMISSION) Slog.v(TAG_URI_PERMISSION,
8316                         "Can't grant URI permission no uid for: " + targetPkg
8317                         + " on user " + targetUserId);
8318                 return null;
8319             }
8320         }
8321         if (data != null) {
8322             GrantUri grantUri = GrantUri.resolve(contentUserHint, data);
8323             targetUid = checkGrantUriPermissionLocked(callingUid, targetPkg, grantUri, mode,
8324                     targetUid);
8325             if (targetUid > 0) {
8326                 if (needed == null) {
8327                     needed = new NeededUriGrants(targetPkg, targetUid, mode);
8328                 }
8329                 needed.add(grantUri);
8330             }
8331         }
8332         if (clip != null) {
8333             for (int i=0; i<clip.getItemCount(); i++) {
8334                 Uri uri = clip.getItemAt(i).getUri();
8335                 if (uri != null) {
8336                     GrantUri grantUri = GrantUri.resolve(contentUserHint, uri);
8337                     targetUid = checkGrantUriPermissionLocked(callingUid, targetPkg, grantUri, mode,
8338                             targetUid);
8339                     if (targetUid > 0) {
8340                         if (needed == null) {
8341                             needed = new NeededUriGrants(targetPkg, targetUid, mode);
8342                         }
8343                         needed.add(grantUri);
8344                     }
8345                 } else {
8346                     Intent clipIntent = clip.getItemAt(i).getIntent();
8347                     if (clipIntent != null) {
8348                         NeededUriGrants newNeeded = checkGrantUriPermissionFromIntentLocked(
8349                                 callingUid, targetPkg, clipIntent, mode, needed, targetUserId);
8350                         if (newNeeded != null) {
8351                             needed = newNeeded;
8352                         }
8353                     }
8354                 }
8355             }
8356         }
8357
8358         return needed;
8359     }
8360
8361     /**
8362      * Like grantUriPermissionUncheckedLocked, but takes an Intent.
8363      */
8364     void grantUriPermissionUncheckedFromIntentLocked(NeededUriGrants needed,
8365             UriPermissionOwner owner) {
8366         if (needed != null) {
8367             for (int i=0; i<needed.size(); i++) {
8368                 GrantUri grantUri = needed.get(i);
8369                 grantUriPermissionUncheckedLocked(needed.targetUid, needed.targetPkg,
8370                         grantUri, needed.flags, owner);
8371             }
8372         }
8373     }
8374
8375     void grantUriPermissionFromIntentLocked(int callingUid,
8376             String targetPkg, Intent intent, UriPermissionOwner owner, int targetUserId) {
8377         NeededUriGrants needed = checkGrantUriPermissionFromIntentLocked(callingUid, targetPkg,
8378                 intent, intent != null ? intent.getFlags() : 0, null, targetUserId);
8379         if (needed == null) {
8380             return;
8381         }
8382
8383         grantUriPermissionUncheckedFromIntentLocked(needed, owner);
8384     }
8385
8386     /**
8387      * @param uri This uri must NOT contain an embedded userId.
8388      * @param userId The userId in which the uri is to be resolved.
8389      */
8390     @Override
8391     public void grantUriPermission(IApplicationThread caller, String targetPkg, Uri uri,
8392             final int modeFlags, int userId) {
8393         enforceNotIsolatedCaller("grantUriPermission");
8394         GrantUri grantUri = new GrantUri(userId, uri, false);
8395         synchronized(this) {
8396             final ProcessRecord r = getRecordForAppLocked(caller);
8397             if (r == null) {
8398                 throw new SecurityException("Unable to find app for caller "
8399                         + caller
8400                         + " when granting permission to uri " + grantUri);
8401             }
8402             if (targetPkg == null) {
8403                 throw new IllegalArgumentException("null target");
8404             }
8405             if (grantUri == null) {
8406                 throw new IllegalArgumentException("null uri");
8407             }
8408
8409             Preconditions.checkFlagsArgument(modeFlags, Intent.FLAG_GRANT_READ_URI_PERMISSION
8410                     | Intent.FLAG_GRANT_WRITE_URI_PERMISSION
8411                     | Intent.FLAG_GRANT_PERSISTABLE_URI_PERMISSION
8412                     | Intent.FLAG_GRANT_PREFIX_URI_PERMISSION);
8413
8414             grantUriPermissionLocked(r.uid, targetPkg, grantUri, modeFlags, null,
8415                     UserHandle.getUserId(r.uid));
8416         }
8417     }
8418
8419     void removeUriPermissionIfNeededLocked(UriPermission perm) {
8420         if (perm.modeFlags == 0) {
8421             final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.get(
8422                     perm.targetUid);
8423             if (perms != null) {
8424                 if (DEBUG_URI_PERMISSION) Slog.v(TAG_URI_PERMISSION,
8425                         "Removing " + perm.targetUid + " permission to " + perm.uri);
8426
8427                 perms.remove(perm.uri);
8428                 if (perms.isEmpty()) {
8429                     mGrantedUriPermissions.remove(perm.targetUid);
8430                 }
8431             }
8432         }
8433     }
8434
8435     private void revokeUriPermissionLocked(int callingUid, GrantUri grantUri, final int modeFlags) {
8436         if (DEBUG_URI_PERMISSION) Slog.v(TAG_URI_PERMISSION,
8437                 "Revoking all granted permissions to " + grantUri);
8438
8439         final IPackageManager pm = AppGlobals.getPackageManager();
8440         final String authority = grantUri.uri.getAuthority();
8441         final ProviderInfo pi = getProviderInfoLocked(authority, grantUri.sourceUserId,
8442                 MATCH_DIRECT_BOOT_AWARE | MATCH_DIRECT_BOOT_UNAWARE);
8443         if (pi == null) {
8444             Slog.w(TAG, "No content provider found for permission revoke: "
8445                     + grantUri.toSafeString());
8446             return;
8447         }
8448
8449         // Does the caller have this permission on the URI?
8450         if (!checkHoldingPermissionsLocked(pm, pi, grantUri, callingUid, modeFlags)) {
8451             // If they don't have direct access to the URI, then revoke any
8452             // ownerless URI permissions that have been granted to them.
8453             final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.get(callingUid);
8454             if (perms != null) {
8455                 boolean persistChanged = false;
8456                 for (Iterator<UriPermission> it = perms.values().iterator(); it.hasNext();) {
8457                     final UriPermission perm = it.next();
8458                     if (perm.uri.sourceUserId == grantUri.sourceUserId
8459                             && perm.uri.uri.isPathPrefixMatch(grantUri.uri)) {
8460                         if (DEBUG_URI_PERMISSION) Slog.v(TAG_URI_PERMISSION,
8461                                 "Revoking non-owned " + perm.targetUid
8462                                 + " permission to " + perm.uri);
8463                         persistChanged |= perm.revokeModes(
8464                                 modeFlags | Intent.FLAG_GRANT_PERSISTABLE_URI_PERMISSION, false);
8465                         if (perm.modeFlags == 0) {
8466                             it.remove();
8467                         }
8468                     }
8469                 }
8470                 if (perms.isEmpty()) {
8471                     mGrantedUriPermissions.remove(callingUid);
8472                 }
8473                 if (persistChanged) {
8474                     schedulePersistUriGrants();
8475                 }
8476             }
8477             return;
8478         }
8479
8480         boolean persistChanged = false;
8481
8482         // Go through all of the permissions and remove any that match.
8483         int N = mGrantedUriPermissions.size();
8484         for (int i = 0; i < N; i++) {
8485             final int targetUid = mGrantedUriPermissions.keyAt(i);
8486             final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.valueAt(i);
8487
8488             for (Iterator<UriPermission> it = perms.values().iterator(); it.hasNext();) {
8489                 final UriPermission perm = it.next();
8490                 if (perm.uri.sourceUserId == grantUri.sourceUserId
8491                         && perm.uri.uri.isPathPrefixMatch(grantUri.uri)) {
8492                     if (DEBUG_URI_PERMISSION) Slog.v(TAG_URI_PERMISSION,
8493                                 "Revoking " + perm.targetUid + " permission to " + perm.uri);
8494                     persistChanged |= perm.revokeModes(
8495                             modeFlags | Intent.FLAG_GRANT_PERSISTABLE_URI_PERMISSION, true);
8496                     if (perm.modeFlags == 0) {
8497                         it.remove();
8498                     }
8499                 }
8500             }
8501
8502             if (perms.isEmpty()) {
8503                 mGrantedUriPermissions.remove(targetUid);
8504                 N--;
8505                 i--;
8506             }
8507         }
8508
8509         if (persistChanged) {
8510             schedulePersistUriGrants();
8511         }
8512     }
8513
8514     /**
8515      * @param uri This uri must NOT contain an embedded userId.
8516      * @param userId The userId in which the uri is to be resolved.
8517      */
8518     @Override
8519     public void revokeUriPermission(IApplicationThread caller, Uri uri, final int modeFlags,
8520             int userId) {
8521         enforceNotIsolatedCaller("revokeUriPermission");
8522         synchronized(this) {
8523             final ProcessRecord r = getRecordForAppLocked(caller);
8524             if (r == null) {
8525                 throw new SecurityException("Unable to find app for caller "
8526                         + caller
8527                         + " when revoking permission to uri " + uri);
8528             }
8529             if (uri == null) {
8530                 Slog.w(TAG, "revokeUriPermission: null uri");
8531                 return;
8532             }
8533
8534             if (!Intent.isAccessUriMode(modeFlags)) {
8535                 return;
8536             }
8537
8538             final String authority = uri.getAuthority();
8539             final ProviderInfo pi = getProviderInfoLocked(authority, userId,
8540                     MATCH_DIRECT_BOOT_AWARE | MATCH_DIRECT_BOOT_UNAWARE);
8541             if (pi == null) {
8542                 Slog.w(TAG, "No content provider found for permission revoke: "
8543                         + uri.toSafeString());
8544                 return;
8545             }
8546
8547             revokeUriPermissionLocked(r.uid, new GrantUri(userId, uri, false), modeFlags);
8548         }
8549     }
8550
8551     /**
8552      * Remove any {@link UriPermission} granted <em>from</em> or <em>to</em> the
8553      * given package.
8554      *
8555      * @param packageName Package name to match, or {@code null} to apply to all
8556      *            packages.
8557      * @param userHandle User to match, or {@link UserHandle#USER_ALL} to apply
8558      *            to all users.
8559      * @param persistable If persistable grants should be removed.
8560      */
8561     private void removeUriPermissionsForPackageLocked(
8562             String packageName, int userHandle, boolean persistable) {
8563         if (userHandle == UserHandle.USER_ALL && packageName == null) {
8564             throw new IllegalArgumentException("Must narrow by either package or user");
8565         }
8566
8567         boolean persistChanged = false;
8568
8569         int N = mGrantedUriPermissions.size();
8570         for (int i = 0; i < N; i++) {
8571             final int targetUid = mGrantedUriPermissions.keyAt(i);
8572             final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.valueAt(i);
8573
8574             // Only inspect grants matching user
8575             if (userHandle == UserHandle.USER_ALL
8576                     || userHandle == UserHandle.getUserId(targetUid)) {
8577                 for (Iterator<UriPermission> it = perms.values().iterator(); it.hasNext();) {
8578                     final UriPermission perm = it.next();
8579
8580                     // Only inspect grants matching package
8581                     if (packageName == null || perm.sourcePkg.equals(packageName)
8582                             || perm.targetPkg.equals(packageName)) {
8583                         // Hacky solution as part of fixing a security bug; ignore
8584                         // grants associated with DownloadManager so we don't have
8585                         // to immediately launch it to regrant the permissions
8586                         if (Downloads.Impl.AUTHORITY.equals(perm.uri.uri.getAuthority())
8587                                 && !persistable) continue;
8588
8589                         persistChanged |= perm.revokeModes(persistable
8590                                 ? ~0 : ~Intent.FLAG_GRANT_PERSISTABLE_URI_PERMISSION, true);
8591
8592                         // Only remove when no modes remain; any persisted grants
8593                         // will keep this alive.
8594                         if (perm.modeFlags == 0) {
8595                             it.remove();
8596                         }
8597                     }
8598                 }
8599
8600                 if (perms.isEmpty()) {
8601                     mGrantedUriPermissions.remove(targetUid);
8602                     N--;
8603                     i--;
8604                 }
8605             }
8606         }
8607
8608         if (persistChanged) {
8609             schedulePersistUriGrants();
8610         }
8611     }
8612
8613     @Override
8614     public IBinder newUriPermissionOwner(String name) {
8615         enforceNotIsolatedCaller("newUriPermissionOwner");
8616         synchronized(this) {
8617             UriPermissionOwner owner = new UriPermissionOwner(this, name);
8618             return owner.getExternalTokenLocked();
8619         }
8620     }
8621
8622     @Override
8623     public IBinder getUriPermissionOwnerForActivity(IBinder activityToken) {
8624         enforceNotIsolatedCaller("getUriPermissionOwnerForActivity");
8625         synchronized(this) {
8626             ActivityRecord r = ActivityRecord.isInStackLocked(activityToken);
8627             if (r == null) {
8628                 throw new IllegalArgumentException("Activity does not exist; token="
8629                         + activityToken);
8630             }
8631             return r.getUriPermissionsLocked().getExternalTokenLocked();
8632         }
8633     }
8634     /**
8635      * @param uri This uri must NOT contain an embedded userId.
8636      * @param sourceUserId The userId in which the uri is to be resolved.
8637      * @param targetUserId The userId of the app that receives the grant.
8638      */
8639     @Override
8640     public void grantUriPermissionFromOwner(IBinder token, int fromUid, String targetPkg, Uri uri,
8641             final int modeFlags, int sourceUserId, int targetUserId) {
8642         targetUserId = mUserController.handleIncomingUser(Binder.getCallingPid(),
8643                 Binder.getCallingUid(), targetUserId, false, ALLOW_FULL_ONLY,
8644                 "grantUriPermissionFromOwner", null);
8645         synchronized(this) {
8646             UriPermissionOwner owner = UriPermissionOwner.fromExternalToken(token);
8647             if (owner == null) {
8648                 throw new IllegalArgumentException("Unknown owner: " + token);
8649             }
8650             if (fromUid != Binder.getCallingUid()) {
8651                 if (Binder.getCallingUid() != Process.myUid()) {
8652                     // Only system code can grant URI permissions on behalf
8653                     // of other users.
8654                     throw new SecurityException("nice try");
8655                 }
8656             }
8657             if (targetPkg == null) {
8658                 throw new IllegalArgumentException("null target");
8659             }
8660             if (uri == null) {
8661                 throw new IllegalArgumentException("null uri");
8662             }
8663
8664             grantUriPermissionLocked(fromUid, targetPkg, new GrantUri(sourceUserId, uri, false),
8665                     modeFlags, owner, targetUserId);
8666         }
8667     }
8668
8669     /**
8670      * @param uri This uri must NOT contain an embedded userId.
8671      * @param userId The userId in which the uri is to be resolved.
8672      */
8673     @Override
8674     public void revokeUriPermissionFromOwner(IBinder token, Uri uri, int mode, int userId) {
8675         synchronized(this) {
8676             UriPermissionOwner owner = UriPermissionOwner.fromExternalToken(token);
8677             if (owner == null) {
8678                 throw new IllegalArgumentException("Unknown owner: " + token);
8679             }
8680
8681             if (uri == null) {
8682                 owner.removeUriPermissionsLocked(mode);
8683             } else {
8684                 final boolean prefix = (mode & Intent.FLAG_GRANT_PREFIX_URI_PERMISSION) != 0;
8685                 owner.removeUriPermissionLocked(new GrantUri(userId, uri, prefix), mode);
8686             }
8687         }
8688     }
8689
8690     private void schedulePersistUriGrants() {
8691         if (!mHandler.hasMessages(PERSIST_URI_GRANTS_MSG)) {
8692             mHandler.sendMessageDelayed(mHandler.obtainMessage(PERSIST_URI_GRANTS_MSG),
8693                     10 * DateUtils.SECOND_IN_MILLIS);
8694         }
8695     }
8696
8697     private void writeGrantedUriPermissions() {
8698         if (DEBUG_URI_PERMISSION) Slog.v(TAG_URI_PERMISSION, "writeGrantedUriPermissions()");
8699
8700         // Snapshot permissions so we can persist without lock
8701         ArrayList<UriPermission.Snapshot> persist = Lists.newArrayList();
8702         synchronized (this) {
8703             final int size = mGrantedUriPermissions.size();
8704             for (int i = 0; i < size; i++) {
8705                 final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.valueAt(i);
8706                 for (UriPermission perm : perms.values()) {
8707                     if (perm.persistedModeFlags != 0) {
8708                         persist.add(perm.snapshot());
8709                     }
8710                 }
8711             }
8712         }
8713
8714         FileOutputStream fos = null;
8715         try {
8716             fos = mGrantFile.startWrite();
8717
8718             XmlSerializer out = new FastXmlSerializer();
8719             out.setOutput(fos, StandardCharsets.UTF_8.name());
8720             out.startDocument(null, true);
8721             out.startTag(null, TAG_URI_GRANTS);
8722             for (UriPermission.Snapshot perm : persist) {
8723                 out.startTag(null, TAG_URI_GRANT);
8724                 writeIntAttribute(out, ATTR_SOURCE_USER_ID, perm.uri.sourceUserId);
8725                 writeIntAttribute(out, ATTR_TARGET_USER_ID, perm.targetUserId);
8726                 out.attribute(null, ATTR_SOURCE_PKG, perm.sourcePkg);
8727                 out.attribute(null, ATTR_TARGET_PKG, perm.targetPkg);
8728                 out.attribute(null, ATTR_URI, String.valueOf(perm.uri.uri));
8729                 writeBooleanAttribute(out, ATTR_PREFIX, perm.uri.prefix);
8730                 writeIntAttribute(out, ATTR_MODE_FLAGS, perm.persistedModeFlags);
8731                 writeLongAttribute(out, ATTR_CREATED_TIME, perm.persistedCreateTime);
8732                 out.endTag(null, TAG_URI_GRANT);
8733             }
8734             out.endTag(null, TAG_URI_GRANTS);
8735             out.endDocument();
8736
8737             mGrantFile.finishWrite(fos);
8738         } catch (IOException e) {
8739             if (fos != null) {
8740                 mGrantFile.failWrite(fos);
8741             }
8742         }
8743     }
8744
8745     private void readGrantedUriPermissionsLocked() {
8746         if (DEBUG_URI_PERMISSION) Slog.v(TAG_URI_PERMISSION, "readGrantedUriPermissions()");
8747
8748         final long now = System.currentTimeMillis();
8749
8750         FileInputStream fis = null;
8751         try {
8752             fis = mGrantFile.openRead();
8753             final XmlPullParser in = Xml.newPullParser();
8754             in.setInput(fis, StandardCharsets.UTF_8.name());
8755
8756             int type;
8757             while ((type = in.next()) != END_DOCUMENT) {
8758                 final String tag = in.getName();
8759                 if (type == START_TAG) {
8760                     if (TAG_URI_GRANT.equals(tag)) {
8761                         final int sourceUserId;
8762                         final int targetUserId;
8763                         final int userHandle = readIntAttribute(in,
8764                                 ATTR_USER_HANDLE, UserHandle.USER_NULL);
8765                         if (userHandle != UserHandle.USER_NULL) {
8766                             // For backwards compatibility.
8767                             sourceUserId = userHandle;
8768                             targetUserId = userHandle;
8769                         } else {
8770                             sourceUserId = readIntAttribute(in, ATTR_SOURCE_USER_ID);
8771                             targetUserId = readIntAttribute(in, ATTR_TARGET_USER_ID);
8772                         }
8773                         final String sourcePkg = in.getAttributeValue(null, ATTR_SOURCE_PKG);
8774                         final String targetPkg = in.getAttributeValue(null, ATTR_TARGET_PKG);
8775                         final Uri uri = Uri.parse(in.getAttributeValue(null, ATTR_URI));
8776                         final boolean prefix = readBooleanAttribute(in, ATTR_PREFIX);
8777                         final int modeFlags = readIntAttribute(in, ATTR_MODE_FLAGS);
8778                         final long createdTime = readLongAttribute(in, ATTR_CREATED_TIME, now);
8779
8780                         // Sanity check that provider still belongs to source package
8781                         // Both direct boot aware and unaware packages are fine as we
8782                         // will do filtering at query time to avoid multiple parsing.
8783                         final ProviderInfo pi = getProviderInfoLocked(
8784                                 uri.getAuthority(), sourceUserId, MATCH_DIRECT_BOOT_AWARE
8785                                         | MATCH_DIRECT_BOOT_UNAWARE);
8786                         if (pi != null && sourcePkg.equals(pi.packageName)) {
8787                             int targetUid = -1;
8788                             try {
8789                                 targetUid = AppGlobals.getPackageManager().getPackageUid(
8790                                         targetPkg, MATCH_UNINSTALLED_PACKAGES, targetUserId);
8791                             } catch (RemoteException e) {
8792                             }
8793                             if (targetUid != -1) {
8794                                 final UriPermission perm = findOrCreateUriPermissionLocked(
8795                                         sourcePkg, targetPkg, targetUid,
8796                                         new GrantUri(sourceUserId, uri, prefix));
8797                                 perm.initPersistedModes(modeFlags, createdTime);
8798                             }
8799                         } else {
8800                             Slog.w(TAG, "Persisted grant for " + uri + " had source " + sourcePkg
8801                                     + " but instead found " + pi);
8802                         }
8803                     }
8804                 }
8805             }
8806         } catch (FileNotFoundException e) {
8807             // Missing grants is okay
8808         } catch (IOException e) {
8809             Slog.wtf(TAG, "Failed reading Uri grants", e);
8810         } catch (XmlPullParserException e) {
8811             Slog.wtf(TAG, "Failed reading Uri grants", e);
8812         } finally {
8813             IoUtils.closeQuietly(fis);
8814         }
8815     }
8816
8817     /**
8818      * @param uri This uri must NOT contain an embedded userId.
8819      * @param userId The userId in which the uri is to be resolved.
8820      */
8821     @Override
8822     public void takePersistableUriPermission(Uri uri, final int modeFlags, int userId) {
8823         enforceNotIsolatedCaller("takePersistableUriPermission");
8824
8825         Preconditions.checkFlagsArgument(modeFlags,
8826                 Intent.FLAG_GRANT_READ_URI_PERMISSION | Intent.FLAG_GRANT_WRITE_URI_PERMISSION);
8827
8828         synchronized (this) {
8829             final int callingUid = Binder.getCallingUid();
8830             boolean persistChanged = false;
8831             GrantUri grantUri = new GrantUri(userId, uri, false);
8832
8833             UriPermission exactPerm = findUriPermissionLocked(callingUid,
8834                     new GrantUri(userId, uri, false));
8835             UriPermission prefixPerm = findUriPermissionLocked(callingUid,
8836                     new GrantUri(userId, uri, true));
8837
8838             final boolean exactValid = (exactPerm != null)
8839                     && ((modeFlags & exactPerm.persistableModeFlags) == modeFlags);
8840             final boolean prefixValid = (prefixPerm != null)
8841                     && ((modeFlags & prefixPerm.persistableModeFlags) == modeFlags);
8842
8843             if (!(exactValid || prefixValid)) {
8844                 throw new SecurityException("No persistable permission grants found for UID "
8845                         + callingUid + " and Uri " + grantUri.toSafeString());
8846             }
8847
8848             if (exactValid) {
8849                 persistChanged |= exactPerm.takePersistableModes(modeFlags);
8850             }
8851             if (prefixValid) {
8852                 persistChanged |= prefixPerm.takePersistableModes(modeFlags);
8853             }
8854
8855             persistChanged |= maybePrunePersistedUriGrantsLocked(callingUid);
8856
8857             if (persistChanged) {
8858                 schedulePersistUriGrants();
8859             }
8860         }
8861     }
8862
8863     /**
8864      * @param uri This uri must NOT contain an embedded userId.
8865      * @param userId The userId in which the uri is to be resolved.
8866      */
8867     @Override
8868     public void releasePersistableUriPermission(Uri uri, final int modeFlags, int userId) {
8869         enforceNotIsolatedCaller("releasePersistableUriPermission");
8870
8871         Preconditions.checkFlagsArgument(modeFlags,
8872                 Intent.FLAG_GRANT_READ_URI_PERMISSION | Intent.FLAG_GRANT_WRITE_URI_PERMISSION);
8873
8874         synchronized (this) {
8875             final int callingUid = Binder.getCallingUid();
8876             boolean persistChanged = false;
8877
8878             UriPermission exactPerm = findUriPermissionLocked(callingUid,
8879                     new GrantUri(userId, uri, false));
8880             UriPermission prefixPerm = findUriPermissionLocked(callingUid,
8881                     new GrantUri(userId, uri, true));
8882             if (exactPerm == null && prefixPerm == null) {
8883                 throw new SecurityException("No permission grants found for UID " + callingUid
8884                         + " and Uri " + uri.toSafeString());
8885             }
8886
8887             if (exactPerm != null) {
8888                 persistChanged |= exactPerm.releasePersistableModes(modeFlags);
8889                 removeUriPermissionIfNeededLocked(exactPerm);
8890             }
8891             if (prefixPerm != null) {
8892                 persistChanged |= prefixPerm.releasePersistableModes(modeFlags);
8893                 removeUriPermissionIfNeededLocked(prefixPerm);
8894             }
8895
8896             if (persistChanged) {
8897                 schedulePersistUriGrants();
8898             }
8899         }
8900     }
8901
8902     /**
8903      * Prune any older {@link UriPermission} for the given UID until outstanding
8904      * persisted grants are below {@link #MAX_PERSISTED_URI_GRANTS}.
8905      *
8906      * @return if any mutations occured that require persisting.
8907      */
8908     private boolean maybePrunePersistedUriGrantsLocked(int uid) {
8909         final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.get(uid);
8910         if (perms == null) return false;
8911         if (perms.size() < MAX_PERSISTED_URI_GRANTS) return false;
8912
8913         final ArrayList<UriPermission> persisted = Lists.newArrayList();
8914         for (UriPermission perm : perms.values()) {
8915             if (perm.persistedModeFlags != 0) {
8916                 persisted.add(perm);
8917             }
8918         }
8919
8920         final int trimCount = persisted.size() - MAX_PERSISTED_URI_GRANTS;
8921         if (trimCount <= 0) return false;
8922
8923         Collections.sort(persisted, new UriPermission.PersistedTimeComparator());
8924         for (int i = 0; i < trimCount; i++) {
8925             final UriPermission perm = persisted.get(i);
8926
8927             if (DEBUG_URI_PERMISSION) Slog.v(TAG_URI_PERMISSION,
8928                     "Trimming grant created at " + perm.persistedCreateTime);
8929
8930             perm.releasePersistableModes(~0);
8931             removeUriPermissionIfNeededLocked(perm);
8932         }
8933
8934         return true;
8935     }
8936
8937     @Override
8938     public ParceledListSlice<android.content.UriPermission> getPersistedUriPermissions(
8939             String packageName, boolean incoming) {
8940         enforceNotIsolatedCaller("getPersistedUriPermissions");
8941         Preconditions.checkNotNull(packageName, "packageName");
8942
8943         final int callingUid = Binder.getCallingUid();
8944         final int callingUserId = UserHandle.getUserId(callingUid);
8945         final IPackageManager pm = AppGlobals.getPackageManager();
8946         try {
8947             final int packageUid = pm.getPackageUid(packageName,
8948                     MATCH_DIRECT_BOOT_AWARE | MATCH_DIRECT_BOOT_UNAWARE, callingUserId);
8949             if (packageUid != callingUid) {
8950                 throw new SecurityException(
8951                         "Package " + packageName + " does not belong to calling UID " + callingUid);
8952             }
8953         } catch (RemoteException e) {
8954             throw new SecurityException("Failed to verify package name ownership");
8955         }
8956
8957         final ArrayList<android.content.UriPermission> result = Lists.newArrayList();
8958         synchronized (this) {
8959             if (incoming) {
8960                 final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.get(
8961                         callingUid);
8962                 if (perms == null) {
8963                     Slog.w(TAG, "No permission grants found for " + packageName);
8964                 } else {
8965                     for (UriPermission perm : perms.values()) {
8966                         if (packageName.equals(perm.targetPkg) && perm.persistedModeFlags != 0) {
8967                             result.add(perm.buildPersistedPublicApiObject());
8968                         }
8969                     }
8970                 }
8971             } else {
8972                 final int size = mGrantedUriPermissions.size();
8973                 for (int i = 0; i < size; i++) {
8974                     final ArrayMap<GrantUri, UriPermission> perms =
8975                             mGrantedUriPermissions.valueAt(i);
8976                     for (UriPermission perm : perms.values()) {
8977                         if (packageName.equals(perm.sourcePkg) && perm.persistedModeFlags != 0) {
8978                             result.add(perm.buildPersistedPublicApiObject());
8979                         }
8980                     }
8981                 }
8982             }
8983         }
8984         return new ParceledListSlice<android.content.UriPermission>(result);
8985     }
8986
8987     @Override
8988     public ParceledListSlice<android.content.UriPermission> getGrantedUriPermissions(
8989             String packageName, int userId) {
8990         enforceCallingPermission(android.Manifest.permission.GET_APP_GRANTED_URI_PERMISSIONS,
8991                 "getGrantedUriPermissions");
8992
8993         final ArrayList<android.content.UriPermission> result = Lists.newArrayList();
8994         synchronized (this) {
8995             final int size = mGrantedUriPermissions.size();
8996             for (int i = 0; i < size; i++) {
8997                 final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.valueAt(i);
8998                 for (UriPermission perm : perms.values()) {
8999                     if (packageName.equals(perm.targetPkg) && perm.targetUserId == userId
9000                             && perm.persistedModeFlags != 0) {
9001                         result.add(perm.buildPersistedPublicApiObject());
9002                     }
9003                 }
9004             }
9005         }
9006         return new ParceledListSlice<android.content.UriPermission>(result);
9007     }
9008
9009     @Override
9010     public void clearGrantedUriPermissions(String packageName, int userId) {
9011         enforceCallingPermission(android.Manifest.permission.CLEAR_APP_GRANTED_URI_PERMISSIONS,
9012                 "clearGrantedUriPermissions");
9013         removeUriPermissionsForPackageLocked(packageName, userId, true);
9014     }
9015
9016     @Override
9017     public void showWaitingForDebugger(IApplicationThread who, boolean waiting) {
9018         synchronized (this) {
9019             ProcessRecord app =
9020                 who != null ? getRecordForAppLocked(who) : null;
9021             if (app == null) return;
9022
9023             Message msg = Message.obtain();
9024             msg.what = WAIT_FOR_DEBUGGER_UI_MSG;
9025             msg.obj = app;
9026             msg.arg1 = waiting ? 1 : 0;
9027             mUiHandler.sendMessage(msg);
9028         }
9029     }
9030
9031     @Override
9032     public void getMemoryInfo(ActivityManager.MemoryInfo outInfo) {
9033         final long homeAppMem = mProcessList.getMemLevel(ProcessList.HOME_APP_ADJ);
9034         final long cachedAppMem = mProcessList.getMemLevel(ProcessList.CACHED_APP_MIN_ADJ);
9035         outInfo.availMem = Process.getFreeMemory();
9036         outInfo.totalMem = Process.getTotalMemory();
9037         outInfo.threshold = homeAppMem;
9038         outInfo.lowMemory = outInfo.availMem < (homeAppMem + ((cachedAppMem-homeAppMem)/2));
9039         outInfo.hiddenAppThreshold = cachedAppMem;
9040         outInfo.secondaryServerThreshold = mProcessList.getMemLevel(
9041                 ProcessList.SERVICE_ADJ);
9042         outInfo.visibleAppThreshold = mProcessList.getMemLevel(
9043                 ProcessList.VISIBLE_APP_ADJ);
9044         outInfo.foregroundAppThreshold = mProcessList.getMemLevel(
9045                 ProcessList.FOREGROUND_APP_ADJ);
9046     }
9047
9048     // =========================================================
9049     // TASK MANAGEMENT
9050     // =========================================================
9051
9052     @Override
9053     public List<IAppTask> getAppTasks(String callingPackage) {
9054         int callingUid = Binder.getCallingUid();
9055         long ident = Binder.clearCallingIdentity();
9056
9057         synchronized(this) {
9058             ArrayList<IAppTask> list = new ArrayList<IAppTask>();
9059             try {
9060                 if (DEBUG_ALL) Slog.v(TAG, "getAppTasks");
9061
9062                 final int N = mRecentTasks.size();
9063                 for (int i = 0; i < N; i++) {
9064                     TaskRecord tr = mRecentTasks.get(i);
9065                     // Skip tasks that do not match the caller.  We don't need to verify
9066                     // callingPackage, because we are also limiting to callingUid and know
9067                     // that will limit to the correct security sandbox.
9068                     if (tr.effectiveUid != callingUid) {
9069                         continue;
9070                     }
9071                     Intent intent = tr.getBaseIntent();
9072                     if (intent == null ||
9073                             !callingPackage.equals(intent.getComponent().getPackageName())) {
9074                         continue;
9075                     }
9076                     ActivityManager.RecentTaskInfo taskInfo =
9077                             createRecentTaskInfoFromTaskRecord(tr);
9078                     AppTaskImpl taskImpl = new AppTaskImpl(taskInfo.persistentId, callingUid);
9079                     list.add(taskImpl);
9080                 }
9081             } finally {
9082                 Binder.restoreCallingIdentity(ident);
9083             }
9084             return list;
9085         }
9086     }
9087
9088     @Override
9089     public List<RunningTaskInfo> getTasks(int maxNum, int flags) {
9090         final int callingUid = Binder.getCallingUid();
9091         ArrayList<RunningTaskInfo> list = new ArrayList<RunningTaskInfo>();
9092
9093         synchronized(this) {
9094             if (DEBUG_ALL) Slog.v(
9095                 TAG, "getTasks: max=" + maxNum + ", flags=" + flags);
9096
9097             final boolean allowed = isGetTasksAllowed("getTasks", Binder.getCallingPid(),
9098                     callingUid);
9099
9100             // TODO: Improve with MRU list from all ActivityStacks.
9101             mStackSupervisor.getTasksLocked(maxNum, list, callingUid, allowed);
9102         }
9103
9104         return list;
9105     }
9106
9107     /**
9108      * Creates a new RecentTaskInfo from a TaskRecord.
9109      */
9110     private ActivityManager.RecentTaskInfo createRecentTaskInfoFromTaskRecord(TaskRecord tr) {
9111         // Update the task description to reflect any changes in the task stack
9112         tr.updateTaskDescription();
9113
9114         // Compose the recent task info
9115         ActivityManager.RecentTaskInfo rti = new ActivityManager.RecentTaskInfo();
9116         rti.id = tr.getTopActivity() == null ? INVALID_TASK_ID : tr.taskId;
9117         rti.persistentId = tr.taskId;
9118         rti.baseIntent = new Intent(tr.getBaseIntent());
9119         rti.origActivity = tr.origActivity;
9120         rti.realActivity = tr.realActivity;
9121         rti.description = tr.lastDescription;
9122         rti.stackId = tr.stack != null ? tr.stack.mStackId : -1;
9123         rti.userId = tr.userId;
9124         rti.taskDescription = new ActivityManager.TaskDescription(tr.lastTaskDescription);
9125         rti.firstActiveTime = tr.firstActiveTime;
9126         rti.lastActiveTime = tr.lastActiveTime;
9127         rti.affiliatedTaskId = tr.mAffiliatedTaskId;
9128         rti.affiliatedTaskColor = tr.mAffiliatedTaskColor;
9129         rti.numActivities = 0;
9130         if (tr.mBounds != null) {
9131             rti.bounds = new Rect(tr.mBounds);
9132         }
9133         rti.isDockable = tr.canGoInDockedStack();
9134         rti.resizeMode = tr.mResizeMode;
9135
9136         ActivityRecord base = null;
9137         ActivityRecord top = null;
9138         ActivityRecord tmp;
9139
9140         for (int i = tr.mActivities.size() - 1; i >= 0; --i) {
9141             tmp = tr.mActivities.get(i);
9142             if (tmp.finishing) {
9143                 continue;
9144             }
9145             base = tmp;
9146             if (top == null || (top.state == ActivityState.INITIALIZING)) {
9147                 top = base;
9148             }
9149             rti.numActivities++;
9150         }
9151
9152         rti.baseActivity = (base != null) ? base.intent.getComponent() : null;
9153         rti.topActivity = (top != null) ? top.intent.getComponent() : null;
9154
9155         return rti;
9156     }
9157
9158     private boolean isGetTasksAllowed(String caller, int callingPid, int callingUid) {
9159         boolean allowed = checkPermission(android.Manifest.permission.REAL_GET_TASKS,
9160                 callingPid, callingUid) == PackageManager.PERMISSION_GRANTED;
9161         if (!allowed) {
9162             if (checkPermission(android.Manifest.permission.GET_TASKS,
9163                     callingPid, callingUid) == PackageManager.PERMISSION_GRANTED) {
9164                 // Temporary compatibility: some existing apps on the system image may
9165                 // still be requesting the old permission and not switched to the new
9166                 // one; if so, we'll still allow them full access.  This means we need
9167                 // to see if they are holding the old permission and are a system app.
9168                 try {
9169                     if (AppGlobals.getPackageManager().isUidPrivileged(callingUid)) {
9170                         allowed = true;
9171                         if (DEBUG_TASKS) Slog.w(TAG, caller + ": caller " + callingUid
9172                                 + " is using old GET_TASKS but privileged; allowing");
9173                     }
9174                 } catch (RemoteException e) {
9175                 }
9176             }
9177         }
9178         if (!allowed) {
9179             if (DEBUG_TASKS) Slog.w(TAG, caller + ": caller " + callingUid
9180                     + " does not hold REAL_GET_TASKS; limiting output");
9181         }
9182         return allowed;
9183     }
9184
9185     @Override
9186     public ParceledListSlice<ActivityManager.RecentTaskInfo> getRecentTasks(int maxNum, int flags,
9187             int userId) {
9188         final int callingUid = Binder.getCallingUid();
9189         userId = mUserController.handleIncomingUser(Binder.getCallingPid(), callingUid, userId,
9190                 false, ALLOW_FULL_ONLY, "getRecentTasks", null);
9191
9192         final boolean includeProfiles = (flags & ActivityManager.RECENT_INCLUDE_PROFILES) != 0;
9193         final boolean withExcluded = (flags&ActivityManager.RECENT_WITH_EXCLUDED) != 0;
9194         synchronized (this) {
9195             final boolean allowed = isGetTasksAllowed("getRecentTasks", Binder.getCallingPid(),
9196                     callingUid);
9197             final boolean detailed = checkCallingPermission(
9198                     android.Manifest.permission.GET_DETAILED_TASKS)
9199                     == PackageManager.PERMISSION_GRANTED;
9200
9201             if (!isUserRunning(userId, ActivityManager.FLAG_AND_UNLOCKED)) {
9202                 Slog.i(TAG, "user " + userId + " is still locked. Cannot load recents");
9203                 return ParceledListSlice.emptyList();
9204             }
9205             mRecentTasks.loadUserRecentsLocked(userId);
9206
9207             final int recentsCount = mRecentTasks.size();
9208             ArrayList<ActivityManager.RecentTaskInfo> res =
9209                     new ArrayList<>(maxNum < recentsCount ? maxNum : recentsCount);
9210
9211             final Set<Integer> includedUsers;
9212             if (includeProfiles) {
9213                 includedUsers = mUserController.getProfileIds(userId);
9214             } else {
9215                 includedUsers = new HashSet<>();
9216             }
9217             includedUsers.add(Integer.valueOf(userId));
9218
9219             for (int i = 0; i < recentsCount && maxNum > 0; i++) {
9220                 TaskRecord tr = mRecentTasks.get(i);
9221                 // Only add calling user or related users recent tasks
9222                 if (!includedUsers.contains(Integer.valueOf(tr.userId))) {
9223                     if (DEBUG_RECENTS) Slog.d(TAG_RECENTS, "Skipping, not user: " + tr);
9224                     continue;
9225                 }
9226
9227                 if (tr.realActivitySuspended) {
9228                     if (DEBUG_RECENTS) Slog.d(TAG_RECENTS, "Skipping, activity suspended: " + tr);
9229                     continue;
9230                 }
9231
9232                 // Return the entry if desired by the caller.  We always return
9233                 // the first entry, because callers always expect this to be the
9234                 // foreground app.  We may filter others if the caller has
9235                 // not supplied RECENT_WITH_EXCLUDED and there is some reason
9236                 // we should exclude the entry.
9237
9238                 if (i == 0
9239                         || withExcluded
9240                         || (tr.intent == null)
9241                         || ((tr.intent.getFlags() & Intent.FLAG_ACTIVITY_EXCLUDE_FROM_RECENTS)
9242                                 == 0)) {
9243                     if (!allowed) {
9244                         // If the caller doesn't have the GET_TASKS permission, then only
9245                         // allow them to see a small subset of tasks -- their own and home.
9246                         if (!tr.isHomeTask() && tr.effectiveUid != callingUid) {
9247                             if (DEBUG_RECENTS) Slog.d(TAG_RECENTS, "Skipping, not allowed: " + tr);
9248                             continue;
9249                         }
9250                     }
9251                     if ((flags & ActivityManager.RECENT_IGNORE_HOME_STACK_TASKS) != 0) {
9252                         if (tr.stack != null && tr.stack.isHomeStack()) {
9253                             if (DEBUG_RECENTS) Slog.d(TAG_RECENTS,
9254                                     "Skipping, home stack task: " + tr);
9255                             continue;
9256                         }
9257                     }
9258                     if ((flags & ActivityManager.RECENT_INGORE_DOCKED_STACK_TOP_TASK) != 0) {
9259                         final ActivityStack stack = tr.stack;
9260                         if (stack != null && stack.isDockedStack() && stack.topTask() == tr) {
9261                             if (DEBUG_RECENTS) Slog.d(TAG_RECENTS,
9262                                     "Skipping, top task in docked stack: " + tr);
9263                             continue;
9264                         }
9265                     }
9266                     if ((flags & ActivityManager.RECENT_INGORE_PINNED_STACK_TASKS) != 0) {
9267                         if (tr.stack != null && tr.stack.isPinnedStack()) {
9268                             if (DEBUG_RECENTS) Slog.d(TAG_RECENTS,
9269                                     "Skipping, pinned stack task: " + tr);
9270                             continue;
9271                         }
9272                     }
9273                     if (tr.autoRemoveRecents && tr.getTopActivity() == null) {
9274                         // Don't include auto remove tasks that are finished or finishing.
9275                         if (DEBUG_RECENTS) Slog.d(TAG_RECENTS,
9276                                 "Skipping, auto-remove without activity: " + tr);
9277                         continue;
9278                     }
9279                     if ((flags&ActivityManager.RECENT_IGNORE_UNAVAILABLE) != 0
9280                             && !tr.isAvailable) {
9281                         if (DEBUG_RECENTS) Slog.d(TAG_RECENTS,
9282                                 "Skipping, unavail real act: " + tr);
9283                         continue;
9284                     }
9285
9286                     if (!tr.mUserSetupComplete) {
9287                         // Don't include task launched while user is not done setting-up.
9288                         if (DEBUG_RECENTS) Slog.d(TAG_RECENTS,
9289                                 "Skipping, user setup not complete: " + tr);
9290                         continue;
9291                     }
9292
9293                     ActivityManager.RecentTaskInfo rti = createRecentTaskInfoFromTaskRecord(tr);
9294                     if (!detailed) {
9295                         rti.baseIntent.replaceExtras((Bundle)null);
9296                     }
9297
9298                     res.add(rti);
9299                     maxNum--;
9300                 }
9301             }
9302             return new ParceledListSlice<>(res);
9303         }
9304     }
9305
9306     @Override
9307     public ActivityManager.TaskThumbnail getTaskThumbnail(int id) {
9308         synchronized (this) {
9309             enforceCallingPermission(android.Manifest.permission.READ_FRAME_BUFFER,
9310                     "getTaskThumbnail()");
9311             final TaskRecord tr = mStackSupervisor.anyTaskForIdLocked(
9312                     id, !RESTORE_FROM_RECENTS, INVALID_STACK_ID);
9313             if (tr != null) {
9314                 return tr.getTaskThumbnailLocked();
9315             }
9316         }
9317         return null;
9318     }
9319
9320     @Override
9321     public int addAppTask(IBinder activityToken, Intent intent,
9322             ActivityManager.TaskDescription description, Bitmap thumbnail) throws RemoteException {
9323         final int callingUid = Binder.getCallingUid();
9324         final long callingIdent = Binder.clearCallingIdentity();
9325
9326         try {
9327             synchronized (this) {
9328                 ActivityRecord r = ActivityRecord.isInStackLocked(activityToken);
9329                 if (r == null) {
9330                     throw new IllegalArgumentException("Activity does not exist; token="
9331                             + activityToken);
9332                 }
9333                 ComponentName comp = intent.getComponent();
9334                 if (comp == null) {
9335                     throw new IllegalArgumentException("Intent " + intent
9336                             + " must specify explicit component");
9337                 }
9338                 if (thumbnail.getWidth() != mThumbnailWidth
9339                         || thumbnail.getHeight() != mThumbnailHeight) {
9340                     throw new IllegalArgumentException("Bad thumbnail size: got "
9341                             + thumbnail.getWidth() + "x" + thumbnail.getHeight() + ", require "
9342                             + mThumbnailWidth + "x" + mThumbnailHeight);
9343                 }
9344                 if (intent.getSelector() != null) {
9345                     intent.setSelector(null);
9346                 }
9347                 if (intent.getSourceBounds() != null) {
9348                     intent.setSourceBounds(null);
9349                 }
9350                 if ((intent.getFlags()&Intent.FLAG_ACTIVITY_NEW_DOCUMENT) != 0) {
9351                     if ((intent.getFlags()&Intent.FLAG_ACTIVITY_RETAIN_IN_RECENTS) == 0) {
9352                         // The caller has added this as an auto-remove task...  that makes no
9353                         // sense, so turn off auto-remove.
9354                         intent.addFlags(Intent.FLAG_ACTIVITY_RETAIN_IN_RECENTS);
9355                     }
9356                 }
9357                 if (!comp.equals(mLastAddedTaskComponent) || callingUid != mLastAddedTaskUid) {
9358                     mLastAddedTaskActivity = null;
9359                 }
9360                 ActivityInfo ainfo = mLastAddedTaskActivity;
9361                 if (ainfo == null) {
9362                     ainfo = mLastAddedTaskActivity = AppGlobals.getPackageManager().getActivityInfo(
9363                             comp, 0, UserHandle.getUserId(callingUid));
9364                     if (ainfo.applicationInfo.uid != callingUid) {
9365                         throw new SecurityException(
9366                                 "Can't add task for another application: target uid="
9367                                 + ainfo.applicationInfo.uid + ", calling uid=" + callingUid);
9368                     }
9369                 }
9370
9371                 // Use the full screen as the context for the task thumbnail
9372                 final Point displaySize = new Point();
9373                 final TaskThumbnailInfo thumbnailInfo = new TaskThumbnailInfo();
9374                 r.task.stack.getDisplaySize(displaySize);
9375                 thumbnailInfo.taskWidth = displaySize.x;
9376                 thumbnailInfo.taskHeight = displaySize.y;
9377                 thumbnailInfo.screenOrientation = mConfiguration.orientation;
9378
9379                 TaskRecord task = new TaskRecord(this,
9380                         mStackSupervisor.getNextTaskIdForUserLocked(r.userId),
9381                         ainfo, intent, description, thumbnailInfo);
9382
9383                 int trimIdx = mRecentTasks.trimForTaskLocked(task, false);
9384                 if (trimIdx >= 0) {
9385                     // If this would have caused a trim, then we'll abort because that
9386                     // means it would be added at the end of the list but then just removed.
9387                     return INVALID_TASK_ID;
9388                 }
9389
9390                 final int N = mRecentTasks.size();
9391                 if (N >= (ActivityManager.getMaxRecentTasksStatic()-1)) {
9392                     final TaskRecord tr = mRecentTasks.remove(N - 1);
9393                     tr.removedFromRecents();
9394                 }
9395
9396                 task.inRecents = true;
9397                 mRecentTasks.add(task);
9398                 r.task.stack.addTask(task, false, "addAppTask");
9399
9400                 task.setLastThumbnailLocked(thumbnail);
9401                 task.freeLastThumbnail();
9402
9403                 return task.taskId;
9404             }
9405         } finally {
9406             Binder.restoreCallingIdentity(callingIdent);
9407         }
9408     }
9409
9410     @Override
9411     public Point getAppTaskThumbnailSize() {
9412         synchronized (this) {
9413             return new Point(mThumbnailWidth,  mThumbnailHeight);
9414         }
9415     }
9416
9417     @Override
9418     public void setTaskDescription(IBinder token, ActivityManager.TaskDescription td) {
9419         synchronized (this) {
9420             ActivityRecord r = ActivityRecord.isInStackLocked(token);
9421             if (r != null) {
9422                 r.setTaskDescription(td);
9423                 r.task.updateTaskDescription();
9424             }
9425         }
9426     }
9427
9428     @Override
9429     public void setTaskResizeable(int taskId, int resizeableMode) {
9430         synchronized (this) {
9431             final TaskRecord task = mStackSupervisor.anyTaskForIdLocked(
9432                     taskId, !RESTORE_FROM_RECENTS, INVALID_STACK_ID);
9433             if (task == null) {
9434                 Slog.w(TAG, "setTaskResizeable: taskId=" + taskId + " not found");
9435                 return;
9436             }
9437             if (task.mResizeMode != resizeableMode) {
9438                 task.mResizeMode = resizeableMode;
9439                 mWindowManager.setTaskResizeable(taskId, resizeableMode);
9440                 mStackSupervisor.ensureActivitiesVisibleLocked(null, 0, !PRESERVE_WINDOWS);
9441                 mStackSupervisor.resumeFocusedStackTopActivityLocked();
9442             }
9443         }
9444     }
9445
9446     @Override
9447     public void resizeTask(int taskId, Rect bounds, int resizeMode) {
9448         enforceCallingPermission(MANAGE_ACTIVITY_STACKS, "resizeTask()");
9449         long ident = Binder.clearCallingIdentity();
9450         try {
9451             synchronized (this) {
9452                 TaskRecord task = mStackSupervisor.anyTaskForIdLocked(taskId);
9453                 if (task == null) {
9454                     Slog.w(TAG, "resizeTask: taskId=" + taskId + " not found");
9455                     return;
9456                 }
9457                 int stackId = task.stack.mStackId;
9458                 // We allow the task to scroll instead of resizing if this is a non-resizeable task
9459                 // in crop windows resize mode or if the task size is affected by the docked stack
9460                 // changing size. No need to update configuration.
9461                 if (bounds != null && task.inCropWindowsResizeMode()
9462                         && mStackSupervisor.isStackDockedInEffect(stackId)) {
9463                     mWindowManager.scrollTask(task.taskId, bounds);
9464                     return;
9465                 }
9466
9467                 // Place the task in the right stack if it isn't there already based on
9468                 // the requested bounds.
9469                 // The stack transition logic is:
9470                 // - a null bounds on a freeform task moves that task to fullscreen
9471                 // - a non-null bounds on a non-freeform (fullscreen OR docked) task moves
9472                 //   that task to freeform
9473                 // - otherwise the task is not moved
9474                 if (!StackId.isTaskResizeAllowed(stackId)) {
9475                     throw new IllegalArgumentException("resizeTask not allowed on task=" + task);
9476                 }
9477                 if (bounds == null && stackId == FREEFORM_WORKSPACE_STACK_ID) {
9478                     stackId = FULLSCREEN_WORKSPACE_STACK_ID;
9479                 } else if (bounds != null && stackId != FREEFORM_WORKSPACE_STACK_ID ) {
9480                     stackId = FREEFORM_WORKSPACE_STACK_ID;
9481                 }
9482                 boolean preserveWindow = (resizeMode & RESIZE_MODE_PRESERVE_WINDOW) != 0;
9483                 if (stackId != task.stack.mStackId) {
9484                     mStackSupervisor.moveTaskToStackUncheckedLocked(
9485                             task, stackId, ON_TOP, !FORCE_FOCUS, "resizeTask");
9486                     preserveWindow = false;
9487                 }
9488
9489                 mStackSupervisor.resizeTaskLocked(task, bounds, resizeMode, preserveWindow,
9490                         false /* deferResume */);
9491             }
9492         } finally {
9493             Binder.restoreCallingIdentity(ident);
9494         }
9495     }
9496
9497     @Override
9498     public Rect getTaskBounds(int taskId) {
9499         enforceCallingPermission(MANAGE_ACTIVITY_STACKS, "getTaskBounds()");
9500         long ident = Binder.clearCallingIdentity();
9501         Rect rect = new Rect();
9502         try {
9503             synchronized (this) {
9504                 final TaskRecord task = mStackSupervisor.anyTaskForIdLocked(
9505                         taskId, !RESTORE_FROM_RECENTS, INVALID_STACK_ID);
9506                 if (task == null) {
9507                     Slog.w(TAG, "getTaskBounds: taskId=" + taskId + " not found");
9508                     return rect;
9509                 }
9510                 if (task.stack != null) {
9511                     // Return the bounds from window manager since it will be adjusted for various
9512                     // things like the presense of a docked stack for tasks that aren't resizeable.
9513                     mWindowManager.getTaskBounds(task.taskId, rect);
9514                 } else {
9515                     // Task isn't in window manager yet since it isn't associated with a stack.
9516                     // Return the persist value from activity manager
9517                     if (task.mBounds != null) {
9518                         rect.set(task.mBounds);
9519                     } else if (task.mLastNonFullscreenBounds != null) {
9520                         rect.set(task.mLastNonFullscreenBounds);
9521                     }
9522                 }
9523             }
9524         } finally {
9525             Binder.restoreCallingIdentity(ident);
9526         }
9527         return rect;
9528     }
9529
9530     @Override
9531     public Bitmap getTaskDescriptionIcon(String filePath, int userId) {
9532         if (userId != UserHandle.getCallingUserId()) {
9533             enforceCallingPermission(android.Manifest.permission.INTERACT_ACROSS_USERS_FULL,
9534                     "getTaskDescriptionIcon");
9535         }
9536         final File passedIconFile = new File(filePath);
9537         final File legitIconFile = new File(TaskPersister.getUserImagesDir(userId),
9538                 passedIconFile.getName());
9539         if (!legitIconFile.getPath().equals(filePath)
9540                 || !filePath.contains(ActivityRecord.ACTIVITY_ICON_SUFFIX)) {
9541             throw new IllegalArgumentException("Bad file path: " + filePath
9542                     + " passed for userId " + userId);
9543         }
9544         return mRecentTasks.getTaskDescriptionIcon(filePath);
9545     }
9546
9547     @Override
9548     public void startInPlaceAnimationOnFrontMostApplication(ActivityOptions opts)
9549             throws RemoteException {
9550         if (opts.getAnimationType() != ActivityOptions.ANIM_CUSTOM_IN_PLACE ||
9551                 opts.getCustomInPlaceResId() == 0) {
9552             throw new IllegalArgumentException("Expected in-place ActivityOption " +
9553                     "with valid animation");
9554         }
9555         mWindowManager.prepareAppTransition(TRANSIT_TASK_IN_PLACE, false);
9556         mWindowManager.overridePendingAppTransitionInPlace(opts.getPackageName(),
9557                 opts.getCustomInPlaceResId());
9558         mWindowManager.executeAppTransition();
9559     }
9560
9561     private void cleanUpRemovedTaskLocked(TaskRecord tr, boolean killProcess,
9562             boolean removeFromRecents) {
9563         if (removeFromRecents) {
9564             mRecentTasks.remove(tr);
9565             tr.removedFromRecents();
9566         }
9567         ComponentName component = tr.getBaseIntent().getComponent();
9568         if (component == null) {
9569             Slog.w(TAG, "No component for base intent of task: " + tr);
9570             return;
9571         }
9572
9573         // Find any running services associated with this app and stop if needed.
9574         mServices.cleanUpRemovedTaskLocked(tr, component, new Intent(tr.getBaseIntent()));
9575
9576         if (!killProcess) {
9577             return;
9578         }
9579
9580         // Determine if the process(es) for this task should be killed.
9581         final String pkg = component.getPackageName();
9582         ArrayList<ProcessRecord> procsToKill = new ArrayList<>();
9583         ArrayMap<String, SparseArray<ProcessRecord>> pmap = mProcessNames.getMap();
9584         for (int i = 0; i < pmap.size(); i++) {
9585
9586             SparseArray<ProcessRecord> uids = pmap.valueAt(i);
9587             for (int j = 0; j < uids.size(); j++) {
9588                 ProcessRecord proc = uids.valueAt(j);
9589                 if (proc.userId != tr.userId) {
9590                     // Don't kill process for a different user.
9591                     continue;
9592                 }
9593                 if (proc == mHomeProcess) {
9594                     // Don't kill the home process along with tasks from the same package.
9595                     continue;
9596                 }
9597                 if (!proc.pkgList.containsKey(pkg)) {
9598                     // Don't kill process that is not associated with this task.
9599                     continue;
9600                 }
9601
9602                 for (int k = 0; k < proc.activities.size(); k++) {
9603                     TaskRecord otherTask = proc.activities.get(k).task;
9604                     if (tr.taskId != otherTask.taskId && otherTask.inRecents) {
9605                         // Don't kill process(es) that has an activity in a different task that is
9606                         // also in recents.
9607                         return;
9608                     }
9609                 }
9610
9611                 if (proc.foregroundServices) {
9612                     // Don't kill process(es) with foreground service.
9613                     return;
9614                 }
9615
9616                 // Add process to kill list.
9617                 procsToKill.add(proc);
9618             }
9619         }
9620
9621         // Kill the running processes.
9622         for (int i = 0; i < procsToKill.size(); i++) {
9623             ProcessRecord pr = procsToKill.get(i);
9624             if (pr.setSchedGroup == ProcessList.SCHED_GROUP_BACKGROUND
9625                     && pr.curReceiver == null) {
9626                 pr.kill("remove task", true);
9627             } else {
9628                 // We delay killing processes that are not in the background or running a receiver.
9629                 pr.waitingToKill = "remove task";
9630             }
9631         }
9632     }
9633
9634     private void removeTasksByPackageNameLocked(String packageName, int userId) {
9635         // Remove all tasks with activities in the specified package from the list of recent tasks
9636         for (int i = mRecentTasks.size() - 1; i >= 0; i--) {
9637             TaskRecord tr = mRecentTasks.get(i);
9638             if (tr.userId != userId) continue;
9639
9640             ComponentName cn = tr.intent.getComponent();
9641             if (cn != null && cn.getPackageName().equals(packageName)) {
9642                 // If the package name matches, remove the task.
9643                 removeTaskByIdLocked(tr.taskId, true, REMOVE_FROM_RECENTS);
9644             }
9645         }
9646     }
9647
9648     private void cleanupDisabledPackageTasksLocked(String packageName, Set<String> filterByClasses,
9649             int userId) {
9650
9651         for (int i = mRecentTasks.size() - 1; i >= 0; i--) {
9652             TaskRecord tr = mRecentTasks.get(i);
9653             if (userId != UserHandle.USER_ALL && tr.userId != userId) {
9654                 continue;
9655             }
9656
9657             ComponentName cn = tr.intent.getComponent();
9658             final boolean sameComponent = cn != null && cn.getPackageName().equals(packageName)
9659                     && (filterByClasses == null || filterByClasses.contains(cn.getClassName()));
9660             if (sameComponent) {
9661                 removeTaskByIdLocked(tr.taskId, false, REMOVE_FROM_RECENTS);
9662             }
9663         }
9664     }
9665
9666     /**
9667      * Removes the task with the specified task id.
9668      *
9669      * @param taskId Identifier of the task to be removed.
9670      * @param killProcess Kill any process associated with the task if possible.
9671      * @param removeFromRecents Whether to also remove the task from recents.
9672      * @return Returns true if the given task was found and removed.
9673      */
9674     private boolean removeTaskByIdLocked(int taskId, boolean killProcess,
9675             boolean removeFromRecents) {
9676         final TaskRecord tr = mStackSupervisor.anyTaskForIdLocked(
9677                 taskId, !RESTORE_FROM_RECENTS, INVALID_STACK_ID);
9678         if (tr != null) {
9679             tr.removeTaskActivitiesLocked();
9680             cleanUpRemovedTaskLocked(tr, killProcess, removeFromRecents);
9681             if (tr.isPersistable) {
9682                 notifyTaskPersisterLocked(null, true);
9683             }
9684             return true;
9685         }
9686         Slog.w(TAG, "Request to remove task ignored for non-existent task " + taskId);
9687         return false;
9688     }
9689
9690     @Override
9691     public void removeStack(int stackId) {
9692         enforceCallingPermission(Manifest.permission.MANAGE_ACTIVITY_STACKS, "removeStack()");
9693         if (stackId == HOME_STACK_ID) {
9694             throw new IllegalArgumentException("Removing home stack is not allowed.");
9695         }
9696
9697         synchronized (this) {
9698             final long ident = Binder.clearCallingIdentity();
9699             try {
9700                 final ActivityStack stack = mStackSupervisor.getStack(stackId);
9701                 if (stack == null) {
9702                     return;
9703                 }
9704                 final ArrayList<TaskRecord> tasks = stack.getAllTasks();
9705                 for (int i = tasks.size() - 1; i >= 0; i--) {
9706                     removeTaskByIdLocked(
9707                             tasks.get(i).taskId, true /* killProcess */, REMOVE_FROM_RECENTS);
9708                 }
9709             } finally {
9710                 Binder.restoreCallingIdentity(ident);
9711             }
9712         }
9713     }
9714
9715     @Override
9716     public boolean removeTask(int taskId) {
9717         enforceCallingPermission(android.Manifest.permission.REMOVE_TASKS, "removeTask()");
9718         synchronized (this) {
9719             final long ident = Binder.clearCallingIdentity();
9720             try {
9721                 return removeTaskByIdLocked(taskId, true, REMOVE_FROM_RECENTS);
9722             } finally {
9723                 Binder.restoreCallingIdentity(ident);
9724             }
9725         }
9726     }
9727
9728     /**
9729      * TODO: Add mController hook
9730      */
9731     @Override
9732     public void moveTaskToFront(int taskId, int flags, Bundle bOptions) {
9733         enforceCallingPermission(android.Manifest.permission.REORDER_TASKS, "moveTaskToFront()");
9734
9735         if (DEBUG_STACK) Slog.d(TAG_STACK, "moveTaskToFront: moving taskId=" + taskId);
9736         synchronized(this) {
9737             moveTaskToFrontLocked(taskId, flags, bOptions);
9738         }
9739     }
9740
9741     void moveTaskToFrontLocked(int taskId, int flags, Bundle bOptions) {
9742         ActivityOptions options = ActivityOptions.fromBundle(bOptions);
9743
9744         if (!checkAppSwitchAllowedLocked(Binder.getCallingPid(),
9745                 Binder.getCallingUid(), -1, -1, "Task to front")) {
9746             ActivityOptions.abort(options);
9747             return;
9748         }
9749         final long origId = Binder.clearCallingIdentity();
9750         try {
9751             final TaskRecord task = mStackSupervisor.anyTaskForIdLocked(taskId);
9752             if (task == null) {
9753                 Slog.d(TAG, "Could not find task for id: "+ taskId);
9754                 return;
9755             }
9756             if (mStackSupervisor.isLockTaskModeViolation(task)) {
9757                 mStackSupervisor.showLockTaskToast();
9758                 Slog.e(TAG, "moveTaskToFront: Attempt to violate Lock Task Mode");
9759                 return;
9760             }
9761             final ActivityRecord prev = mStackSupervisor.topRunningActivityLocked();
9762             if (prev != null && prev.isRecentsActivity()) {
9763                 task.setTaskToReturnTo(ActivityRecord.RECENTS_ACTIVITY_TYPE);
9764             }
9765             mStackSupervisor.findTaskToMoveToFrontLocked(task, flags, options, "moveTaskToFront",
9766                     false /* forceNonResizable */);
9767         } finally {
9768             Binder.restoreCallingIdentity(origId);
9769         }
9770         ActivityOptions.abort(options);
9771     }
9772
9773     /**
9774      * Moves an activity, and all of the other activities within the same task, to the bottom
9775      * of the history stack.  The activity's order within the task is unchanged.
9776      *
9777      * @param token A reference to the activity we wish to move
9778      * @param nonRoot If false then this only works if the activity is the root
9779      *                of a task; if true it will work for any activity in a task.
9780      * @return Returns true if the move completed, false if not.
9781      */
9782     @Override
9783     public boolean moveActivityTaskToBack(IBinder token, boolean nonRoot) {
9784         enforceNotIsolatedCaller("moveActivityTaskToBack");
9785         synchronized(this) {
9786             final long origId = Binder.clearCallingIdentity();
9787             try {
9788                 int taskId = ActivityRecord.getTaskForActivityLocked(token, !nonRoot);
9789                 final TaskRecord task = mStackSupervisor.anyTaskForIdLocked(taskId);
9790                 if (task != null) {
9791                     if (mStackSupervisor.isLockedTask(task)) {
9792                         mStackSupervisor.showLockTaskToast();
9793                         return false;
9794                     }
9795                     return ActivityRecord.getStackLocked(token).moveTaskToBackLocked(taskId);
9796                 }
9797             } finally {
9798                 Binder.restoreCallingIdentity(origId);
9799             }
9800         }
9801         return false;
9802     }
9803
9804     @Override
9805     public void moveTaskBackwards(int task) {
9806         enforceCallingPermission(android.Manifest.permission.REORDER_TASKS,
9807                 "moveTaskBackwards()");
9808
9809         synchronized(this) {
9810             if (!checkAppSwitchAllowedLocked(Binder.getCallingPid(),
9811                     Binder.getCallingUid(), -1, -1, "Task backwards")) {
9812                 return;
9813             }
9814             final long origId = Binder.clearCallingIdentity();
9815             moveTaskBackwardsLocked(task);
9816             Binder.restoreCallingIdentity(origId);
9817         }
9818     }
9819
9820     private final void moveTaskBackwardsLocked(int task) {
9821         Slog.e(TAG, "moveTaskBackwards not yet implemented!");
9822     }
9823
9824     @Override
9825     public IActivityContainer createVirtualActivityContainer(IBinder parentActivityToken,
9826             IActivityContainerCallback callback) throws RemoteException {
9827         enforceCallingPermission(MANAGE_ACTIVITY_STACKS, "createActivityContainer()");
9828         synchronized (this) {
9829             if (parentActivityToken == null) {
9830                 throw new IllegalArgumentException("parent token must not be null");
9831             }
9832             ActivityRecord r = ActivityRecord.forTokenLocked(parentActivityToken);
9833             if (r == null) {
9834                 return null;
9835             }
9836             if (callback == null) {
9837                 throw new IllegalArgumentException("callback must not be null");
9838             }
9839             return mStackSupervisor.createVirtualActivityContainer(r, callback);
9840         }
9841     }
9842
9843     @Override
9844     public void deleteActivityContainer(IActivityContainer container) throws RemoteException {
9845         enforceCallingPermission(MANAGE_ACTIVITY_STACKS, "deleteActivityContainer()");
9846         synchronized (this) {
9847             mStackSupervisor.deleteActivityContainer(container);
9848         }
9849     }
9850
9851     @Override
9852     public IActivityContainer createStackOnDisplay(int displayId) throws RemoteException {
9853         enforceCallingPermission(MANAGE_ACTIVITY_STACKS, "createStackOnDisplay()");
9854         synchronized (this) {
9855             final int stackId = mStackSupervisor.getNextStackId();
9856             final ActivityStack stack =
9857                     mStackSupervisor.createStackOnDisplay(stackId, displayId, true /*onTop*/);
9858             if (stack == null) {
9859                 return null;
9860             }
9861             return stack.mActivityContainer;
9862         }
9863     }
9864
9865     @Override
9866     public int getActivityDisplayId(IBinder activityToken) throws RemoteException {
9867         synchronized (this) {
9868             ActivityStack stack = ActivityRecord.getStackLocked(activityToken);
9869             if (stack != null && stack.mActivityContainer.isAttachedLocked()) {
9870                 return stack.mActivityContainer.getDisplayId();
9871             }
9872             return Display.DEFAULT_DISPLAY;
9873         }
9874     }
9875
9876     @Override
9877     public int getActivityStackId(IBinder token) throws RemoteException {
9878         synchronized (this) {
9879             ActivityStack stack = ActivityRecord.getStackLocked(token);
9880             if (stack == null) {
9881                 return INVALID_STACK_ID;
9882             }
9883             return stack.mStackId;
9884         }
9885     }
9886
9887     @Override
9888     public void exitFreeformMode(IBinder token) throws RemoteException {
9889         synchronized (this) {
9890             long ident = Binder.clearCallingIdentity();
9891             try {
9892                 final ActivityRecord r = ActivityRecord.forTokenLocked(token);
9893                 if (r == null) {
9894                     throw new IllegalArgumentException(
9895                             "exitFreeformMode: No activity record matching token=" + token);
9896                 }
9897                 final ActivityStack stack = r.getStackLocked(token);
9898                 if (stack == null || stack.mStackId != FREEFORM_WORKSPACE_STACK_ID) {
9899                     throw new IllegalStateException(
9900                             "exitFreeformMode: You can only go fullscreen from freeform.");
9901                 }
9902                 if (DEBUG_STACK) Slog.d(TAG_STACK, "exitFreeformMode: " + r);
9903                 mStackSupervisor.moveTaskToStackLocked(r.task.taskId, FULLSCREEN_WORKSPACE_STACK_ID,
9904                         ON_TOP, !FORCE_FOCUS, "exitFreeformMode", ANIMATE);
9905             } finally {
9906                 Binder.restoreCallingIdentity(ident);
9907             }
9908         }
9909     }
9910
9911     @Override
9912     public void moveTaskToStack(int taskId, int stackId, boolean toTop) {
9913         enforceCallingPermission(MANAGE_ACTIVITY_STACKS, "moveTaskToStack()");
9914         if (stackId == HOME_STACK_ID) {
9915             throw new IllegalArgumentException(
9916                     "moveTaskToStack: Attempt to move task " + taskId + " to home stack");
9917         }
9918         synchronized (this) {
9919             long ident = Binder.clearCallingIdentity();
9920             try {
9921                 if (DEBUG_STACK) Slog.d(TAG_STACK, "moveTaskToStack: moving task=" + taskId
9922                         + " to stackId=" + stackId + " toTop=" + toTop);
9923                 if (stackId == DOCKED_STACK_ID) {
9924                     mWindowManager.setDockedStackCreateState(DOCKED_STACK_CREATE_MODE_TOP_OR_LEFT,
9925                             null /* initialBounds */);
9926                 }
9927                 boolean result = mStackSupervisor.moveTaskToStackLocked(taskId, stackId, toTop,
9928                         !FORCE_FOCUS, "moveTaskToStack", ANIMATE);
9929                 if (result && stackId == DOCKED_STACK_ID) {
9930                     // If task moved to docked stack - show recents if needed.
9931                     mStackSupervisor.moveHomeStackTaskToTop(RECENTS_ACTIVITY_TYPE,
9932                             "moveTaskToDockedStack");
9933                 }
9934             } finally {
9935                 Binder.restoreCallingIdentity(ident);
9936             }
9937         }
9938     }
9939
9940     @Override
9941     public void swapDockedAndFullscreenStack() throws RemoteException {
9942         enforceCallingPermission(MANAGE_ACTIVITY_STACKS, "swapDockedAndFullscreenStack()");
9943         synchronized (this) {
9944             long ident = Binder.clearCallingIdentity();
9945             try {
9946                 final ActivityStack fullscreenStack = mStackSupervisor.getStack(
9947                         FULLSCREEN_WORKSPACE_STACK_ID);
9948                 final TaskRecord topTask = fullscreenStack != null ? fullscreenStack.topTask()
9949                         : null;
9950                 final ActivityStack dockedStack = mStackSupervisor.getStack(DOCKED_STACK_ID);
9951                 final ArrayList<TaskRecord> tasks = dockedStack != null ? dockedStack.getAllTasks()
9952                         : null;
9953                 if (topTask == null || tasks == null || tasks.size() == 0) {
9954                     Slog.w(TAG,
9955                             "Unable to swap tasks, either docked or fullscreen stack is empty.");
9956                     return;
9957                 }
9958
9959                 // TODO: App transition
9960                 mWindowManager.prepareAppTransition(TRANSIT_ACTIVITY_RELAUNCH, false);
9961
9962                 // Defer the resume so resume/pausing while moving stacks is dangerous.
9963                 mStackSupervisor.moveTaskToStackLocked(topTask.taskId, DOCKED_STACK_ID,
9964                         false /* toTop */, !FORCE_FOCUS, "swapDockedAndFullscreenStack",
9965                         ANIMATE, true /* deferResume */);
9966                 final int size = tasks.size();
9967                 for (int i = 0; i < size; i++) {
9968                     final int id = tasks.get(i).taskId;
9969                     if (id == topTask.taskId) {
9970                         continue;
9971                     }
9972                     mStackSupervisor.moveTaskToStackLocked(id,
9973                             FULLSCREEN_WORKSPACE_STACK_ID, true /* toTop */, !FORCE_FOCUS,
9974                             "swapDockedAndFullscreenStack", ANIMATE, true /* deferResume */);
9975                 }
9976
9977                 // Because we deferred the resume, to avoid conflicts with stack switches while
9978                 // resuming, we need to do it after all the tasks are moved.
9979                 mStackSupervisor.ensureActivitiesVisibleLocked(null, 0, !PRESERVE_WINDOWS);
9980                 mStackSupervisor.resumeFocusedStackTopActivityLocked();
9981
9982                 mWindowManager.executeAppTransition();
9983             } finally {
9984                 Binder.restoreCallingIdentity(ident);
9985             }
9986         }
9987     }
9988
9989     /**
9990      * Moves the input task to the docked stack.
9991      *
9992      * @param taskId Id of task to move.
9993      * @param createMode The mode the docked stack should be created in if it doesn't exist
9994      *                   already. See
9995      *                   {@link android.app.ActivityManager#DOCKED_STACK_CREATE_MODE_TOP_OR_LEFT}
9996      *                   and
9997      *                   {@link android.app.ActivityManager#DOCKED_STACK_CREATE_MODE_BOTTOM_OR_RIGHT}
9998      * @param toTop If the task and stack should be moved to the top.
9999      * @param animate Whether we should play an animation for the moving the task
10000      * @param initialBounds If the docked stack gets created, it will use these bounds for the
10001      *                      docked stack. Pass {@code null} to use default bounds.
10002      */
10003     @Override
10004     public boolean moveTaskToDockedStack(int taskId, int createMode, boolean toTop, boolean animate,
10005             Rect initialBounds, boolean moveHomeStackFront) {
10006         enforceCallingPermission(MANAGE_ACTIVITY_STACKS, "moveTaskToDockedStack()");
10007         synchronized (this) {
10008             long ident = Binder.clearCallingIdentity();
10009             try {
10010                 if (DEBUG_STACK) Slog.d(TAG_STACK, "moveTaskToDockedStack: moving task=" + taskId
10011                         + " to createMode=" + createMode + " toTop=" + toTop);
10012                 mWindowManager.setDockedStackCreateState(createMode, initialBounds);
10013                 final boolean moved = mStackSupervisor.moveTaskToStackLocked(
10014                         taskId, DOCKED_STACK_ID, toTop, !FORCE_FOCUS, "moveTaskToDockedStack",
10015                         animate, DEFER_RESUME);
10016                 if (moved) {
10017                     if (moveHomeStackFront) {
10018                         mStackSupervisor.moveHomeStackToFront("moveTaskToDockedStack");
10019                     }
10020                     mStackSupervisor.ensureActivitiesVisibleLocked(null, 0, !PRESERVE_WINDOWS);
10021                 }
10022                 return moved;
10023             } finally {
10024                 Binder.restoreCallingIdentity(ident);
10025             }
10026         }
10027     }
10028
10029     /**
10030      * Moves the top activity in the input stackId to the pinned stack.
10031      *
10032      * @param stackId Id of stack to move the top activity to pinned stack.
10033      * @param bounds Bounds to use for pinned stack.
10034      *
10035      * @return True if the top activity of the input stack was successfully moved to the pinned
10036      *          stack.
10037      */
10038     @Override
10039     public boolean moveTopActivityToPinnedStack(int stackId, Rect bounds) {
10040         enforceCallingPermission(MANAGE_ACTIVITY_STACKS, "moveTopActivityToPinnedStack()");
10041         synchronized (this) {
10042             if (!mSupportsPictureInPicture) {
10043                 throw new IllegalStateException("moveTopActivityToPinnedStack:"
10044                         + "Device doesn't support picture-in-pciture mode");
10045             }
10046
10047             long ident = Binder.clearCallingIdentity();
10048             try {
10049                 return mStackSupervisor.moveTopStackActivityToPinnedStackLocked(stackId, bounds);
10050             } finally {
10051                 Binder.restoreCallingIdentity(ident);
10052             }
10053         }
10054     }
10055
10056     @Override
10057     public void resizeStack(int stackId, Rect bounds, boolean allowResizeInDockedMode,
10058             boolean preserveWindows, boolean animate, int animationDuration) {
10059         enforceCallingPermission(MANAGE_ACTIVITY_STACKS, "resizeStack()");
10060         long ident = Binder.clearCallingIdentity();
10061         try {
10062             synchronized (this) {
10063                 if (animate) {
10064                     if (stackId == PINNED_STACK_ID) {
10065                         mWindowManager.animateResizePinnedStack(bounds, animationDuration);
10066                     } else {
10067                         throw new IllegalArgumentException("Stack: " + stackId
10068                                 + " doesn't support animated resize.");
10069                     }
10070                 } else {
10071                     mStackSupervisor.resizeStackLocked(stackId, bounds, null /* tempTaskBounds */,
10072                             null /* tempTaskInsetBounds */, preserveWindows,
10073                             allowResizeInDockedMode, !DEFER_RESUME);
10074                 }
10075             }
10076         } finally {
10077             Binder.restoreCallingIdentity(ident);
10078         }
10079     }
10080
10081     @Override
10082     public void resizeDockedStack(Rect dockedBounds, Rect tempDockedTaskBounds,
10083             Rect tempDockedTaskInsetBounds,
10084             Rect tempOtherTaskBounds, Rect tempOtherTaskInsetBounds) {
10085         enforceCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS,
10086                 "resizeDockedStack()");
10087         long ident = Binder.clearCallingIdentity();
10088         try {
10089             synchronized (this) {
10090                 mStackSupervisor.resizeDockedStackLocked(dockedBounds, tempDockedTaskBounds,
10091                         tempDockedTaskInsetBounds, tempOtherTaskBounds, tempOtherTaskInsetBounds,
10092                         PRESERVE_WINDOWS);
10093             }
10094         } finally {
10095             Binder.restoreCallingIdentity(ident);
10096         }
10097     }
10098
10099     @Override
10100     public void resizePinnedStack(Rect pinnedBounds, Rect tempPinnedTaskBounds) {
10101         enforceCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS,
10102                 "resizePinnedStack()");
10103         final long ident = Binder.clearCallingIdentity();
10104         try {
10105             synchronized (this) {
10106                 mStackSupervisor.resizePinnedStackLocked(pinnedBounds, tempPinnedTaskBounds);
10107             }
10108         } finally {
10109             Binder.restoreCallingIdentity(ident);
10110         }
10111     }
10112
10113     @Override
10114     public void positionTaskInStack(int taskId, int stackId, int position) {
10115         enforceCallingPermission(MANAGE_ACTIVITY_STACKS, "positionTaskInStack()");
10116         if (stackId == HOME_STACK_ID) {
10117             throw new IllegalArgumentException(
10118                     "positionTaskInStack: Attempt to change the position of task "
10119                     + taskId + " in/to home stack");
10120         }
10121         synchronized (this) {
10122             long ident = Binder.clearCallingIdentity();
10123             try {
10124                 if (DEBUG_STACK) Slog.d(TAG_STACK,
10125                         "positionTaskInStack: positioning task=" + taskId
10126                         + " in stackId=" + stackId + " at position=" + position);
10127                 mStackSupervisor.positionTaskInStackLocked(taskId, stackId, position);
10128             } finally {
10129                 Binder.restoreCallingIdentity(ident);
10130             }
10131         }
10132     }
10133
10134     @Override
10135     public List<StackInfo> getAllStackInfos() {
10136         enforceCallingPermission(MANAGE_ACTIVITY_STACKS, "getAllStackInfos()");
10137         long ident = Binder.clearCallingIdentity();
10138         try {
10139             synchronized (this) {
10140                 return mStackSupervisor.getAllStackInfosLocked();
10141             }
10142         } finally {
10143             Binder.restoreCallingIdentity(ident);
10144         }
10145     }
10146
10147     @Override
10148     public StackInfo getStackInfo(int stackId) {
10149         enforceCallingPermission(MANAGE_ACTIVITY_STACKS, "getStackInfo()");
10150         long ident = Binder.clearCallingIdentity();
10151         try {
10152             synchronized (this) {
10153                 return mStackSupervisor.getStackInfoLocked(stackId);
10154             }
10155         } finally {
10156             Binder.restoreCallingIdentity(ident);
10157         }
10158     }
10159
10160     @Override
10161     public boolean isInHomeStack(int taskId) {
10162         enforceCallingPermission(MANAGE_ACTIVITY_STACKS, "getStackInfo()");
10163         long ident = Binder.clearCallingIdentity();
10164         try {
10165             synchronized (this) {
10166                 final TaskRecord tr = mStackSupervisor.anyTaskForIdLocked(
10167                         taskId, !RESTORE_FROM_RECENTS, INVALID_STACK_ID);
10168                 return tr != null && tr.stack != null && tr.stack.isHomeStack();
10169             }
10170         } finally {
10171             Binder.restoreCallingIdentity(ident);
10172         }
10173     }
10174
10175     @Override
10176     public int getTaskForActivity(IBinder token, boolean onlyRoot) {
10177         synchronized(this) {
10178             return ActivityRecord.getTaskForActivityLocked(token, onlyRoot);
10179         }
10180     }
10181
10182     @Override
10183     public void updateDeviceOwner(String packageName) {
10184         final int callingUid = Binder.getCallingUid();
10185         if (callingUid != 0 && callingUid != Process.SYSTEM_UID) {
10186             throw new SecurityException("updateDeviceOwner called from non-system process");
10187         }
10188         synchronized (this) {
10189             mDeviceOwnerName = packageName;
10190         }
10191     }
10192
10193     @Override
10194     public void updateLockTaskPackages(int userId, String[] packages) {
10195         final int callingUid = Binder.getCallingUid();
10196         if (callingUid != 0 && callingUid != Process.SYSTEM_UID) {
10197             enforceCallingPermission(android.Manifest.permission.UPDATE_LOCK_TASK_PACKAGES,
10198                     "updateLockTaskPackages()");
10199         }
10200         synchronized (this) {
10201             if (DEBUG_LOCKTASK) Slog.w(TAG_LOCKTASK, "Whitelisting " + userId + ":" +
10202                     Arrays.toString(packages));
10203             mLockTaskPackages.put(userId, packages);
10204             mStackSupervisor.onLockTaskPackagesUpdatedLocked();
10205         }
10206     }
10207
10208
10209     void startLockTaskModeLocked(TaskRecord task) {
10210         if (DEBUG_LOCKTASK) Slog.w(TAG_LOCKTASK, "startLockTaskModeLocked: " + task);
10211         if (task.mLockTaskAuth == LOCK_TASK_AUTH_DONT_LOCK) {
10212             return;
10213         }
10214
10215         // isSystemInitiated is used to distinguish between locked and pinned mode, as pinned mode
10216         // is initiated by system after the pinning request was shown and locked mode is initiated
10217         // by an authorized app directly
10218         final int callingUid = Binder.getCallingUid();
10219         boolean isSystemInitiated = callingUid == Process.SYSTEM_UID;
10220         long ident = Binder.clearCallingIdentity();
10221         try {
10222             if (!isSystemInitiated) {
10223                 task.mLockTaskUid = callingUid;
10224                 if (task.mLockTaskAuth == LOCK_TASK_AUTH_PINNABLE) {
10225                     // startLockTask() called by app and task mode is lockTaskModeDefault.
10226                     if (DEBUG_LOCKTASK) Slog.w(TAG_LOCKTASK, "Mode default, asking user");
10227                     StatusBarManagerInternal statusBarManager =
10228                             LocalServices.getService(StatusBarManagerInternal.class);
10229                     if (statusBarManager != null) {
10230                         statusBarManager.showScreenPinningRequest(task.taskId);
10231                     }
10232                     return;
10233                 }
10234
10235                 final ActivityStack stack = mStackSupervisor.getFocusedStack();
10236                 if (stack == null || task != stack.topTask()) {
10237                     throw new IllegalArgumentException("Invalid task, not in foreground");
10238                 }
10239             }
10240             if (DEBUG_LOCKTASK) Slog.w(TAG_LOCKTASK, isSystemInitiated ? "Locking pinned" :
10241                     "Locking fully");
10242             mStackSupervisor.setLockTaskModeLocked(task, isSystemInitiated ?
10243                     ActivityManager.LOCK_TASK_MODE_PINNED :
10244                     ActivityManager.LOCK_TASK_MODE_LOCKED,
10245                     "startLockTask", true);
10246         } finally {
10247             Binder.restoreCallingIdentity(ident);
10248         }
10249     }
10250
10251     @Override
10252     public void startLockTaskMode(int taskId) {
10253         synchronized (this) {
10254             final TaskRecord task = mStackSupervisor.anyTaskForIdLocked(taskId);
10255             if (task != null) {
10256                 startLockTaskModeLocked(task);
10257             }
10258         }
10259     }
10260
10261     @Override
10262     public void startLockTaskMode(IBinder token) {
10263         synchronized (this) {
10264             final ActivityRecord r = ActivityRecord.forTokenLocked(token);
10265             if (r == null) {
10266                 return;
10267             }
10268             final TaskRecord task = r.task;
10269             if (task != null) {
10270                 startLockTaskModeLocked(task);
10271             }
10272         }
10273     }
10274
10275     @Override
10276     public void startSystemLockTaskMode(int taskId) throws RemoteException {
10277         enforceCallingPermission(MANAGE_ACTIVITY_STACKS, "startSystemLockTaskMode");
10278         // This makes inner call to look as if it was initiated by system.
10279         long ident = Binder.clearCallingIdentity();
10280         try {
10281             synchronized (this) {
10282                 startLockTaskMode(taskId);
10283             }
10284         } finally {
10285             Binder.restoreCallingIdentity(ident);
10286         }
10287     }
10288
10289     @Override
10290     public void stopLockTaskMode() {
10291         final TaskRecord lockTask = mStackSupervisor.getLockedTaskLocked();
10292         if (lockTask == null) {
10293             // Our work here is done.
10294             return;
10295         }
10296
10297         final int callingUid = Binder.getCallingUid();
10298         final int lockTaskUid = lockTask.mLockTaskUid;
10299         final int lockTaskModeState = mStackSupervisor.getLockTaskModeState();
10300         if (lockTaskModeState == ActivityManager.LOCK_TASK_MODE_NONE) {
10301             // Done.
10302             return;
10303         } else {
10304             // Ensure the same caller for startLockTaskMode and stopLockTaskMode.
10305             // It is possible lockTaskMode was started by the system process because
10306             // android:lockTaskMode is set to a locking value in the application manifest
10307             // instead of the app calling startLockTaskMode. In this case
10308             // {@link TaskRecord.mLockTaskUid} will be 0, so we compare the callingUid to the
10309             // {@link TaskRecord.effectiveUid} instead. Also caller with
10310             // {@link MANAGE_ACTIVITY_STACKS} can stop any lock task.
10311             if (checkCallingPermission(MANAGE_ACTIVITY_STACKS) != PERMISSION_GRANTED
10312                     && callingUid != lockTaskUid
10313                     && (lockTaskUid != 0 || callingUid != lockTask.effectiveUid)) {
10314                 throw new SecurityException("Invalid uid, expected " + lockTaskUid
10315                         + " callingUid=" + callingUid + " effectiveUid=" + lockTask.effectiveUid);
10316             }
10317         }
10318         long ident = Binder.clearCallingIdentity();
10319         try {
10320             Log.d(TAG, "stopLockTaskMode");
10321             // Stop lock task
10322             synchronized (this) {
10323                 mStackSupervisor.setLockTaskModeLocked(null, ActivityManager.LOCK_TASK_MODE_NONE,
10324                         "stopLockTask", true);
10325             }
10326             TelecomManager tm = (TelecomManager) mContext.getSystemService(Context.TELECOM_SERVICE);
10327             if (tm != null) {
10328                 tm.showInCallScreen(false);
10329             }
10330         } finally {
10331             Binder.restoreCallingIdentity(ident);
10332         }
10333     }
10334
10335     /**
10336      * This API should be called by SystemUI only when user perform certain action to dismiss
10337      * lock task mode. We should only dismiss pinned lock task mode in this case.
10338      */
10339     @Override
10340     public void stopSystemLockTaskMode() throws RemoteException {
10341         if (mStackSupervisor.getLockTaskModeState() == ActivityManager.LOCK_TASK_MODE_PINNED) {
10342             stopLockTaskMode();
10343         } else {
10344             mStackSupervisor.showLockTaskToast();
10345         }
10346     }
10347
10348     @Override
10349     public boolean isInLockTaskMode() {
10350         return getLockTaskModeState() != ActivityManager.LOCK_TASK_MODE_NONE;
10351     }
10352
10353     @Override
10354     public int getLockTaskModeState() {
10355         synchronized (this) {
10356             return mStackSupervisor.getLockTaskModeState();
10357         }
10358     }
10359
10360     @Override
10361     public void showLockTaskEscapeMessage(IBinder token) {
10362         synchronized (this) {
10363             final ActivityRecord r = ActivityRecord.forTokenLocked(token);
10364             if (r == null) {
10365                 return;
10366             }
10367             mStackSupervisor.showLockTaskEscapeMessageLocked(r.task);
10368         }
10369     }
10370
10371     // =========================================================
10372     // CONTENT PROVIDERS
10373     // =========================================================
10374
10375     private final List<ProviderInfo> generateApplicationProvidersLocked(ProcessRecord app) {
10376         List<ProviderInfo> providers = null;
10377         try {
10378             providers = AppGlobals.getPackageManager()
10379                     .queryContentProviders(app.processName, app.uid,
10380                             STOCK_PM_FLAGS | PackageManager.GET_URI_PERMISSION_PATTERNS
10381                                     | MATCH_DEBUG_TRIAGED_MISSING)
10382                     .getList();
10383         } catch (RemoteException ex) {
10384         }
10385         if (DEBUG_MU) Slog.v(TAG_MU,
10386                 "generateApplicationProvidersLocked, app.info.uid = " + app.uid);
10387         int userId = app.userId;
10388         if (providers != null) {
10389             int N = providers.size();
10390             app.pubProviders.ensureCapacity(N + app.pubProviders.size());
10391             for (int i=0; i<N; i++) {
10392                 // TODO: keep logic in sync with installEncryptionUnawareProviders
10393                 ProviderInfo cpi =
10394                     (ProviderInfo)providers.get(i);
10395                 boolean singleton = isSingleton(cpi.processName, cpi.applicationInfo,
10396                         cpi.name, cpi.flags);
10397                 if (singleton && UserHandle.getUserId(app.uid) != UserHandle.USER_SYSTEM) {
10398                     // This is a singleton provider, but a user besides the
10399                     // default user is asking to initialize a process it runs
10400                     // in...  well, no, it doesn't actually run in this process,
10401                     // it runs in the process of the default user.  Get rid of it.
10402                     providers.remove(i);
10403                     N--;
10404                     i--;
10405                     continue;
10406                 }
10407
10408                 ComponentName comp = new ComponentName(cpi.packageName, cpi.name);
10409                 ContentProviderRecord cpr = mProviderMap.getProviderByClass(comp, userId);
10410                 if (cpr == null) {
10411                     cpr = new ContentProviderRecord(this, cpi, app.info, comp, singleton);
10412                     mProviderMap.putProviderByClass(comp, cpr);
10413                 }
10414                 if (DEBUG_MU) Slog.v(TAG_MU,
10415                         "generateApplicationProvidersLocked, cpi.uid = " + cpr.uid);
10416                 app.pubProviders.put(cpi.name, cpr);
10417                 if (!cpi.multiprocess || !"android".equals(cpi.packageName)) {
10418                     // Don't add this if it is a platform component that is marked
10419                     // to run in multiple processes, because this is actually
10420                     // part of the framework so doesn't make sense to track as a
10421                     // separate apk in the process.
10422                     app.addPackage(cpi.applicationInfo.packageName, cpi.applicationInfo.versionCode,
10423                             mProcessStats);
10424                 }
10425                 notifyPackageUse(cpi.applicationInfo.packageName,
10426                                  PackageManager.NOTIFY_PACKAGE_USE_CONTENT_PROVIDER);
10427             }
10428         }
10429         return providers;
10430     }
10431
10432     /**
10433      * Check if the calling UID has a possible chance at accessing the provider
10434      * at the given authority and user.
10435      */
10436     public String checkContentProviderAccess(String authority, int userId) {
10437         if (userId == UserHandle.USER_ALL) {
10438             mContext.enforceCallingOrSelfPermission(
10439                     Manifest.permission.INTERACT_ACROSS_USERS_FULL, TAG);
10440             userId = UserHandle.getCallingUserId();
10441         }
10442
10443         ProviderInfo cpi = null;
10444         try {
10445             cpi = AppGlobals.getPackageManager().resolveContentProvider(authority,
10446                     STOCK_PM_FLAGS | PackageManager.GET_URI_PERMISSION_PATTERNS
10447                             | PackageManager.MATCH_DIRECT_BOOT_AWARE
10448                             | PackageManager.MATCH_DIRECT_BOOT_UNAWARE,
10449                     userId);
10450         } catch (RemoteException ignored) {
10451         }
10452         if (cpi == null) {
10453             // TODO: make this an outright failure in a future platform release;
10454             // until then anonymous content notifications are unprotected
10455             //return "Failed to find provider " + authority + " for user " + userId;
10456             return null;
10457         }
10458
10459         ProcessRecord r = null;
10460         synchronized (mPidsSelfLocked) {
10461             r = mPidsSelfLocked.get(Binder.getCallingPid());
10462         }
10463         if (r == null) {
10464             return "Failed to find PID " + Binder.getCallingPid();
10465         }
10466
10467         synchronized (this) {
10468             return checkContentProviderPermissionLocked(cpi, r, userId, true);
10469         }
10470     }
10471
10472     /**
10473      * Check if {@link ProcessRecord} has a possible chance at accessing the
10474      * given {@link ProviderInfo}. Final permission checking is always done
10475      * in {@link ContentProvider}.
10476      */
10477     private final String checkContentProviderPermissionLocked(
10478             ProviderInfo cpi, ProcessRecord r, int userId, boolean checkUser) {
10479         final int callingPid = (r != null) ? r.pid : Binder.getCallingPid();
10480         final int callingUid = (r != null) ? r.uid : Binder.getCallingUid();
10481         boolean checkedGrants = false;
10482         if (checkUser) {
10483             // Looking for cross-user grants before enforcing the typical cross-users permissions
10484             int tmpTargetUserId = mUserController.unsafeConvertIncomingUserLocked(userId);
10485             if (tmpTargetUserId != UserHandle.getUserId(callingUid)) {
10486                 if (checkAuthorityGrants(callingUid, cpi, tmpTargetUserId, checkUser)) {
10487                     return null;
10488                 }
10489                 checkedGrants = true;
10490             }
10491             userId = mUserController.handleIncomingUser(callingPid, callingUid, userId, false,
10492                     ALLOW_NON_FULL, "checkContentProviderPermissionLocked " + cpi.authority, null);
10493             if (userId != tmpTargetUserId) {
10494                 // When we actually went to determine the final targer user ID, this ended
10495                 // up different than our initial check for the authority.  This is because
10496                 // they had asked for USER_CURRENT_OR_SELF and we ended up switching to
10497                 // SELF.  So we need to re-check the grants again.
10498                 checkedGrants = false;
10499             }
10500         }
10501         if (checkComponentPermission(cpi.readPermission, callingPid, callingUid,
10502                 cpi.applicationInfo.uid, cpi.exported)
10503                 == PackageManager.PERMISSION_GRANTED) {
10504             return null;
10505         }
10506         if (checkComponentPermission(cpi.writePermission, callingPid, callingUid,
10507                 cpi.applicationInfo.uid, cpi.exported)
10508                 == PackageManager.PERMISSION_GRANTED) {
10509             return null;
10510         }
10511
10512         PathPermission[] pps = cpi.pathPermissions;
10513         if (pps != null) {
10514             int i = pps.length;
10515             while (i > 0) {
10516                 i--;
10517                 PathPermission pp = pps[i];
10518                 String pprperm = pp.getReadPermission();
10519                 if (pprperm != null && checkComponentPermission(pprperm, callingPid, callingUid,
10520                         cpi.applicationInfo.uid, cpi.exported)
10521                         == PackageManager.PERMISSION_GRANTED) {
10522                     return null;
10523                 }
10524                 String ppwperm = pp.getWritePermission();
10525                 if (ppwperm != null && checkComponentPermission(ppwperm, callingPid, callingUid,
10526                         cpi.applicationInfo.uid, cpi.exported)
10527                         == PackageManager.PERMISSION_GRANTED) {
10528                     return null;
10529                 }
10530             }
10531         }
10532         if (!checkedGrants && checkAuthorityGrants(callingUid, cpi, userId, checkUser)) {
10533             return null;
10534         }
10535
10536         String msg;
10537         if (!cpi.exported) {
10538             msg = "Permission Denial: opening provider " + cpi.name
10539                     + " from " + (r != null ? r : "(null)") + " (pid=" + callingPid
10540                     + ", uid=" + callingUid + ") that is not exported from uid "
10541                     + cpi.applicationInfo.uid;
10542         } else {
10543             msg = "Permission Denial: opening provider " + cpi.name
10544                     + " from " + (r != null ? r : "(null)") + " (pid=" + callingPid
10545                     + ", uid=" + callingUid + ") requires "
10546                     + cpi.readPermission + " or " + cpi.writePermission;
10547         }
10548         Slog.w(TAG, msg);
10549         return msg;
10550     }
10551
10552     /**
10553      * Returns if the ContentProvider has granted a uri to callingUid
10554      */
10555     boolean checkAuthorityGrants(int callingUid, ProviderInfo cpi, int userId, boolean checkUser) {
10556         final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.get(callingUid);
10557         if (perms != null) {
10558             for (int i=perms.size()-1; i>=0; i--) {
10559                 GrantUri grantUri = perms.keyAt(i);
10560                 if (grantUri.sourceUserId == userId || !checkUser) {
10561                     if (matchesProvider(grantUri.uri, cpi)) {
10562                         return true;
10563                     }
10564                 }
10565             }
10566         }
10567         return false;
10568     }
10569
10570     /**
10571      * Returns true if the uri authority is one of the authorities specified in the provider.
10572      */
10573     boolean matchesProvider(Uri uri, ProviderInfo cpi) {
10574         String uriAuth = uri.getAuthority();
10575         String cpiAuth = cpi.authority;
10576         if (cpiAuth.indexOf(';') == -1) {
10577             return cpiAuth.equals(uriAuth);
10578         }
10579         String[] cpiAuths = cpiAuth.split(";");
10580         int length = cpiAuths.length;
10581         for (int i = 0; i < length; i++) {
10582             if (cpiAuths[i].equals(uriAuth)) return true;
10583         }
10584         return false;
10585     }
10586
10587     ContentProviderConnection incProviderCountLocked(ProcessRecord r,
10588             final ContentProviderRecord cpr, IBinder externalProcessToken, boolean stable) {
10589         if (r != null) {
10590             for (int i=0; i<r.conProviders.size(); i++) {
10591                 ContentProviderConnection conn = r.conProviders.get(i);
10592                 if (conn.provider == cpr) {
10593                     if (DEBUG_PROVIDER) Slog.v(TAG_PROVIDER,
10594                             "Adding provider requested by "
10595                             + r.processName + " from process "
10596                             + cpr.info.processName + ": " + cpr.name.flattenToShortString()
10597                             + " scnt=" + conn.stableCount + " uscnt=" + conn.unstableCount);
10598                     if (stable) {
10599                         conn.stableCount++;
10600                         conn.numStableIncs++;
10601                     } else {
10602                         conn.unstableCount++;
10603                         conn.numUnstableIncs++;
10604                     }
10605                     return conn;
10606                 }
10607             }
10608             ContentProviderConnection conn = new ContentProviderConnection(cpr, r);
10609             if (stable) {
10610                 conn.stableCount = 1;
10611                 conn.numStableIncs = 1;
10612             } else {
10613                 conn.unstableCount = 1;
10614                 conn.numUnstableIncs = 1;
10615             }
10616             cpr.connections.add(conn);
10617             r.conProviders.add(conn);
10618             startAssociationLocked(r.uid, r.processName, r.curProcState,
10619                     cpr.uid, cpr.name, cpr.info.processName);
10620             return conn;
10621         }
10622         cpr.addExternalProcessHandleLocked(externalProcessToken);
10623         return null;
10624     }
10625
10626     boolean decProviderCountLocked(ContentProviderConnection conn,
10627             ContentProviderRecord cpr, IBinder externalProcessToken, boolean stable) {
10628         if (conn != null) {
10629             cpr = conn.provider;
10630             if (DEBUG_PROVIDER) Slog.v(TAG_PROVIDER,
10631                     "Removing provider requested by "
10632                     + conn.client.processName + " from process "
10633                     + cpr.info.processName + ": " + cpr.name.flattenToShortString()
10634                     + " scnt=" + conn.stableCount + " uscnt=" + conn.unstableCount);
10635             if (stable) {
10636                 conn.stableCount--;
10637             } else {
10638                 conn.unstableCount--;
10639             }
10640             if (conn.stableCount == 0 && conn.unstableCount == 0) {
10641                 cpr.connections.remove(conn);
10642                 conn.client.conProviders.remove(conn);
10643                 if (conn.client.setProcState < ActivityManager.PROCESS_STATE_LAST_ACTIVITY) {
10644                     // The client is more important than last activity -- note the time this
10645                     // is happening, so we keep the old provider process around a bit as last
10646                     // activity to avoid thrashing it.
10647                     if (cpr.proc != null) {
10648                         cpr.proc.lastProviderTime = SystemClock.uptimeMillis();
10649                     }
10650                 }
10651                 stopAssociationLocked(conn.client.uid, conn.client.processName, cpr.uid, cpr.name);
10652                 return true;
10653             }
10654             return false;
10655         }
10656         cpr.removeExternalProcessHandleLocked(externalProcessToken);
10657         return false;
10658     }
10659
10660     private void checkTime(long startTime, String where) {
10661         long now = SystemClock.uptimeMillis();
10662         if ((now-startTime) > 50) {
10663             // If we are taking more than 50ms, log about it.
10664             Slog.w(TAG, "Slow operation: " + (now-startTime) + "ms so far, now at " + where);
10665         }
10666     }
10667
10668     private static final int[] PROCESS_STATE_STATS_FORMAT = new int[] {
10669             PROC_SPACE_TERM,
10670             PROC_SPACE_TERM|PROC_PARENS,
10671             PROC_SPACE_TERM|PROC_CHAR|PROC_OUT_LONG,        // 3: process state
10672     };
10673
10674     private final long[] mProcessStateStatsLongs = new long[1];
10675
10676     boolean isProcessAliveLocked(ProcessRecord proc) {
10677         if (proc.procStatFile == null) {
10678             proc.procStatFile = "/proc/" + proc.pid + "/stat";
10679         }
10680         mProcessStateStatsLongs[0] = 0;
10681         if (!Process.readProcFile(proc.procStatFile, PROCESS_STATE_STATS_FORMAT, null,
10682                 mProcessStateStatsLongs, null)) {
10683             if (DEBUG_OOM_ADJ) Slog.d(TAG, "UNABLE TO RETRIEVE STATE FOR " + proc.procStatFile);
10684             return false;
10685         }
10686         final long state = mProcessStateStatsLongs[0];
10687         if (DEBUG_OOM_ADJ) Slog.d(TAG, "RETRIEVED STATE FOR " + proc.procStatFile + ": "
10688                 + (char)state);
10689         return state != 'Z' && state != 'X' && state != 'x' && state != 'K';
10690     }
10691
10692     private ContentProviderHolder getContentProviderImpl(IApplicationThread caller,
10693             String name, IBinder token, boolean stable, int userId) {
10694         ContentProviderRecord cpr;
10695         ContentProviderConnection conn = null;
10696         ProviderInfo cpi = null;
10697
10698         synchronized(this) {
10699             long startTime = SystemClock.uptimeMillis();
10700
10701             ProcessRecord r = null;
10702             if (caller != null) {
10703                 r = getRecordForAppLocked(caller);
10704                 if (r == null) {
10705                     throw new SecurityException(
10706                             "Unable to find app for caller " + caller
10707                           + " (pid=" + Binder.getCallingPid()
10708                           + ") when getting content provider " + name);
10709                 }
10710             }
10711
10712             boolean checkCrossUser = true;
10713
10714             checkTime(startTime, "getContentProviderImpl: getProviderByName");
10715
10716             // First check if this content provider has been published...
10717             cpr = mProviderMap.getProviderByName(name, userId);
10718             // If that didn't work, check if it exists for user 0 and then
10719             // verify that it's a singleton provider before using it.
10720             if (cpr == null && userId != UserHandle.USER_SYSTEM) {
10721                 cpr = mProviderMap.getProviderByName(name, UserHandle.USER_SYSTEM);
10722                 if (cpr != null) {
10723                     cpi = cpr.info;
10724                     if (isSingleton(cpi.processName, cpi.applicationInfo,
10725                             cpi.name, cpi.flags)
10726                             && isValidSingletonCall(r.uid, cpi.applicationInfo.uid)) {
10727                         userId = UserHandle.USER_SYSTEM;
10728                         checkCrossUser = false;
10729                     } else {
10730                         cpr = null;
10731                         cpi = null;
10732                     }
10733                 }
10734             }
10735
10736             boolean providerRunning = cpr != null && cpr.proc != null && !cpr.proc.killed;
10737             if (providerRunning) {
10738                 cpi = cpr.info;
10739                 String msg;
10740                 checkTime(startTime, "getContentProviderImpl: before checkContentProviderPermission");
10741                 if ((msg = checkContentProviderPermissionLocked(cpi, r, userId, checkCrossUser))
10742                         != null) {
10743                     throw new SecurityException(msg);
10744                 }
10745                 checkTime(startTime, "getContentProviderImpl: after checkContentProviderPermission");
10746
10747                 if (r != null && cpr.canRunHere(r)) {
10748                     // This provider has been published or is in the process
10749                     // of being published...  but it is also allowed to run
10750                     // in the caller's process, so don't make a connection
10751                     // and just let the caller instantiate its own instance.
10752                     ContentProviderHolder holder = cpr.newHolder(null);
10753                     // don't give caller the provider object, it needs
10754                     // to make its own.
10755                     holder.provider = null;
10756                     return holder;
10757                 }
10758
10759                 final long origId = Binder.clearCallingIdentity();
10760
10761                 checkTime(startTime, "getContentProviderImpl: incProviderCountLocked");
10762
10763                 // In this case the provider instance already exists, so we can
10764                 // return it right away.
10765                 conn = incProviderCountLocked(r, cpr, token, stable);
10766                 if (conn != null && (conn.stableCount+conn.unstableCount) == 1) {
10767                     if (cpr.proc != null && r.setAdj <= ProcessList.PERCEPTIBLE_APP_ADJ) {
10768                         // If this is a perceptible app accessing the provider,
10769                         // make sure to count it as being accessed and thus
10770                         // back up on the LRU list.  This is good because
10771                         // content providers are often expensive to start.
10772                         checkTime(startTime, "getContentProviderImpl: before updateLruProcess");
10773                         updateLruProcessLocked(cpr.proc, false, null);
10774                         checkTime(startTime, "getContentProviderImpl: after updateLruProcess");
10775                     }
10776                 }
10777
10778                 checkTime(startTime, "getContentProviderImpl: before updateOomAdj");
10779                 final int verifiedAdj = cpr.proc.verifiedAdj;
10780                 boolean success = updateOomAdjLocked(cpr.proc);
10781                 // XXX things have changed so updateOomAdjLocked doesn't actually tell us
10782                 // if the process has been successfully adjusted.  So to reduce races with
10783                 // it, we will check whether the process still exists.  Note that this doesn't
10784                 // completely get rid of races with LMK killing the process, but should make
10785                 // them much smaller.
10786                 if (success && verifiedAdj != cpr.proc.setAdj && !isProcessAliveLocked(cpr.proc)) {
10787                     success = false;
10788                 }
10789                 maybeUpdateProviderUsageStatsLocked(r, cpr.info.packageName, name);
10790                 checkTime(startTime, "getContentProviderImpl: after updateOomAdj");
10791                 if (DEBUG_PROVIDER) Slog.i(TAG_PROVIDER, "Adjust success: " + success);
10792                 // NOTE: there is still a race here where a signal could be
10793                 // pending on the process even though we managed to update its
10794                 // adj level.  Not sure what to do about this, but at least
10795                 // the race is now smaller.
10796                 if (!success) {
10797                     // Uh oh...  it looks like the provider's process
10798                     // has been killed on us.  We need to wait for a new
10799                     // process to be started, and make sure its death
10800                     // doesn't kill our process.
10801                     Slog.i(TAG, "Existing provider " + cpr.name.flattenToShortString()
10802                             + " is crashing; detaching " + r);
10803                     boolean lastRef = decProviderCountLocked(conn, cpr, token, stable);
10804                     checkTime(startTime, "getContentProviderImpl: before appDied");
10805                     appDiedLocked(cpr.proc);
10806                     checkTime(startTime, "getContentProviderImpl: after appDied");
10807                     if (!lastRef) {
10808                         // This wasn't the last ref our process had on
10809                         // the provider...  we have now been killed, bail.
10810                         return null;
10811                     }
10812                     providerRunning = false;
10813                     conn = null;
10814                 } else {
10815                     cpr.proc.verifiedAdj = cpr.proc.setAdj;
10816                 }
10817
10818                 Binder.restoreCallingIdentity(origId);
10819             }
10820
10821             if (!providerRunning) {
10822                 try {
10823                     checkTime(startTime, "getContentProviderImpl: before resolveContentProvider");
10824                     cpi = AppGlobals.getPackageManager().
10825                         resolveContentProvider(name,
10826                             STOCK_PM_FLAGS | PackageManager.GET_URI_PERMISSION_PATTERNS, userId);
10827                     checkTime(startTime, "getContentProviderImpl: after resolveContentProvider");
10828                 } catch (RemoteException ex) {
10829                 }
10830                 if (cpi == null) {
10831                     return null;
10832                 }
10833                 // If the provider is a singleton AND
10834                 // (it's a call within the same user || the provider is a
10835                 // privileged app)
10836                 // Then allow connecting to the singleton provider
10837                 boolean singleton = isSingleton(cpi.processName, cpi.applicationInfo,
10838                         cpi.name, cpi.flags)
10839                         && isValidSingletonCall(r.uid, cpi.applicationInfo.uid);
10840                 if (singleton) {
10841                     userId = UserHandle.USER_SYSTEM;
10842                 }
10843                 cpi.applicationInfo = getAppInfoForUser(cpi.applicationInfo, userId);
10844                 checkTime(startTime, "getContentProviderImpl: got app info for user");
10845
10846                 String msg;
10847                 checkTime(startTime, "getContentProviderImpl: before checkContentProviderPermission");
10848                 if ((msg = checkContentProviderPermissionLocked(cpi, r, userId, !singleton))
10849                         != null) {
10850                     throw new SecurityException(msg);
10851                 }
10852                 checkTime(startTime, "getContentProviderImpl: after checkContentProviderPermission");
10853
10854                 if (!mProcessesReady
10855                         && !cpi.processName.equals("system")) {
10856                     // If this content provider does not run in the system
10857                     // process, and the system is not yet ready to run other
10858                     // processes, then fail fast instead of hanging.
10859                     throw new IllegalArgumentException(
10860                             "Attempt to launch content provider before system ready");
10861                 }
10862
10863                 // Make sure that the user who owns this provider is running.  If not,
10864                 // we don't want to allow it to run.
10865                 if (!mUserController.isUserRunningLocked(userId, 0)) {
10866                     Slog.w(TAG, "Unable to launch app "
10867                             + cpi.applicationInfo.packageName + "/"
10868                             + cpi.applicationInfo.uid + " for provider "
10869                             + name + ": user " + userId + " is stopped");
10870                     return null;
10871                 }
10872
10873                 ComponentName comp = new ComponentName(cpi.packageName, cpi.name);
10874                 checkTime(startTime, "getContentProviderImpl: before getProviderByClass");
10875                 cpr = mProviderMap.getProviderByClass(comp, userId);
10876                 checkTime(startTime, "getContentProviderImpl: after getProviderByClass");
10877                 final boolean firstClass = cpr == null;
10878                 if (firstClass) {
10879                     final long ident = Binder.clearCallingIdentity();
10880
10881                     // If permissions need a review before any of the app components can run,
10882                     // we return no provider and launch a review activity if the calling app
10883                     // is in the foreground.
10884                     if (mPermissionReviewRequired || Build.PERMISSIONS_REVIEW_REQUIRED) {
10885                         if (!requestTargetProviderPermissionsReviewIfNeededLocked(cpi, r, userId)) {
10886                             return null;
10887                         }
10888                     }
10889
10890                     try {
10891                         checkTime(startTime, "getContentProviderImpl: before getApplicationInfo");
10892                         ApplicationInfo ai =
10893                             AppGlobals.getPackageManager().
10894                                 getApplicationInfo(
10895                                         cpi.applicationInfo.packageName,
10896                                         STOCK_PM_FLAGS, userId);
10897                         checkTime(startTime, "getContentProviderImpl: after getApplicationInfo");
10898                         if (ai == null) {
10899                             Slog.w(TAG, "No package info for content provider "
10900                                     + cpi.name);
10901                             return null;
10902                         }
10903                         ai = getAppInfoForUser(ai, userId);
10904                         cpr = new ContentProviderRecord(this, cpi, ai, comp, singleton);
10905                     } catch (RemoteException ex) {
10906                         // pm is in same process, this will never happen.
10907                     } finally {
10908                         Binder.restoreCallingIdentity(ident);
10909                     }
10910                 }
10911
10912                 checkTime(startTime, "getContentProviderImpl: now have ContentProviderRecord");
10913
10914                 if (r != null && cpr.canRunHere(r)) {
10915                     // If this is a multiprocess provider, then just return its
10916                     // info and allow the caller to instantiate it.  Only do
10917                     // this if the provider is the same user as the caller's
10918                     // process, or can run as root (so can be in any process).
10919                     return cpr.newHolder(null);
10920                 }
10921
10922                 if (DEBUG_PROVIDER) Slog.w(TAG_PROVIDER, "LAUNCHING REMOTE PROVIDER (myuid "
10923                             + (r != null ? r.uid : null) + " pruid " + cpr.appInfo.uid + "): "
10924                             + cpr.info.name + " callers=" + Debug.getCallers(6));
10925
10926                 // This is single process, and our app is now connecting to it.
10927                 // See if we are already in the process of launching this
10928                 // provider.
10929                 final int N = mLaunchingProviders.size();
10930                 int i;
10931                 for (i = 0; i < N; i++) {
10932                     if (mLaunchingProviders.get(i) == cpr) {
10933                         break;
10934                     }
10935                 }
10936
10937                 // If the provider is not already being launched, then get it
10938                 // started.
10939                 if (i >= N) {
10940                     final long origId = Binder.clearCallingIdentity();
10941
10942                     try {
10943                         // Content provider is now in use, its package can't be stopped.
10944                         try {
10945                             checkTime(startTime, "getContentProviderImpl: before set stopped state");
10946                             AppGlobals.getPackageManager().setPackageStoppedState(
10947                                     cpr.appInfo.packageName, false, userId);
10948                             checkTime(startTime, "getContentProviderImpl: after set stopped state");
10949                         } catch (RemoteException e) {
10950                         } catch (IllegalArgumentException e) {
10951                             Slog.w(TAG, "Failed trying to unstop package "
10952                                     + cpr.appInfo.packageName + ": " + e);
10953                         }
10954
10955                         // Use existing process if already started
10956                         checkTime(startTime, "getContentProviderImpl: looking for process record");
10957                         ProcessRecord proc = getProcessRecordLocked(
10958                                 cpi.processName, cpr.appInfo.uid, false);
10959                         if (proc != null && proc.thread != null && !proc.killed) {
10960                             if (DEBUG_PROVIDER) Slog.d(TAG_PROVIDER,
10961                                     "Installing in existing process " + proc);
10962                             if (!proc.pubProviders.containsKey(cpi.name)) {
10963                                 checkTime(startTime, "getContentProviderImpl: scheduling install");
10964                                 proc.pubProviders.put(cpi.name, cpr);
10965                                 try {
10966                                     proc.thread.scheduleInstallProvider(cpi);
10967                                 } catch (RemoteException e) {
10968                                 }
10969                             }
10970                         } else {
10971                             checkTime(startTime, "getContentProviderImpl: before start process");
10972                             proc = startProcessLocked(cpi.processName,
10973                                     cpr.appInfo, false, 0, "content provider",
10974                                     new ComponentName(cpi.applicationInfo.packageName,
10975                                             cpi.name), false, false, false);
10976                             checkTime(startTime, "getContentProviderImpl: after start process");
10977                             if (proc == null) {
10978                                 Slog.w(TAG, "Unable to launch app "
10979                                         + cpi.applicationInfo.packageName + "/"
10980                                         + cpi.applicationInfo.uid + " for provider "
10981                                         + name + ": process is bad");
10982                                 return null;
10983                             }
10984                         }
10985                         cpr.launchingApp = proc;
10986                         mLaunchingProviders.add(cpr);
10987                     } finally {
10988                         Binder.restoreCallingIdentity(origId);
10989                     }
10990                 }
10991
10992                 checkTime(startTime, "getContentProviderImpl: updating data structures");
10993
10994                 // Make sure the provider is published (the same provider class
10995                 // may be published under multiple names).
10996                 if (firstClass) {
10997                     mProviderMap.putProviderByClass(comp, cpr);
10998                 }
10999
11000                 mProviderMap.putProviderByName(name, cpr);
11001                 conn = incProviderCountLocked(r, cpr, token, stable);
11002                 if (conn != null) {
11003                     conn.waiting = true;
11004                 }
11005             }
11006             checkTime(startTime, "getContentProviderImpl: done!");
11007         }
11008
11009         // Wait for the provider to be published...
11010         synchronized (cpr) {
11011             while (cpr.provider == null) {
11012                 if (cpr.launchingApp == null) {
11013                     Slog.w(TAG, "Unable to launch app "
11014                             + cpi.applicationInfo.packageName + "/"
11015                             + cpi.applicationInfo.uid + " for provider "
11016                             + name + ": launching app became null");
11017                     EventLog.writeEvent(EventLogTags.AM_PROVIDER_LOST_PROCESS,
11018                             UserHandle.getUserId(cpi.applicationInfo.uid),
11019                             cpi.applicationInfo.packageName,
11020                             cpi.applicationInfo.uid, name);
11021                     return null;
11022                 }
11023                 try {
11024                     if (DEBUG_MU) Slog.v(TAG_MU,
11025                             "Waiting to start provider " + cpr
11026                             + " launchingApp=" + cpr.launchingApp);
11027                     if (conn != null) {
11028                         conn.waiting = true;
11029                     }
11030                     cpr.wait();
11031                 } catch (InterruptedException ex) {
11032                 } finally {
11033                     if (conn != null) {
11034                         conn.waiting = false;
11035                     }
11036                 }
11037             }
11038         }
11039         return cpr != null ? cpr.newHolder(conn) : null;
11040     }
11041
11042     private boolean requestTargetProviderPermissionsReviewIfNeededLocked(ProviderInfo cpi,
11043             ProcessRecord r, final int userId) {
11044         if (getPackageManagerInternalLocked().isPermissionsReviewRequired(
11045                 cpi.packageName, userId)) {
11046
11047             final boolean callerForeground = r == null || r.setSchedGroup
11048                     != ProcessList.SCHED_GROUP_BACKGROUND;
11049
11050             // Show a permission review UI only for starting from a foreground app
11051             if (!callerForeground) {
11052                 Slog.w(TAG, "u" + userId + " Instantiating a provider in package"
11053                         + cpi.packageName + " requires a permissions review");
11054                 return false;
11055             }
11056
11057             final Intent intent = new Intent(Intent.ACTION_REVIEW_PERMISSIONS);
11058             intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK
11059                     | Intent.FLAG_ACTIVITY_EXCLUDE_FROM_RECENTS);
11060             intent.putExtra(Intent.EXTRA_PACKAGE_NAME, cpi.packageName);
11061
11062             if (DEBUG_PERMISSIONS_REVIEW) {
11063                 Slog.i(TAG, "u" + userId + " Launching permission review "
11064                         + "for package " + cpi.packageName);
11065             }
11066
11067             final UserHandle userHandle = new UserHandle(userId);
11068             mHandler.post(new Runnable() {
11069                 @Override
11070                 public void run() {
11071                     mContext.startActivityAsUser(intent, userHandle);
11072                 }
11073             });
11074
11075             return false;
11076         }
11077
11078         return true;
11079     }
11080
11081     PackageManagerInternal getPackageManagerInternalLocked() {
11082         if (mPackageManagerInt == null) {
11083             mPackageManagerInt = LocalServices.getService(PackageManagerInternal.class);
11084         }
11085         return mPackageManagerInt;
11086     }
11087
11088     @Override
11089     public final ContentProviderHolder getContentProvider(
11090             IApplicationThread caller, String name, int userId, boolean stable) {
11091         enforceNotIsolatedCaller("getContentProvider");
11092         if (caller == null) {
11093             String msg = "null IApplicationThread when getting content provider "
11094                     + name;
11095             Slog.w(TAG, msg);
11096             throw new SecurityException(msg);
11097         }
11098         // The incoming user check is now handled in checkContentProviderPermissionLocked() to deal
11099         // with cross-user grant.
11100         return getContentProviderImpl(caller, name, null, stable, userId);
11101     }
11102
11103     public ContentProviderHolder getContentProviderExternal(
11104             String name, int userId, IBinder token) {
11105         enforceCallingPermission(android.Manifest.permission.ACCESS_CONTENT_PROVIDERS_EXTERNALLY,
11106             "Do not have permission in call getContentProviderExternal()");
11107         userId = mUserController.handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(),
11108                 userId, false, ALLOW_FULL_ONLY, "getContentProvider", null);
11109         return getContentProviderExternalUnchecked(name, token, userId);
11110     }
11111
11112     private ContentProviderHolder getContentProviderExternalUnchecked(String name,
11113             IBinder token, int userId) {
11114         return getContentProviderImpl(null, name, token, true, userId);
11115     }
11116
11117     /**
11118      * Drop a content provider from a ProcessRecord's bookkeeping
11119      */
11120     public void removeContentProvider(IBinder connection, boolean stable) {
11121         enforceNotIsolatedCaller("removeContentProvider");
11122         long ident = Binder.clearCallingIdentity();
11123         try {
11124             synchronized (this) {
11125                 ContentProviderConnection conn;
11126                 try {
11127                     conn = (ContentProviderConnection)connection;
11128                 } catch (ClassCastException e) {
11129                     String msg ="removeContentProvider: " + connection
11130                             + " not a ContentProviderConnection";
11131                     Slog.w(TAG, msg);
11132                     throw new IllegalArgumentException(msg);
11133                 }
11134                 if (conn == null) {
11135                     throw new NullPointerException("connection is null");
11136                 }
11137                 if (decProviderCountLocked(conn, null, null, stable)) {
11138                     updateOomAdjLocked();
11139                 }
11140             }
11141         } finally {
11142             Binder.restoreCallingIdentity(ident);
11143         }
11144     }
11145
11146     public void removeContentProviderExternal(String name, IBinder token) {
11147         enforceCallingPermission(android.Manifest.permission.ACCESS_CONTENT_PROVIDERS_EXTERNALLY,
11148             "Do not have permission in call removeContentProviderExternal()");
11149         int userId = UserHandle.getCallingUserId();
11150         long ident = Binder.clearCallingIdentity();
11151         try {
11152             removeContentProviderExternalUnchecked(name, token, userId);
11153         } finally {
11154             Binder.restoreCallingIdentity(ident);
11155         }
11156     }
11157
11158     private void removeContentProviderExternalUnchecked(String name, IBinder token, int userId) {
11159         synchronized (this) {
11160             ContentProviderRecord cpr = mProviderMap.getProviderByName(name, userId);
11161             if(cpr == null) {
11162                 //remove from mProvidersByClass
11163                 if(DEBUG_ALL) Slog.v(TAG, name+" content provider not found in providers list");
11164                 return;
11165             }
11166
11167             //update content provider record entry info
11168             ComponentName comp = new ComponentName(cpr.info.packageName, cpr.info.name);
11169             ContentProviderRecord localCpr = mProviderMap.getProviderByClass(comp, userId);
11170             if (localCpr.hasExternalProcessHandles()) {
11171                 if (localCpr.removeExternalProcessHandleLocked(token)) {
11172                     updateOomAdjLocked();
11173                 } else {
11174                     Slog.e(TAG, "Attmpt to remove content provider " + localCpr
11175                             + " with no external reference for token: "
11176                             + token + ".");
11177                 }
11178             } else {
11179                 Slog.e(TAG, "Attmpt to remove content provider: " + localCpr
11180                         + " with no external references.");
11181             }
11182         }
11183     }
11184
11185     public final void publishContentProviders(IApplicationThread caller,
11186             List<ContentProviderHolder> providers) {
11187         if (providers == null) {
11188             return;
11189         }
11190
11191         enforceNotIsolatedCaller("publishContentProviders");
11192         synchronized (this) {
11193             final ProcessRecord r = getRecordForAppLocked(caller);
11194             if (DEBUG_MU) Slog.v(TAG_MU, "ProcessRecord uid = " + r.uid);
11195             if (r == null) {
11196                 throw new SecurityException(
11197                         "Unable to find app for caller " + caller
11198                       + " (pid=" + Binder.getCallingPid()
11199                       + ") when publishing content providers");
11200             }
11201
11202             final long origId = Binder.clearCallingIdentity();
11203
11204             final int N = providers.size();
11205             for (int i = 0; i < N; i++) {
11206                 ContentProviderHolder src = providers.get(i);
11207                 if (src == null || src.info == null || src.provider == null) {
11208                     continue;
11209                 }
11210                 ContentProviderRecord dst = r.pubProviders.get(src.info.name);
11211                 if (DEBUG_MU) Slog.v(TAG_MU, "ContentProviderRecord uid = " + dst.uid);
11212                 if (dst != null) {
11213                     ComponentName comp = new ComponentName(dst.info.packageName, dst.info.name);
11214                     mProviderMap.putProviderByClass(comp, dst);
11215                     String names[] = dst.info.authority.split(";");
11216                     for (int j = 0; j < names.length; j++) {
11217                         mProviderMap.putProviderByName(names[j], dst);
11218                     }
11219
11220                     int launchingCount = mLaunchingProviders.size();
11221                     int j;
11222                     boolean wasInLaunchingProviders = false;
11223                     for (j = 0; j < launchingCount; j++) {
11224                         if (mLaunchingProviders.get(j) == dst) {
11225                             mLaunchingProviders.remove(j);
11226                             wasInLaunchingProviders = true;
11227                             j--;
11228                             launchingCount--;
11229                         }
11230                     }
11231                     if (wasInLaunchingProviders) {
11232                         mHandler.removeMessages(CONTENT_PROVIDER_PUBLISH_TIMEOUT_MSG, r);
11233                     }
11234                     synchronized (dst) {
11235                         dst.provider = src.provider;
11236                         dst.proc = r;
11237                         dst.notifyAll();
11238                     }
11239                     updateOomAdjLocked(r);
11240                     maybeUpdateProviderUsageStatsLocked(r, src.info.packageName,
11241                             src.info.authority);
11242                 }
11243             }
11244
11245             Binder.restoreCallingIdentity(origId);
11246         }
11247     }
11248
11249     public boolean refContentProvider(IBinder connection, int stable, int unstable) {
11250         ContentProviderConnection conn;
11251         try {
11252             conn = (ContentProviderConnection)connection;
11253         } catch (ClassCastException e) {
11254             String msg ="refContentProvider: " + connection
11255                     + " not a ContentProviderConnection";
11256             Slog.w(TAG, msg);
11257             throw new IllegalArgumentException(msg);
11258         }
11259         if (conn == null) {
11260             throw new NullPointerException("connection is null");
11261         }
11262
11263         synchronized (this) {
11264             if (stable > 0) {
11265                 conn.numStableIncs += stable;
11266             }
11267             stable = conn.stableCount + stable;
11268             if (stable < 0) {
11269                 throw new IllegalStateException("stableCount < 0: " + stable);
11270             }
11271
11272             if (unstable > 0) {
11273                 conn.numUnstableIncs += unstable;
11274             }
11275             unstable = conn.unstableCount + unstable;
11276             if (unstable < 0) {
11277                 throw new IllegalStateException("unstableCount < 0: " + unstable);
11278             }
11279
11280             if ((stable+unstable) <= 0) {
11281                 throw new IllegalStateException("ref counts can't go to zero here: stable="
11282                         + stable + " unstable=" + unstable);
11283             }
11284             conn.stableCount = stable;
11285             conn.unstableCount = unstable;
11286             return !conn.dead;
11287         }
11288     }
11289
11290     public void unstableProviderDied(IBinder connection) {
11291         ContentProviderConnection conn;
11292         try {
11293             conn = (ContentProviderConnection)connection;
11294         } catch (ClassCastException e) {
11295             String msg ="refContentProvider: " + connection
11296                     + " not a ContentProviderConnection";
11297             Slog.w(TAG, msg);
11298             throw new IllegalArgumentException(msg);
11299         }
11300         if (conn == null) {
11301             throw new NullPointerException("connection is null");
11302         }
11303
11304         // Safely retrieve the content provider associated with the connection.
11305         IContentProvider provider;
11306         synchronized (this) {
11307             provider = conn.provider.provider;
11308         }
11309
11310         if (provider == null) {
11311             // Um, yeah, we're way ahead of you.
11312             return;
11313         }
11314
11315         // Make sure the caller is being honest with us.
11316         if (provider.asBinder().pingBinder()) {
11317             // Er, no, still looks good to us.
11318             synchronized (this) {
11319                 Slog.w(TAG, "unstableProviderDied: caller " + Binder.getCallingUid()
11320                         + " says " + conn + " died, but we don't agree");
11321                 return;
11322             }
11323         }
11324
11325         // Well look at that!  It's dead!
11326         synchronized (this) {
11327             if (conn.provider.provider != provider) {
11328                 // But something changed...  good enough.
11329                 return;
11330             }
11331
11332             ProcessRecord proc = conn.provider.proc;
11333             if (proc == null || proc.thread == null) {
11334                 // Seems like the process is already cleaned up.
11335                 return;
11336             }
11337
11338             // As far as we're concerned, this is just like receiving a
11339             // death notification...  just a bit prematurely.
11340             Slog.i(TAG, "Process " + proc.processName + " (pid " + proc.pid
11341                     + ") early provider death");
11342             final long ident = Binder.clearCallingIdentity();
11343             try {
11344                 appDiedLocked(proc);
11345             } finally {
11346                 Binder.restoreCallingIdentity(ident);
11347             }
11348         }
11349     }
11350
11351     @Override
11352     public void appNotRespondingViaProvider(IBinder connection) {
11353         enforceCallingPermission(
11354                 android.Manifest.permission.REMOVE_TASKS, "appNotRespondingViaProvider()");
11355
11356         final ContentProviderConnection conn = (ContentProviderConnection) connection;
11357         if (conn == null) {
11358             Slog.w(TAG, "ContentProviderConnection is null");
11359             return;
11360         }
11361
11362         final ProcessRecord host = conn.provider.proc;
11363         if (host == null) {
11364             Slog.w(TAG, "Failed to find hosting ProcessRecord");
11365             return;
11366         }
11367
11368         mHandler.post(new Runnable() {
11369             @Override
11370             public void run() {
11371                 mAppErrors.appNotResponding(host, null, null, false,
11372                         "ContentProvider not responding");
11373             }
11374         });
11375     }
11376
11377     public final void installSystemProviders() {
11378         List<ProviderInfo> providers;
11379         synchronized (this) {
11380             ProcessRecord app = mProcessNames.get("system", Process.SYSTEM_UID);
11381             providers = generateApplicationProvidersLocked(app);
11382             if (providers != null) {
11383                 for (int i=providers.size()-1; i>=0; i--) {
11384                     ProviderInfo pi = (ProviderInfo)providers.get(i);
11385                     if ((pi.applicationInfo.flags&ApplicationInfo.FLAG_SYSTEM) == 0) {
11386                         Slog.w(TAG, "Not installing system proc provider " + pi.name
11387                                 + ": not system .apk");
11388                         providers.remove(i);
11389                     }
11390                 }
11391             }
11392         }
11393         if (providers != null) {
11394             mSystemThread.installSystemProviders(providers);
11395         }
11396
11397         mCoreSettingsObserver = new CoreSettingsObserver(this);
11398         mFontScaleSettingObserver = new FontScaleSettingObserver();
11399
11400         //mUsageStatsService.monitorPackages();
11401     }
11402
11403     private void startPersistentApps(int matchFlags) {
11404         if (mFactoryTest == FactoryTest.FACTORY_TEST_LOW_LEVEL) return;
11405
11406         synchronized (this) {
11407             try {
11408                 final List<ApplicationInfo> apps = AppGlobals.getPackageManager()
11409                         .getPersistentApplications(STOCK_PM_FLAGS | matchFlags).getList();
11410                 for (ApplicationInfo app : apps) {
11411                     if (!"android".equals(app.packageName)) {
11412                         addAppLocked(app, false, null /* ABI override */);
11413                     }
11414                 }
11415             } catch (RemoteException ex) {
11416             }
11417         }
11418     }
11419
11420     /**
11421      * When a user is unlocked, we need to install encryption-unaware providers
11422      * belonging to any running apps.
11423      */
11424     private void installEncryptionUnawareProviders(int userId) {
11425         // We're only interested in providers that are encryption unaware, and
11426         // we don't care about uninstalled apps, since there's no way they're
11427         // running at this point.
11428         final int matchFlags = GET_PROVIDERS | MATCH_DIRECT_BOOT_UNAWARE;
11429
11430         synchronized (this) {
11431             final int NP = mProcessNames.getMap().size();
11432             for (int ip = 0; ip < NP; ip++) {
11433                 final SparseArray<ProcessRecord> apps = mProcessNames.getMap().valueAt(ip);
11434                 final int NA = apps.size();
11435                 for (int ia = 0; ia < NA; ia++) {
11436                     final ProcessRecord app = apps.valueAt(ia);
11437                     if (app.userId != userId || app.thread == null || app.unlocked) continue;
11438
11439                     final int NG = app.pkgList.size();
11440                     for (int ig = 0; ig < NG; ig++) {
11441                         try {
11442                             final String pkgName = app.pkgList.keyAt(ig);
11443                             final PackageInfo pkgInfo = AppGlobals.getPackageManager()
11444                                     .getPackageInfo(pkgName, matchFlags, userId);
11445                             if (pkgInfo != null && !ArrayUtils.isEmpty(pkgInfo.providers)) {
11446                                 for (ProviderInfo pi : pkgInfo.providers) {
11447                                     // TODO: keep in sync with generateApplicationProvidersLocked
11448                                     final boolean processMatch = Objects.equals(pi.processName,
11449                                             app.processName) || pi.multiprocess;
11450                                     final boolean userMatch = isSingleton(pi.processName,
11451                                             pi.applicationInfo, pi.name, pi.flags)
11452                                                     ? (app.userId == UserHandle.USER_SYSTEM) : true;
11453                                     if (processMatch && userMatch) {
11454                                         Log.v(TAG, "Installing " + pi);
11455                                         app.thread.scheduleInstallProvider(pi);
11456                                     } else {
11457                                         Log.v(TAG, "Skipping " + pi);
11458                                     }
11459                                 }
11460                             }
11461                         } catch (RemoteException ignored) {
11462                         }
11463                     }
11464                 }
11465             }
11466         }
11467     }
11468
11469     /**
11470      * Allows apps to retrieve the MIME type of a URI.
11471      * If an app is in the same user as the ContentProvider, or if it is allowed to interact across
11472      * users, then it does not need permission to access the ContentProvider.
11473      * Either, it needs cross-user uri grants.
11474      *
11475      * CTS tests for this functionality can be run with "runtest cts-appsecurity".
11476      *
11477      * Test cases are at cts/tests/appsecurity-tests/test-apps/UsePermissionDiffCert/
11478      *     src/com/android/cts/usespermissiondiffcertapp/AccessPermissionWithDiffSigTest.java
11479      */
11480     public String getProviderMimeType(Uri uri, int userId) {
11481         enforceNotIsolatedCaller("getProviderMimeType");
11482         final String name = uri.getAuthority();
11483         int callingUid = Binder.getCallingUid();
11484         int callingPid = Binder.getCallingPid();
11485         long ident = 0;
11486         boolean clearedIdentity = false;
11487         synchronized (this) {
11488             userId = mUserController.unsafeConvertIncomingUserLocked(userId);
11489         }
11490         if (canClearIdentity(callingPid, callingUid, userId)) {
11491             clearedIdentity = true;
11492             ident = Binder.clearCallingIdentity();
11493         }
11494         ContentProviderHolder holder = null;
11495         try {
11496             holder = getContentProviderExternalUnchecked(name, null, userId);
11497             if (holder != null) {
11498                 return holder.provider.getType(uri);
11499             }
11500         } catch (RemoteException e) {
11501             Log.w(TAG, "Content provider dead retrieving " + uri, e);
11502             return null;
11503         } catch (Exception e) {
11504             Log.w(TAG, "Exception while determining type of " + uri, e);
11505             return null;
11506         } finally {
11507             // We need to clear the identity to call removeContentProviderExternalUnchecked
11508             if (!clearedIdentity) {
11509                 ident = Binder.clearCallingIdentity();
11510             }
11511             try {
11512                 if (holder != null) {
11513                     removeContentProviderExternalUnchecked(name, null, userId);
11514                 }
11515             } finally {
11516                 Binder.restoreCallingIdentity(ident);
11517             }
11518         }
11519
11520         return null;
11521     }
11522
11523     private boolean canClearIdentity(int callingPid, int callingUid, int userId) {
11524         if (UserHandle.getUserId(callingUid) == userId) {
11525             return true;
11526         }
11527         if (checkComponentPermission(INTERACT_ACROSS_USERS, callingPid,
11528                 callingUid, -1, true) == PackageManager.PERMISSION_GRANTED
11529                 || checkComponentPermission(INTERACT_ACROSS_USERS_FULL, callingPid,
11530                 callingUid, -1, true) == PackageManager.PERMISSION_GRANTED) {
11531                 return true;
11532         }
11533         return false;
11534     }
11535
11536     // =========================================================
11537     // GLOBAL MANAGEMENT
11538     // =========================================================
11539
11540     final ProcessRecord newProcessRecordLocked(ApplicationInfo info, String customProcess,
11541             boolean isolated, int isolatedUid) {
11542         String proc = customProcess != null ? customProcess : info.processName;
11543         BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
11544         final int userId = UserHandle.getUserId(info.uid);
11545         int uid = info.uid;
11546         if (isolated) {
11547             if (isolatedUid == 0) {
11548                 int stepsLeft = Process.LAST_ISOLATED_UID - Process.FIRST_ISOLATED_UID + 1;
11549                 while (true) {
11550                     if (mNextIsolatedProcessUid < Process.FIRST_ISOLATED_UID
11551                             || mNextIsolatedProcessUid > Process.LAST_ISOLATED_UID) {
11552                         mNextIsolatedProcessUid = Process.FIRST_ISOLATED_UID;
11553                     }
11554                     uid = UserHandle.getUid(userId, mNextIsolatedProcessUid);
11555                     mNextIsolatedProcessUid++;
11556                     if (mIsolatedProcesses.indexOfKey(uid) < 0) {
11557                         // No process for this uid, use it.
11558                         break;
11559                     }
11560                     stepsLeft--;
11561                     if (stepsLeft <= 0) {
11562                         return null;
11563                     }
11564                 }
11565             } else {
11566                 // Special case for startIsolatedProcess (internal only), where
11567                 // the uid of the isolated process is specified by the caller.
11568                 uid = isolatedUid;
11569             }
11570
11571             // Register the isolated UID with this application so BatteryStats knows to
11572             // attribute resource usage to the application.
11573             //
11574             // NOTE: This is done here before addProcessNameLocked, which will tell BatteryStats
11575             // about the process state of the isolated UID *before* it is registered with the
11576             // owning application.
11577             mBatteryStatsService.addIsolatedUid(uid, info.uid);
11578         }
11579         final ProcessRecord r = new ProcessRecord(stats, info, proc, uid);
11580         if (!mBooted && !mBooting
11581                 && userId == UserHandle.USER_SYSTEM
11582                 && (info.flags & PERSISTENT_MASK) == PERSISTENT_MASK) {
11583             r.persistent = true;
11584         }
11585         addProcessNameLocked(r);
11586         return r;
11587     }
11588
11589     final ProcessRecord addAppLocked(ApplicationInfo info, boolean isolated,
11590             String abiOverride) {
11591         ProcessRecord app;
11592         if (!isolated) {
11593             app = getProcessRecordLocked(info.processName, info.uid, true);
11594         } else {
11595             app = null;
11596         }
11597
11598         if (app == null) {
11599             app = newProcessRecordLocked(info, null, isolated, 0);
11600             updateLruProcessLocked(app, false, null);
11601             updateOomAdjLocked();
11602         }
11603
11604         // This package really, really can not be stopped.
11605         try {
11606             AppGlobals.getPackageManager().setPackageStoppedState(
11607                     info.packageName, false, UserHandle.getUserId(app.uid));
11608         } catch (RemoteException e) {
11609         } catch (IllegalArgumentException e) {
11610             Slog.w(TAG, "Failed trying to unstop package "
11611                     + info.packageName + ": " + e);
11612         }
11613
11614         if ((info.flags & PERSISTENT_MASK) == PERSISTENT_MASK) {
11615             app.persistent = true;
11616             app.maxAdj = ProcessList.PERSISTENT_PROC_ADJ;
11617         }
11618         if (app.thread == null && mPersistentStartingProcesses.indexOf(app) < 0) {
11619             mPersistentStartingProcesses.add(app);
11620             startProcessLocked(app, "added application", app.processName, abiOverride,
11621                     null /* entryPoint */, null /* entryPointArgs */);
11622         }
11623
11624         return app;
11625     }
11626
11627     public void unhandledBack() {
11628         enforceCallingPermission(android.Manifest.permission.FORCE_BACK,
11629                 "unhandledBack()");
11630
11631         synchronized(this) {
11632             final long origId = Binder.clearCallingIdentity();
11633             try {
11634                 getFocusedStack().unhandledBackLocked();
11635             } finally {
11636                 Binder.restoreCallingIdentity(origId);
11637             }
11638         }
11639     }
11640
11641     public ParcelFileDescriptor openContentUri(Uri uri) throws RemoteException {
11642         enforceNotIsolatedCaller("openContentUri");
11643         final int userId = UserHandle.getCallingUserId();
11644         String name = uri.getAuthority();
11645         ContentProviderHolder cph = getContentProviderExternalUnchecked(name, null, userId);
11646         ParcelFileDescriptor pfd = null;
11647         if (cph != null) {
11648             // We record the binder invoker's uid in thread-local storage before
11649             // going to the content provider to open the file.  Later, in the code
11650             // that handles all permissions checks, we look for this uid and use
11651             // that rather than the Activity Manager's own uid.  The effect is that
11652             // we do the check against the caller's permissions even though it looks
11653             // to the content provider like the Activity Manager itself is making
11654             // the request.
11655             Binder token = new Binder();
11656             sCallerIdentity.set(new Identity(
11657                     token, Binder.getCallingPid(), Binder.getCallingUid()));
11658             try {
11659                 pfd = cph.provider.openFile(null, uri, "r", null, token);
11660             } catch (FileNotFoundException e) {
11661                 // do nothing; pfd will be returned null
11662             } finally {
11663                 // Ensure that whatever happens, we clean up the identity state
11664                 sCallerIdentity.remove();
11665                 // Ensure we're done with the provider.
11666                 removeContentProviderExternalUnchecked(name, null, userId);
11667             }
11668         } else {
11669             Slog.d(TAG, "Failed to get provider for authority '" + name + "'");
11670         }
11671         return pfd;
11672     }
11673
11674     // Actually is sleeping or shutting down or whatever else in the future
11675     // is an inactive state.
11676     boolean isSleepingOrShuttingDownLocked() {
11677         return isSleepingLocked() || mShuttingDown;
11678     }
11679
11680     boolean isShuttingDownLocked() {
11681         return mShuttingDown;
11682     }
11683
11684     boolean isSleepingLocked() {
11685         return mSleeping;
11686     }
11687
11688     void onWakefulnessChanged(int wakefulness) {
11689         synchronized(this) {
11690             mWakefulness = wakefulness;
11691             updateSleepIfNeededLocked();
11692         }
11693     }
11694
11695     void finishRunningVoiceLocked() {
11696         if (mRunningVoice != null) {
11697             mRunningVoice = null;
11698             mVoiceWakeLock.release();
11699             updateSleepIfNeededLocked();
11700         }
11701     }
11702
11703     void startTimeTrackingFocusedActivityLocked() {
11704         if (!mSleeping && mCurAppTimeTracker != null && mFocusedActivity != null) {
11705             mCurAppTimeTracker.start(mFocusedActivity.packageName);
11706         }
11707     }
11708
11709     void updateSleepIfNeededLocked() {
11710         if (mSleeping && !shouldSleepLocked()) {
11711             mSleeping = false;
11712             startTimeTrackingFocusedActivityLocked();
11713             mTopProcessState = ActivityManager.PROCESS_STATE_TOP;
11714             mStackSupervisor.comeOutOfSleepIfNeededLocked();
11715             sendNotifyVrManagerOfSleepState(false);
11716             updateOomAdjLocked();
11717         } else if (!mSleeping && shouldSleepLocked()) {
11718             mSleeping = true;
11719             if (mCurAppTimeTracker != null) {
11720                 mCurAppTimeTracker.stop();
11721             }
11722             mTopProcessState = ActivityManager.PROCESS_STATE_TOP_SLEEPING;
11723             mStackSupervisor.goingToSleepLocked();
11724             sendNotifyVrManagerOfSleepState(true);
11725             updateOomAdjLocked();
11726
11727             // Initialize the wake times of all processes.
11728             checkExcessivePowerUsageLocked(false);
11729             mHandler.removeMessages(CHECK_EXCESSIVE_WAKE_LOCKS_MSG);
11730             Message nmsg = mHandler.obtainMessage(CHECK_EXCESSIVE_WAKE_LOCKS_MSG);
11731             mHandler.sendMessageDelayed(nmsg, POWER_CHECK_DELAY);
11732         }
11733     }
11734
11735     private boolean shouldSleepLocked() {
11736         // Resume applications while running a voice interactor.
11737         if (mRunningVoice != null) {
11738             return false;
11739         }
11740
11741         // TODO: Transform the lock screen state into a sleep token instead.
11742         switch (mWakefulness) {
11743             case PowerManagerInternal.WAKEFULNESS_AWAKE:
11744             case PowerManagerInternal.WAKEFULNESS_DREAMING:
11745             case PowerManagerInternal.WAKEFULNESS_DOZING:
11746                 // Pause applications whenever the lock screen is shown or any sleep
11747                 // tokens have been acquired.
11748                 return (mLockScreenShown != LOCK_SCREEN_HIDDEN || !mSleepTokens.isEmpty());
11749             case PowerManagerInternal.WAKEFULNESS_ASLEEP:
11750             default:
11751                 // If we're asleep then pause applications unconditionally.
11752                 return true;
11753         }
11754     }
11755
11756     /** Pokes the task persister. */
11757     void notifyTaskPersisterLocked(TaskRecord task, boolean flush) {
11758         mRecentTasks.notifyTaskPersisterLocked(task, flush);
11759     }
11760
11761     /** Notifies all listeners when the task stack has changed. */
11762     void notifyTaskStackChangedLocked() {
11763         mHandler.sendEmptyMessage(LOG_STACK_STATE);
11764         mHandler.removeMessages(NOTIFY_TASK_STACK_CHANGE_LISTENERS_MSG);
11765         Message nmsg = mHandler.obtainMessage(NOTIFY_TASK_STACK_CHANGE_LISTENERS_MSG);
11766         mHandler.sendMessageDelayed(nmsg, NOTIFY_TASK_STACK_CHANGE_LISTENERS_DELAY);
11767     }
11768
11769     /** Notifies all listeners when an Activity is pinned. */
11770     void notifyActivityPinnedLocked() {
11771         mHandler.removeMessages(NOTIFY_ACTIVITY_PINNED_LISTENERS_MSG);
11772         mHandler.obtainMessage(NOTIFY_ACTIVITY_PINNED_LISTENERS_MSG).sendToTarget();
11773     }
11774
11775     /**
11776      * Notifies all listeners when an attempt was made to start an an activity that is already
11777      * running in the pinned stack and the activity was not actually started, but the task is
11778      * either brought to the front or a new Intent is delivered to it.
11779      */
11780     void notifyPinnedActivityRestartAttemptLocked() {
11781         mHandler.removeMessages(NOTIFY_PINNED_ACTIVITY_RESTART_ATTEMPT_LISTENERS_MSG);
11782         mHandler.obtainMessage(NOTIFY_PINNED_ACTIVITY_RESTART_ATTEMPT_LISTENERS_MSG).sendToTarget();
11783     }
11784
11785     /** Notifies all listeners when the pinned stack animation ends. */
11786     @Override
11787     public void notifyPinnedStackAnimationEnded() {
11788         synchronized (this) {
11789             mHandler.removeMessages(NOTIFY_PINNED_STACK_ANIMATION_ENDED_LISTENERS_MSG);
11790             mHandler.obtainMessage(
11791                     NOTIFY_PINNED_STACK_ANIMATION_ENDED_LISTENERS_MSG).sendToTarget();
11792         }
11793     }
11794
11795     @Override
11796     public void notifyCleartextNetwork(int uid, byte[] firstPacket) {
11797         mHandler.obtainMessage(NOTIFY_CLEARTEXT_NETWORK_MSG, uid, 0, firstPacket).sendToTarget();
11798     }
11799
11800     @Override
11801     public boolean shutdown(int timeout) {
11802         if (checkCallingPermission(android.Manifest.permission.SHUTDOWN)
11803                 != PackageManager.PERMISSION_GRANTED) {
11804             throw new SecurityException("Requires permission "
11805                     + android.Manifest.permission.SHUTDOWN);
11806         }
11807
11808         boolean timedout = false;
11809
11810         synchronized(this) {
11811             mShuttingDown = true;
11812             updateEventDispatchingLocked();
11813             timedout = mStackSupervisor.shutdownLocked(timeout);
11814         }
11815
11816         mAppOpsService.shutdown();
11817         if (mUsageStatsService != null) {
11818             mUsageStatsService.prepareShutdown();
11819         }
11820         mBatteryStatsService.shutdown();
11821         synchronized (this) {
11822             mProcessStats.shutdownLocked();
11823             notifyTaskPersisterLocked(null, true);
11824         }
11825
11826         return timedout;
11827     }
11828
11829     public final void activitySlept(IBinder token) {
11830         if (DEBUG_ALL) Slog.v(TAG, "Activity slept: token=" + token);
11831
11832         final long origId = Binder.clearCallingIdentity();
11833
11834         synchronized (this) {
11835             final ActivityRecord r = ActivityRecord.isInStackLocked(token);
11836             if (r != null) {
11837                 mStackSupervisor.activitySleptLocked(r);
11838             }
11839         }
11840
11841         Binder.restoreCallingIdentity(origId);
11842     }
11843
11844     private String lockScreenShownToString() {
11845         switch (mLockScreenShown) {
11846             case LOCK_SCREEN_HIDDEN: return "LOCK_SCREEN_HIDDEN";
11847             case LOCK_SCREEN_LEAVING: return "LOCK_SCREEN_LEAVING";
11848             case LOCK_SCREEN_SHOWN: return "LOCK_SCREEN_SHOWN";
11849             default: return "Unknown=" + mLockScreenShown;
11850         }
11851     }
11852
11853     void logLockScreen(String msg) {
11854         if (DEBUG_LOCKSCREEN) Slog.d(TAG_LOCKSCREEN, Debug.getCallers(2) + ":" + msg
11855                 + " mLockScreenShown=" + lockScreenShownToString() + " mWakefulness="
11856                 + PowerManagerInternal.wakefulnessToString(mWakefulness)
11857                 + " mSleeping=" + mSleeping);
11858     }
11859
11860     void startRunningVoiceLocked(IVoiceInteractionSession session, int targetUid) {
11861         Slog.d(TAG, "<<<  startRunningVoiceLocked()");
11862         mVoiceWakeLock.setWorkSource(new WorkSource(targetUid));
11863         if (mRunningVoice == null || mRunningVoice.asBinder() != session.asBinder()) {
11864             boolean wasRunningVoice = mRunningVoice != null;
11865             mRunningVoice = session;
11866             if (!wasRunningVoice) {
11867                 mVoiceWakeLock.acquire();
11868                 updateSleepIfNeededLocked();
11869             }
11870         }
11871     }
11872
11873     private void updateEventDispatchingLocked() {
11874         mWindowManager.setEventDispatching(mBooted && !mShuttingDown);
11875     }
11876
11877     public void setLockScreenShown(boolean showing, boolean occluded) {
11878         if (checkCallingPermission(android.Manifest.permission.DEVICE_POWER)
11879                 != PackageManager.PERMISSION_GRANTED) {
11880             throw new SecurityException("Requires permission "
11881                     + android.Manifest.permission.DEVICE_POWER);
11882         }
11883
11884         synchronized(this) {
11885             long ident = Binder.clearCallingIdentity();
11886             try {
11887                 if (DEBUG_LOCKSCREEN) logLockScreen(" showing=" + showing + " occluded=" + occluded);
11888                 mLockScreenShown = (showing && !occluded) ? LOCK_SCREEN_SHOWN : LOCK_SCREEN_HIDDEN;
11889                 if (showing && occluded) {
11890                     // The lock screen is currently showing, but is occluded by a window that can
11891                     // show on top of the lock screen. In this can we want to dismiss the docked
11892                     // stack since it will be complicated/risky to try to put the activity on top
11893                     // of the lock screen in the right fullscreen configuration.
11894                     mStackSupervisor.moveTasksToFullscreenStackLocked(DOCKED_STACK_ID,
11895                             mStackSupervisor.mFocusedStack.getStackId() == DOCKED_STACK_ID);
11896                 }
11897
11898                 updateSleepIfNeededLocked();
11899             } finally {
11900                 Binder.restoreCallingIdentity(ident);
11901             }
11902         }
11903     }
11904
11905     @Override
11906     public void notifyLockedProfile(@UserIdInt int userId) {
11907         try {
11908             if (!AppGlobals.getPackageManager().isUidPrivileged(Binder.getCallingUid())) {
11909                 throw new SecurityException("Only privileged app can call notifyLockedProfile");
11910             }
11911         } catch (RemoteException ex) {
11912             throw new SecurityException("Fail to check is caller a privileged app", ex);
11913         }
11914
11915         synchronized (this) {
11916             if (mStackSupervisor.isUserLockedProfile(userId)) {
11917                 final long ident = Binder.clearCallingIdentity();
11918                 try {
11919                     final int currentUserId = mUserController.getCurrentUserIdLocked();
11920
11921                     // Drop locked freeform tasks out into the fullscreen stack.
11922                     // TODO: Redact the tasks in place. It's much better to keep them on the screen
11923                     //       where they were before, but in an obscured state.
11924                     mStackSupervisor.moveProfileTasksFromFreeformToFullscreenStackLocked(userId);
11925
11926                     if (mUserController.isLockScreenDisabled(currentUserId)) {
11927                         // If there is no device lock, we will show the profile's credential page.
11928                         mActivityStarter.showConfirmDeviceCredential(userId);
11929                     } else {
11930                         // Showing launcher to avoid user entering credential twice.
11931                         startHomeActivityLocked(currentUserId, "notifyLockedProfile");
11932                     }
11933                 } finally {
11934                     Binder.restoreCallingIdentity(ident);
11935                 }
11936             }
11937         }
11938     }
11939
11940     @Override
11941     public void startConfirmDeviceCredentialIntent(Intent intent) {
11942         enforceCallingPermission(MANAGE_ACTIVITY_STACKS, "startConfirmDeviceCredentialIntent");
11943         synchronized (this) {
11944             final long ident = Binder.clearCallingIdentity();
11945             try {
11946                 mActivityStarter.startConfirmCredentialIntent(intent);
11947             } finally {
11948                 Binder.restoreCallingIdentity(ident);
11949             }
11950         }
11951     }
11952
11953     @Override
11954     public void stopAppSwitches() {
11955         if (checkCallingPermission(android.Manifest.permission.STOP_APP_SWITCHES)
11956                 != PackageManager.PERMISSION_GRANTED) {
11957             throw new SecurityException("viewquires permission "
11958                     + android.Manifest.permission.STOP_APP_SWITCHES);
11959         }
11960
11961         synchronized(this) {
11962             mAppSwitchesAllowedTime = SystemClock.uptimeMillis()
11963                     + APP_SWITCH_DELAY_TIME;
11964             mDidAppSwitch = false;
11965             mHandler.removeMessages(DO_PENDING_ACTIVITY_LAUNCHES_MSG);
11966             Message msg = mHandler.obtainMessage(DO_PENDING_ACTIVITY_LAUNCHES_MSG);
11967             mHandler.sendMessageDelayed(msg, APP_SWITCH_DELAY_TIME);
11968         }
11969     }
11970
11971     public void resumeAppSwitches() {
11972         if (checkCallingPermission(android.Manifest.permission.STOP_APP_SWITCHES)
11973                 != PackageManager.PERMISSION_GRANTED) {
11974             throw new SecurityException("Requires permission "
11975                     + android.Manifest.permission.STOP_APP_SWITCHES);
11976         }
11977
11978         synchronized(this) {
11979             // Note that we don't execute any pending app switches... we will
11980             // let those wait until either the timeout, or the next start
11981             // activity request.
11982             mAppSwitchesAllowedTime = 0;
11983         }
11984     }
11985
11986     boolean checkAppSwitchAllowedLocked(int sourcePid, int sourceUid,
11987             int callingPid, int callingUid, String name) {
11988         if (mAppSwitchesAllowedTime < SystemClock.uptimeMillis()) {
11989             return true;
11990         }
11991
11992         int perm = checkComponentPermission(
11993                 android.Manifest.permission.STOP_APP_SWITCHES, sourcePid,
11994                 sourceUid, -1, true);
11995         if (perm == PackageManager.PERMISSION_GRANTED) {
11996             return true;
11997         }
11998
11999         // If the actual IPC caller is different from the logical source, then
12000         // also see if they are allowed to control app switches.
12001         if (callingUid != -1 && callingUid != sourceUid) {
12002             perm = checkComponentPermission(
12003                     android.Manifest.permission.STOP_APP_SWITCHES, callingPid,
12004                     callingUid, -1, true);
12005             if (perm == PackageManager.PERMISSION_GRANTED) {
12006                 return true;
12007             }
12008         }
12009
12010         Slog.w(TAG, name + " request from " + sourceUid + " stopped");
12011         return false;
12012     }
12013
12014     public void setDebugApp(String packageName, boolean waitForDebugger,
12015             boolean persistent) {
12016         enforceCallingPermission(android.Manifest.permission.SET_DEBUG_APP,
12017                 "setDebugApp()");
12018
12019         long ident = Binder.clearCallingIdentity();
12020         try {
12021             // Note that this is not really thread safe if there are multiple
12022             // callers into it at the same time, but that's not a situation we
12023             // care about.
12024             if (persistent) {
12025                 final ContentResolver resolver = mContext.getContentResolver();
12026                 Settings.Global.putString(
12027                     resolver, Settings.Global.DEBUG_APP,
12028                     packageName);
12029                 Settings.Global.putInt(
12030                     resolver, Settings.Global.WAIT_FOR_DEBUGGER,
12031                     waitForDebugger ? 1 : 0);
12032             }
12033
12034             synchronized (this) {
12035                 if (!persistent) {
12036                     mOrigDebugApp = mDebugApp;
12037                     mOrigWaitForDebugger = mWaitForDebugger;
12038                 }
12039                 mDebugApp = packageName;
12040                 mWaitForDebugger = waitForDebugger;
12041                 mDebugTransient = !persistent;
12042                 if (packageName != null) {
12043                     forceStopPackageLocked(packageName, -1, false, false, true, true,
12044                             false, UserHandle.USER_ALL, "set debug app");
12045                 }
12046             }
12047         } finally {
12048             Binder.restoreCallingIdentity(ident);
12049         }
12050     }
12051
12052     void setTrackAllocationApp(ApplicationInfo app, String processName) {
12053         synchronized (this) {
12054             boolean isDebuggable = "1".equals(SystemProperties.get(SYSTEM_DEBUGGABLE, "0"));
12055             if (!isDebuggable) {
12056                 if ((app.flags & ApplicationInfo.FLAG_DEBUGGABLE) == 0) {
12057                     throw new SecurityException("Process not debuggable: " + app.packageName);
12058                 }
12059             }
12060
12061             mTrackAllocationApp = processName;
12062         }
12063     }
12064
12065     void setProfileApp(ApplicationInfo app, String processName, ProfilerInfo profilerInfo) {
12066         synchronized (this) {
12067             boolean isDebuggable = "1".equals(SystemProperties.get(SYSTEM_DEBUGGABLE, "0"));
12068             if (!isDebuggable) {
12069                 if ((app.flags & ApplicationInfo.FLAG_DEBUGGABLE) == 0) {
12070                     throw new SecurityException("Process not debuggable: " + app.packageName);
12071                 }
12072             }
12073             mProfileApp = processName;
12074             mProfileFile = profilerInfo.profileFile;
12075             if (mProfileFd != null) {
12076                 try {
12077                     mProfileFd.close();
12078                 } catch (IOException e) {
12079                 }
12080                 mProfileFd = null;
12081             }
12082             mProfileFd = profilerInfo.profileFd;
12083             mSamplingInterval = profilerInfo.samplingInterval;
12084             mAutoStopProfiler = profilerInfo.autoStopProfiler;
12085             mProfileType = 0;
12086         }
12087     }
12088
12089     void setNativeDebuggingAppLocked(ApplicationInfo app, String processName) {
12090         boolean isDebuggable = "1".equals(SystemProperties.get(SYSTEM_DEBUGGABLE, "0"));
12091         if (!isDebuggable) {
12092             if ((app.flags & ApplicationInfo.FLAG_DEBUGGABLE) == 0) {
12093                 throw new SecurityException("Process not debuggable: " + app.packageName);
12094             }
12095         }
12096         mNativeDebuggingApp = processName;
12097     }
12098
12099     @Override
12100     public void setAlwaysFinish(boolean enabled) {
12101         enforceCallingPermission(android.Manifest.permission.SET_ALWAYS_FINISH,
12102                 "setAlwaysFinish()");
12103
12104         long ident = Binder.clearCallingIdentity();
12105         try {
12106             Settings.Global.putInt(
12107                     mContext.getContentResolver(),
12108                     Settings.Global.ALWAYS_FINISH_ACTIVITIES, enabled ? 1 : 0);
12109
12110             synchronized (this) {
12111                 mAlwaysFinishActivities = enabled;
12112             }
12113         } finally {
12114             Binder.restoreCallingIdentity(ident);
12115         }
12116     }
12117
12118     @Override
12119     public void setLenientBackgroundCheck(boolean enabled) {
12120         enforceCallingPermission(android.Manifest.permission.SET_PROCESS_LIMIT,
12121                 "setLenientBackgroundCheck()");
12122
12123         long ident = Binder.clearCallingIdentity();
12124         try {
12125             Settings.Global.putInt(
12126                     mContext.getContentResolver(),
12127                     Settings.Global.LENIENT_BACKGROUND_CHECK, enabled ? 1 : 0);
12128
12129             synchronized (this) {
12130                 mLenientBackgroundCheck = enabled;
12131             }
12132         } finally {
12133             Binder.restoreCallingIdentity(ident);
12134         }
12135     }
12136
12137     @Override
12138     public void setActivityController(IActivityController controller, boolean imAMonkey) {
12139         enforceCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER,
12140                 "setActivityController()");
12141         synchronized (this) {
12142             mController = controller;
12143             mControllerIsAMonkey = imAMonkey;
12144             Watchdog.getInstance().setActivityController(controller);
12145         }
12146     }
12147
12148     @Override
12149     public void setUserIsMonkey(boolean userIsMonkey) {
12150         synchronized (this) {
12151             synchronized (mPidsSelfLocked) {
12152                 final int callingPid = Binder.getCallingPid();
12153                 ProcessRecord precessRecord = mPidsSelfLocked.get(callingPid);
12154                 if (precessRecord == null) {
12155                     throw new SecurityException("Unknown process: " + callingPid);
12156                 }
12157                 if (precessRecord.instrumentationUiAutomationConnection  == null) {
12158                     throw new SecurityException("Only an instrumentation process "
12159                             + "with a UiAutomation can call setUserIsMonkey");
12160                 }
12161             }
12162             mUserIsMonkey = userIsMonkey;
12163         }
12164     }
12165
12166     @Override
12167     public boolean isUserAMonkey() {
12168         synchronized (this) {
12169             // If there is a controller also implies the user is a monkey.
12170             return (mUserIsMonkey || (mController != null && mControllerIsAMonkey));
12171         }
12172     }
12173
12174     public void requestBugReport(int bugreportType) {
12175         String service = null;
12176         switch (bugreportType) {
12177             case ActivityManager.BUGREPORT_OPTION_FULL:
12178                 service = "bugreport";
12179                 break;
12180             case ActivityManager.BUGREPORT_OPTION_INTERACTIVE:
12181                 service = "bugreportplus";
12182                 break;
12183             case ActivityManager.BUGREPORT_OPTION_REMOTE:
12184                 service = "bugreportremote";
12185                 break;
12186             case ActivityManager.BUGREPORT_OPTION_WEAR:
12187                 service = "bugreportwear";
12188                 break;
12189             case ActivityManager.BUGREPORT_OPTION_TELEPHONY:
12190                 service = "bugreportelefony";
12191                 break;
12192         }
12193         if (service == null) {
12194             throw new IllegalArgumentException("Provided bugreport type is not correct, value: "
12195                     + bugreportType);
12196         }
12197         enforceCallingPermission(android.Manifest.permission.DUMP, "requestBugReport");
12198         SystemProperties.set("ctl.start", service);
12199     }
12200
12201     public static long getInputDispatchingTimeoutLocked(ActivityRecord r) {
12202         return r != null ? getInputDispatchingTimeoutLocked(r.app) : KEY_DISPATCHING_TIMEOUT;
12203     }
12204
12205     public static long getInputDispatchingTimeoutLocked(ProcessRecord r) {
12206         if (r != null && (r.instrumentationClass != null || r.usingWrapper)) {
12207             return INSTRUMENTATION_KEY_DISPATCHING_TIMEOUT;
12208         }
12209         return KEY_DISPATCHING_TIMEOUT;
12210     }
12211
12212     @Override
12213     public long inputDispatchingTimedOut(int pid, final boolean aboveSystem, String reason) {
12214         if (checkCallingPermission(android.Manifest.permission.FILTER_EVENTS)
12215                 != PackageManager.PERMISSION_GRANTED) {
12216             throw new SecurityException("Requires permission "
12217                     + android.Manifest.permission.FILTER_EVENTS);
12218         }
12219         ProcessRecord proc;
12220         long timeout;
12221         synchronized (this) {
12222             synchronized (mPidsSelfLocked) {
12223                 proc = mPidsSelfLocked.get(pid);
12224             }
12225             timeout = getInputDispatchingTimeoutLocked(proc);
12226         }
12227
12228         if (!inputDispatchingTimedOut(proc, null, null, aboveSystem, reason)) {
12229             return -1;
12230         }
12231
12232         return timeout;
12233     }
12234
12235     /**
12236      * Handle input dispatching timeouts.
12237      * Returns whether input dispatching should be aborted or not.
12238      */
12239     public boolean inputDispatchingTimedOut(final ProcessRecord proc,
12240             final ActivityRecord activity, final ActivityRecord parent,
12241             final boolean aboveSystem, String reason) {
12242         if (checkCallingPermission(android.Manifest.permission.FILTER_EVENTS)
12243                 != PackageManager.PERMISSION_GRANTED) {
12244             throw new SecurityException("Requires permission "
12245                     + android.Manifest.permission.FILTER_EVENTS);
12246         }
12247
12248         final String annotation;
12249         if (reason == null) {
12250             annotation = "Input dispatching timed out";
12251         } else {
12252             annotation = "Input dispatching timed out (" + reason + ")";
12253         }
12254
12255         if (proc != null) {
12256             synchronized (this) {
12257                 if (proc.debugging) {
12258                     return false;
12259                 }
12260
12261                 if (mDidDexOpt) {
12262                     // Give more time since we were dexopting.
12263                     mDidDexOpt = false;
12264                     return false;
12265                 }
12266
12267                 if (proc.instrumentationClass != null) {
12268                     Bundle info = new Bundle();
12269                     info.putString("shortMsg", "keyDispatchingTimedOut");
12270                     info.putString("longMsg", annotation);
12271                     finishInstrumentationLocked(proc, Activity.RESULT_CANCELED, info);
12272                     return true;
12273                 }
12274             }
12275             mHandler.post(new Runnable() {
12276                 @Override
12277                 public void run() {
12278                     mAppErrors.appNotResponding(proc, activity, parent, aboveSystem, annotation);
12279                 }
12280             });
12281         }
12282
12283         return true;
12284     }
12285
12286     @Override
12287     public Bundle getAssistContextExtras(int requestType) {
12288         PendingAssistExtras pae = enqueueAssistContext(requestType, null, null, null,
12289                 null, null, true /* focused */, true /* newSessionId */,
12290                 UserHandle.getCallingUserId(), null, PENDING_ASSIST_EXTRAS_TIMEOUT);
12291         if (pae == null) {
12292             return null;
12293         }
12294         synchronized (pae) {
12295             while (!pae.haveResult) {
12296                 try {
12297                     pae.wait();
12298                 } catch (InterruptedException e) {
12299                 }
12300             }
12301         }
12302         synchronized (this) {
12303             buildAssistBundleLocked(pae, pae.result);
12304             mPendingAssistExtras.remove(pae);
12305             mUiHandler.removeCallbacks(pae);
12306         }
12307         return pae.extras;
12308     }
12309
12310     @Override
12311     public boolean isAssistDataAllowedOnCurrentActivity() {
12312         int userId;
12313         synchronized (this) {
12314             userId = mUserController.getCurrentUserIdLocked();
12315             ActivityRecord activity = getFocusedStack().topActivity();
12316             if (activity == null) {
12317                 return false;
12318             }
12319             userId = activity.userId;
12320         }
12321         DevicePolicyManager dpm = (DevicePolicyManager) mContext.getSystemService(
12322                 Context.DEVICE_POLICY_SERVICE);
12323         return (dpm == null) || (!dpm.getScreenCaptureDisabled(null, userId));
12324     }
12325
12326     @Override
12327     public boolean showAssistFromActivity(IBinder token, Bundle args) {
12328         long ident = Binder.clearCallingIdentity();
12329         try {
12330             synchronized (this) {
12331                 ActivityRecord caller = ActivityRecord.forTokenLocked(token);
12332                 ActivityRecord top = getFocusedStack().topActivity();
12333                 if (top != caller) {
12334                     Slog.w(TAG, "showAssistFromActivity failed: caller " + caller
12335                             + " is not current top " + top);
12336                     return false;
12337                 }
12338                 if (!top.nowVisible) {
12339                     Slog.w(TAG, "showAssistFromActivity failed: caller " + caller
12340                             + " is not visible");
12341                     return false;
12342                 }
12343             }
12344             AssistUtils utils = new AssistUtils(mContext);
12345             return utils.showSessionForActiveService(args,
12346                     VoiceInteractionSession.SHOW_SOURCE_APPLICATION, null, token);
12347         } finally {
12348             Binder.restoreCallingIdentity(ident);
12349         }
12350     }
12351
12352     @Override
12353     public boolean requestAssistContextExtras(int requestType, IResultReceiver receiver,
12354             Bundle receiverExtras,
12355             IBinder activityToken, boolean focused, boolean newSessionId) {
12356         return enqueueAssistContext(requestType, null, null, receiver, receiverExtras,
12357                 activityToken, focused, newSessionId,
12358                 UserHandle.getCallingUserId(), null, PENDING_ASSIST_EXTRAS_LONG_TIMEOUT)
12359                 != null;
12360     }
12361
12362     private PendingAssistExtras enqueueAssistContext(int requestType, Intent intent, String hint,
12363             IResultReceiver receiver, Bundle receiverExtras, IBinder activityToken,
12364             boolean focused, boolean newSessionId, int userHandle, Bundle args, long timeout) {
12365         enforceCallingPermission(android.Manifest.permission.GET_TOP_ACTIVITY_INFO,
12366                 "enqueueAssistContext()");
12367         synchronized (this) {
12368             ActivityRecord activity = getFocusedStack().topActivity();
12369             if (activity == null) {
12370                 Slog.w(TAG, "getAssistContextExtras failed: no top activity");
12371                 return null;
12372             }
12373             if (activity.app == null || activity.app.thread == null) {
12374                 Slog.w(TAG, "getAssistContextExtras failed: no process for " + activity);
12375                 return null;
12376             }
12377             if (focused) {
12378                 if (activityToken != null) {
12379                     ActivityRecord caller = ActivityRecord.forTokenLocked(activityToken);
12380                     if (activity != caller) {
12381                         Slog.w(TAG, "enqueueAssistContext failed: caller " + caller
12382                                 + " is not current top " + activity);
12383                         return null;
12384                     }
12385                 }
12386             } else {
12387                 activity = ActivityRecord.forTokenLocked(activityToken);
12388                 if (activity == null) {
12389                     Slog.w(TAG, "enqueueAssistContext failed: activity for token=" + activityToken
12390                             + " couldn't be found");
12391                     return null;
12392                 }
12393             }
12394
12395             PendingAssistExtras pae;
12396             Bundle extras = new Bundle();
12397             if (args != null) {
12398                 extras.putAll(args);
12399             }
12400             extras.putString(Intent.EXTRA_ASSIST_PACKAGE, activity.packageName);
12401             extras.putInt(Intent.EXTRA_ASSIST_UID, activity.app.uid);
12402             pae = new PendingAssistExtras(activity, extras, intent, hint, receiver, receiverExtras,
12403                     userHandle);
12404             // Increment the sessionId if necessary
12405             if (newSessionId) {
12406                 mViSessionId++;
12407             }
12408             try {
12409                 activity.app.thread.requestAssistContextExtras(activity.appToken, pae,
12410                         requestType, mViSessionId);
12411                 mPendingAssistExtras.add(pae);
12412                 mUiHandler.postDelayed(pae, timeout);
12413             } catch (RemoteException e) {
12414                 Slog.w(TAG, "getAssistContextExtras failed: crash calling " + activity);
12415                 return null;
12416             }
12417             return pae;
12418         }
12419     }
12420
12421     void pendingAssistExtrasTimedOut(PendingAssistExtras pae) {
12422         IResultReceiver receiver;
12423         synchronized (this) {
12424             mPendingAssistExtras.remove(pae);
12425             receiver = pae.receiver;
12426         }
12427         if (receiver != null) {
12428             // Caller wants result sent back to them.
12429             Bundle sendBundle = new Bundle();
12430             // At least return the receiver extras
12431             sendBundle.putBundle(VoiceInteractionSession.KEY_RECEIVER_EXTRAS,
12432                     pae.receiverExtras);
12433             try {
12434                 pae.receiver.send(0, sendBundle);
12435             } catch (RemoteException e) {
12436             }
12437         }
12438     }
12439
12440     private void buildAssistBundleLocked(PendingAssistExtras pae, Bundle result) {
12441         if (result != null) {
12442             pae.extras.putBundle(Intent.EXTRA_ASSIST_CONTEXT, result);
12443         }
12444         if (pae.hint != null) {
12445             pae.extras.putBoolean(pae.hint, true);
12446         }
12447     }
12448
12449     public void reportAssistContextExtras(IBinder token, Bundle extras, AssistStructure structure,
12450             AssistContent content, Uri referrer) {
12451         PendingAssistExtras pae = (PendingAssistExtras)token;
12452         synchronized (pae) {
12453             pae.result = extras;
12454             pae.structure = structure;
12455             pae.content = content;
12456             if (referrer != null) {
12457                 pae.extras.putParcelable(Intent.EXTRA_REFERRER, referrer);
12458             }
12459             pae.haveResult = true;
12460             pae.notifyAll();
12461             if (pae.intent == null && pae.receiver == null) {
12462                 // Caller is just waiting for the result.
12463                 return;
12464             }
12465         }
12466
12467         // We are now ready to launch the assist activity.
12468         IResultReceiver sendReceiver = null;
12469         Bundle sendBundle = null;
12470         synchronized (this) {
12471             buildAssistBundleLocked(pae, extras);
12472             boolean exists = mPendingAssistExtras.remove(pae);
12473             mUiHandler.removeCallbacks(pae);
12474             if (!exists) {
12475                 // Timed out.
12476                 return;
12477             }
12478             if ((sendReceiver=pae.receiver) != null) {
12479                 // Caller wants result sent back to them.
12480                 sendBundle = new Bundle();
12481                 sendBundle.putBundle(VoiceInteractionSession.KEY_DATA, pae.extras);
12482                 sendBundle.putParcelable(VoiceInteractionSession.KEY_STRUCTURE, pae.structure);
12483                 sendBundle.putParcelable(VoiceInteractionSession.KEY_CONTENT, pae.content);
12484                 sendBundle.putBundle(VoiceInteractionSession.KEY_RECEIVER_EXTRAS,
12485                         pae.receiverExtras);
12486             }
12487         }
12488         if (sendReceiver != null) {
12489             try {
12490                 sendReceiver.send(0, sendBundle);
12491             } catch (RemoteException e) {
12492             }
12493             return;
12494         }
12495
12496         long ident = Binder.clearCallingIdentity();
12497         try {
12498             pae.intent.replaceExtras(pae.extras);
12499             pae.intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK
12500                     | Intent.FLAG_ACTIVITY_SINGLE_TOP
12501                     | Intent.FLAG_ACTIVITY_CLEAR_TOP);
12502             closeSystemDialogs("assist");
12503             try {
12504                 mContext.startActivityAsUser(pae.intent, new UserHandle(pae.userHandle));
12505             } catch (ActivityNotFoundException e) {
12506                 Slog.w(TAG, "No activity to handle assist action.", e);
12507             }
12508         } finally {
12509             Binder.restoreCallingIdentity(ident);
12510         }
12511     }
12512
12513     public boolean launchAssistIntent(Intent intent, int requestType, String hint, int userHandle,
12514             Bundle args) {
12515         return enqueueAssistContext(requestType, intent, hint, null, null, null,
12516                 true /* focused */, true /* newSessionId */,
12517                 userHandle, args, PENDING_ASSIST_EXTRAS_TIMEOUT) != null;
12518     }
12519
12520     public void registerProcessObserver(IProcessObserver observer) {
12521         enforceCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER,
12522                 "registerProcessObserver()");
12523         synchronized (this) {
12524             mProcessObservers.register(observer);
12525         }
12526     }
12527
12528     @Override
12529     public void unregisterProcessObserver(IProcessObserver observer) {
12530         synchronized (this) {
12531             mProcessObservers.unregister(observer);
12532         }
12533     }
12534
12535     @Override
12536     public void registerUidObserver(IUidObserver observer, int which) {
12537         enforceCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER,
12538                 "registerUidObserver()");
12539         synchronized (this) {
12540             mUidObservers.register(observer, which);
12541         }
12542     }
12543
12544     @Override
12545     public void unregisterUidObserver(IUidObserver observer) {
12546         synchronized (this) {
12547             mUidObservers.unregister(observer);
12548         }
12549     }
12550
12551     @Override
12552     public boolean convertFromTranslucent(IBinder token) {
12553         final long origId = Binder.clearCallingIdentity();
12554         try {
12555             synchronized (this) {
12556                 final ActivityRecord r = ActivityRecord.isInStackLocked(token);
12557                 if (r == null) {
12558                     return false;
12559                 }
12560                 final boolean translucentChanged = r.changeWindowTranslucency(true);
12561                 if (translucentChanged) {
12562                     r.task.stack.releaseBackgroundResources(r);
12563                     mStackSupervisor.ensureActivitiesVisibleLocked(null, 0, !PRESERVE_WINDOWS);
12564                 }
12565                 mWindowManager.setAppFullscreen(token, true);
12566                 return translucentChanged;
12567             }
12568         } finally {
12569             Binder.restoreCallingIdentity(origId);
12570         }
12571     }
12572
12573     @Override
12574     public boolean convertToTranslucent(IBinder token, ActivityOptions options) {
12575         final long origId = Binder.clearCallingIdentity();
12576         try {
12577             synchronized (this) {
12578                 final ActivityRecord r = ActivityRecord.isInStackLocked(token);
12579                 if (r == null) {
12580                     return false;
12581                 }
12582                 int index = r.task.mActivities.lastIndexOf(r);
12583                 if (index > 0) {
12584                     ActivityRecord under = r.task.mActivities.get(index - 1);
12585                     under.returningOptions = options;
12586                 }
12587                 final boolean translucentChanged = r.changeWindowTranslucency(false);
12588                 if (translucentChanged) {
12589                     r.task.stack.convertActivityToTranslucent(r);
12590                 }
12591                 mStackSupervisor.ensureActivitiesVisibleLocked(null, 0, !PRESERVE_WINDOWS);
12592                 mWindowManager.setAppFullscreen(token, false);
12593                 return translucentChanged;
12594             }
12595         } finally {
12596             Binder.restoreCallingIdentity(origId);
12597         }
12598     }
12599
12600     @Override
12601     public boolean requestVisibleBehind(IBinder token, boolean visible) {
12602         final long origId = Binder.clearCallingIdentity();
12603         try {
12604             synchronized (this) {
12605                 final ActivityRecord r = ActivityRecord.isInStackLocked(token);
12606                 if (r != null) {
12607                     return mStackSupervisor.requestVisibleBehindLocked(r, visible);
12608                 }
12609             }
12610             return false;
12611         } finally {
12612             Binder.restoreCallingIdentity(origId);
12613         }
12614     }
12615
12616     @Override
12617     public boolean isBackgroundVisibleBehind(IBinder token) {
12618         final long origId = Binder.clearCallingIdentity();
12619         try {
12620             synchronized (this) {
12621                 final ActivityStack stack = ActivityRecord.getStackLocked(token);
12622                 final boolean visible = stack == null ? false : stack.hasVisibleBehindActivity();
12623                 if (DEBUG_VISIBLE_BEHIND) Slog.d(TAG_VISIBLE_BEHIND,
12624                         "isBackgroundVisibleBehind: stack=" + stack + " visible=" + visible);
12625                 return visible;
12626             }
12627         } finally {
12628             Binder.restoreCallingIdentity(origId);
12629         }
12630     }
12631
12632     @Override
12633     public ActivityOptions getActivityOptions(IBinder token) {
12634         final long origId = Binder.clearCallingIdentity();
12635         try {
12636             synchronized (this) {
12637                 final ActivityRecord r = ActivityRecord.isInStackLocked(token);
12638                 if (r != null) {
12639                     final ActivityOptions activityOptions = r.pendingOptions;
12640                     r.pendingOptions = null;
12641                     return activityOptions;
12642                 }
12643                 return null;
12644             }
12645         } finally {
12646             Binder.restoreCallingIdentity(origId);
12647         }
12648     }
12649
12650     @Override
12651     public void setImmersive(IBinder token, boolean immersive) {
12652         synchronized(this) {
12653             final ActivityRecord r = ActivityRecord.isInStackLocked(token);
12654             if (r == null) {
12655                 throw new IllegalArgumentException();
12656             }
12657             r.immersive = immersive;
12658
12659             // update associated state if we're frontmost
12660             if (r == mFocusedActivity) {
12661                 if (DEBUG_IMMERSIVE) Slog.d(TAG_IMMERSIVE, "Frontmost changed immersion: "+ r);
12662                 applyUpdateLockStateLocked(r);
12663             }
12664         }
12665     }
12666
12667     @Override
12668     public boolean isImmersive(IBinder token) {
12669         synchronized (this) {
12670             ActivityRecord r = ActivityRecord.isInStackLocked(token);
12671             if (r == null) {
12672                 throw new IllegalArgumentException();
12673             }
12674             return r.immersive;
12675         }
12676     }
12677
12678     public void setVrThread(int tid) {
12679         if (!mContext.getPackageManager().hasSystemFeature(PackageManager.FEATURE_VR_MODE)) {
12680             throw new UnsupportedOperationException("VR mode not supported on this device!");
12681         }
12682
12683         synchronized (this) {
12684             ProcessRecord proc;
12685             synchronized (mPidsSelfLocked) {
12686                 final int pid = Binder.getCallingPid();
12687                 proc = mPidsSelfLocked.get(pid);
12688
12689                 if (proc != null && mInVrMode && tid >= 0) {
12690                     // ensure the tid belongs to the process
12691                     if (!Process.isThreadInProcess(pid, tid)) {
12692                         throw new IllegalArgumentException("VR thread does not belong to process");
12693                     }
12694
12695                     // reset existing VR thread to CFS if this thread still exists and belongs to
12696                     // the calling process
12697                     if (proc.vrThreadTid != 0
12698                             && Process.isThreadInProcess(pid, proc.vrThreadTid)) {
12699                         try {
12700                             Process.setThreadScheduler(proc.vrThreadTid, Process.SCHED_OTHER, 0);
12701                         } catch (IllegalArgumentException e) {
12702                             // Ignore this.  Only occurs in race condition where previous VR thread
12703                             // was destroyed during this method call.
12704                         }
12705                     }
12706
12707                     proc.vrThreadTid = tid;
12708
12709                     // promote to FIFO now if the tid is non-zero
12710                     try {
12711                         if (proc.curSchedGroup == ProcessList.SCHED_GROUP_TOP_APP &&
12712                             proc.vrThreadTid > 0) {
12713                             Process.setThreadScheduler(proc.vrThreadTid,
12714                                 Process.SCHED_FIFO | Process.SCHED_RESET_ON_FORK, 1);
12715                         }
12716                     } catch (IllegalArgumentException e) {
12717                         Slog.e(TAG, "Failed to set scheduling policy, thread does"
12718                                + " not exist:\n" + e);
12719                     }
12720                 }
12721             }
12722         }
12723     }
12724
12725     @Override
12726     public void setRenderThread(int tid) {
12727         synchronized (this) {
12728             ProcessRecord proc;
12729             synchronized (mPidsSelfLocked) {
12730                 int pid = Binder.getCallingPid();
12731                 proc = mPidsSelfLocked.get(pid);
12732                 if (proc != null && proc.renderThreadTid == 0 && tid > 0) {
12733                     // ensure the tid belongs to the process
12734                     if (!Process.isThreadInProcess(pid, tid)) {
12735                         throw new IllegalArgumentException(
12736                             "Render thread does not belong to process");
12737                     }
12738                     proc.renderThreadTid = tid;
12739                     if (DEBUG_OOM_ADJ) {
12740                         Slog.d("UI_FIFO", "Set RenderThread tid " + tid + " for pid " + pid);
12741                     }
12742                     // promote to FIFO now
12743                     if (proc.curSchedGroup == ProcessList.SCHED_GROUP_TOP_APP) {
12744                         if (DEBUG_OOM_ADJ) Slog.d("UI_FIFO", "Promoting " + tid + "out of band");
12745                         if (mUseFifoUiScheduling) {
12746                             Process.setThreadScheduler(proc.renderThreadTid,
12747                                 Process.SCHED_FIFO | Process.SCHED_RESET_ON_FORK, 1);
12748                         } else {
12749                             Process.setThreadPriority(proc.renderThreadTid, -10);
12750                         }
12751                     }
12752                 } else {
12753                     if (DEBUG_OOM_ADJ) {
12754                         Slog.d("UI_FIFO", "Didn't set thread from setRenderThread? " +
12755                                "PID: " + pid + ", TID: " + tid + " FIFO: " +
12756                                mUseFifoUiScheduling);
12757                     }
12758                 }
12759             }
12760         }
12761     }
12762
12763     @Override
12764     public int setVrMode(IBinder token, boolean enabled, ComponentName packageName) {
12765         if (!mContext.getPackageManager().hasSystemFeature(PackageManager.FEATURE_VR_MODE)) {
12766             throw new UnsupportedOperationException("VR mode not supported on this device!");
12767         }
12768
12769         final VrManagerInternal vrService = LocalServices.getService(VrManagerInternal.class);
12770
12771         ActivityRecord r;
12772         synchronized (this) {
12773             r = ActivityRecord.isInStackLocked(token);
12774         }
12775
12776         if (r == null) {
12777             throw new IllegalArgumentException();
12778         }
12779
12780         int err;
12781         if ((err = vrService.hasVrPackage(packageName, r.userId)) !=
12782                 VrManagerInternal.NO_ERROR) {
12783             return err;
12784         }
12785
12786         synchronized(this) {
12787             r.requestedVrComponent = (enabled) ? packageName : null;
12788
12789             // Update associated state if this activity is currently focused
12790             if (r == mFocusedActivity) {
12791                 applyUpdateVrModeLocked(r);
12792             }
12793             return 0;
12794         }
12795     }
12796
12797     @Override
12798     public boolean isVrModePackageEnabled(ComponentName packageName) {
12799         if (!mContext.getPackageManager().hasSystemFeature(PackageManager.FEATURE_VR_MODE)) {
12800             throw new UnsupportedOperationException("VR mode not supported on this device!");
12801         }
12802
12803         final VrManagerInternal vrService = LocalServices.getService(VrManagerInternal.class);
12804
12805         return vrService.hasVrPackage(packageName, UserHandle.getCallingUserId()) ==
12806                 VrManagerInternal.NO_ERROR;
12807     }
12808
12809     public boolean isTopActivityImmersive() {
12810         enforceNotIsolatedCaller("startActivity");
12811         synchronized (this) {
12812             ActivityRecord r = getFocusedStack().topRunningActivityLocked();
12813             return (r != null) ? r.immersive : false;
12814         }
12815     }
12816
12817     @Override
12818     public boolean isTopOfTask(IBinder token) {
12819         synchronized (this) {
12820             ActivityRecord r = ActivityRecord.isInStackLocked(token);
12821             if (r == null) {
12822                 throw new IllegalArgumentException();
12823             }
12824             return r.task.getTopActivity() == r;
12825         }
12826     }
12827
12828     @Override
12829     public void setHasTopUi(boolean hasTopUi) throws RemoteException {
12830         if (checkCallingPermission(permission.INTERNAL_SYSTEM_WINDOW) != PERMISSION_GRANTED) {
12831             String msg = "Permission Denial: setHasTopUi() from pid="
12832                     + Binder.getCallingPid()
12833                     + ", uid=" + Binder.getCallingUid()
12834                     + " requires " + permission.INTERNAL_SYSTEM_WINDOW;
12835             Slog.w(TAG, msg);
12836             throw new SecurityException(msg);
12837         }
12838         final int pid = Binder.getCallingPid();
12839         final long origId = Binder.clearCallingIdentity();
12840         try {
12841             synchronized (this) {
12842                 boolean changed = false;
12843                 ProcessRecord pr;
12844                 synchronized (mPidsSelfLocked) {
12845                     pr = mPidsSelfLocked.get(pid);
12846                     if (pr == null) {
12847                         Slog.w(TAG, "setHasTopUi called on unknown pid: " + pid);
12848                         return;
12849                     }
12850                     if (pr.hasTopUi != hasTopUi) {
12851                         Slog.i(TAG, "Setting hasTopUi=" + hasTopUi + " for pid=" + pid);
12852                         pr.hasTopUi = hasTopUi;
12853                         changed = true;
12854                     }
12855                 }
12856                 if (changed) {
12857                     updateOomAdjLocked(pr);
12858                 }
12859             }
12860         } finally {
12861             Binder.restoreCallingIdentity(origId);
12862         }
12863     }
12864
12865     public final void enterSafeMode() {
12866         synchronized(this) {
12867             // It only makes sense to do this before the system is ready
12868             // and started launching other packages.
12869             if (!mSystemReady) {
12870                 try {
12871                     AppGlobals.getPackageManager().enterSafeMode();
12872                 } catch (RemoteException e) {
12873                 }
12874             }
12875
12876             mSafeMode = true;
12877         }
12878     }
12879
12880     public final void showSafeModeOverlay() {
12881         View v = LayoutInflater.from(mContext).inflate(
12882                 com.android.internal.R.layout.safe_mode, null);
12883         WindowManager.LayoutParams lp = new WindowManager.LayoutParams();
12884         lp.type = WindowManager.LayoutParams.TYPE_SECURE_SYSTEM_OVERLAY;
12885         lp.width = WindowManager.LayoutParams.WRAP_CONTENT;
12886         lp.height = WindowManager.LayoutParams.WRAP_CONTENT;
12887         lp.gravity = Gravity.BOTTOM | Gravity.START;
12888         lp.format = v.getBackground().getOpacity();
12889         lp.flags = WindowManager.LayoutParams.FLAG_NOT_FOCUSABLE
12890                 | WindowManager.LayoutParams.FLAG_NOT_TOUCHABLE;
12891         lp.privateFlags |= WindowManager.LayoutParams.PRIVATE_FLAG_SHOW_FOR_ALL_USERS;
12892         ((WindowManager)mContext.getSystemService(
12893                 Context.WINDOW_SERVICE)).addView(v, lp);
12894     }
12895
12896     public void noteWakeupAlarm(IIntentSender sender, int sourceUid, String sourcePkg, String tag) {
12897         if (sender != null && !(sender instanceof PendingIntentRecord)) {
12898             return;
12899         }
12900         final PendingIntentRecord rec = (PendingIntentRecord)sender;
12901         final BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
12902         synchronized (stats) {
12903             if (mBatteryStatsService.isOnBattery()) {
12904                 mBatteryStatsService.enforceCallingPermission();
12905                 int MY_UID = Binder.getCallingUid();
12906                 final int uid;
12907                 if (sender == null) {
12908                     uid = sourceUid;
12909                 } else {
12910                     uid = rec.uid == MY_UID ? Process.SYSTEM_UID : rec.uid;
12911                 }
12912                 BatteryStatsImpl.Uid.Pkg pkg =
12913                     stats.getPackageStatsLocked(sourceUid >= 0 ? sourceUid : uid,
12914                             sourcePkg != null ? sourcePkg : rec.key.packageName);
12915                 pkg.noteWakeupAlarmLocked(tag);
12916             }
12917         }
12918     }
12919
12920     public void noteAlarmStart(IIntentSender sender, int sourceUid, String tag) {
12921         if (sender != null && !(sender instanceof PendingIntentRecord)) {
12922             return;
12923         }
12924         final PendingIntentRecord rec = (PendingIntentRecord)sender;
12925         final BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
12926         synchronized (stats) {
12927             mBatteryStatsService.enforceCallingPermission();
12928             int MY_UID = Binder.getCallingUid();
12929             final int uid;
12930             if (sender == null) {
12931                 uid = sourceUid;
12932             } else {
12933                 uid = rec.uid == MY_UID ? Process.SYSTEM_UID : rec.uid;
12934             }
12935             mBatteryStatsService.noteAlarmStart(tag, sourceUid >= 0 ? sourceUid : uid);
12936         }
12937     }
12938
12939     public void noteAlarmFinish(IIntentSender sender, int sourceUid, String tag) {
12940         if (sender != null && !(sender instanceof PendingIntentRecord)) {
12941             return;
12942         }
12943         final PendingIntentRecord rec = (PendingIntentRecord)sender;
12944         final BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
12945         synchronized (stats) {
12946             mBatteryStatsService.enforceCallingPermission();
12947             int MY_UID = Binder.getCallingUid();
12948             final int uid;
12949             if (sender == null) {
12950                 uid = sourceUid;
12951             } else {
12952                 uid = rec.uid == MY_UID ? Process.SYSTEM_UID : rec.uid;
12953             }
12954             mBatteryStatsService.noteAlarmFinish(tag, sourceUid >= 0 ? sourceUid : uid);
12955         }
12956     }
12957
12958     public boolean killPids(int[] pids, String pReason, boolean secure) {
12959         if (Binder.getCallingUid() != Process.SYSTEM_UID) {
12960             throw new SecurityException("killPids only available to the system");
12961         }
12962         String reason = (pReason == null) ? "Unknown" : pReason;
12963         // XXX Note: don't acquire main activity lock here, because the window
12964         // manager calls in with its locks held.
12965
12966         boolean killed = false;
12967         synchronized (mPidsSelfLocked) {
12968             int worstType = 0;
12969             for (int i=0; i<pids.length; i++) {
12970                 ProcessRecord proc = mPidsSelfLocked.get(pids[i]);
12971                 if (proc != null) {
12972                     int type = proc.setAdj;
12973                     if (type > worstType) {
12974                         worstType = type;
12975                     }
12976                 }
12977             }
12978
12979             // If the worst oom_adj is somewhere in the cached proc LRU range,
12980             // then constrain it so we will kill all cached procs.
12981             if (worstType < ProcessList.CACHED_APP_MAX_ADJ
12982                     && worstType > ProcessList.CACHED_APP_MIN_ADJ) {
12983                 worstType = ProcessList.CACHED_APP_MIN_ADJ;
12984             }
12985
12986             // If this is not a secure call, don't let it kill processes that
12987             // are important.
12988             if (!secure && worstType < ProcessList.SERVICE_ADJ) {
12989                 worstType = ProcessList.SERVICE_ADJ;
12990             }
12991
12992             Slog.w(TAG, "Killing processes " + reason + " at adjustment " + worstType);
12993             for (int i=0; i<pids.length; i++) {
12994                 ProcessRecord proc = mPidsSelfLocked.get(pids[i]);
12995                 if (proc == null) {
12996                     continue;
12997                 }
12998                 int adj = proc.setAdj;
12999                 if (adj >= worstType && !proc.killedByAm) {
13000                     proc.kill(reason, true);
13001                     killed = true;
13002                 }
13003             }
13004         }
13005         return killed;
13006     }
13007
13008     @Override
13009     public void killUid(int appId, int userId, String reason) {
13010         enforceCallingPermission(Manifest.permission.KILL_UID, "killUid");
13011         synchronized (this) {
13012             final long identity = Binder.clearCallingIdentity();
13013             try {
13014                 killPackageProcessesLocked(null, appId, userId,
13015                         ProcessList.PERSISTENT_PROC_ADJ, false, true, true, true,
13016                         reason != null ? reason : "kill uid");
13017             } finally {
13018                 Binder.restoreCallingIdentity(identity);
13019             }
13020         }
13021     }
13022
13023     @Override
13024     public boolean killProcessesBelowForeground(String reason) {
13025         if (Binder.getCallingUid() != Process.SYSTEM_UID) {
13026             throw new SecurityException("killProcessesBelowForeground() only available to system");
13027         }
13028
13029         return killProcessesBelowAdj(ProcessList.FOREGROUND_APP_ADJ, reason);
13030     }
13031
13032     private boolean killProcessesBelowAdj(int belowAdj, String reason) {
13033         if (Binder.getCallingUid() != Process.SYSTEM_UID) {
13034             throw new SecurityException("killProcessesBelowAdj() only available to system");
13035         }
13036
13037         boolean killed = false;
13038         synchronized (mPidsSelfLocked) {
13039             final int size = mPidsSelfLocked.size();
13040             for (int i = 0; i < size; i++) {
13041                 final int pid = mPidsSelfLocked.keyAt(i);
13042                 final ProcessRecord proc = mPidsSelfLocked.valueAt(i);
13043                 if (proc == null) continue;
13044
13045                 final int adj = proc.setAdj;
13046                 if (adj > belowAdj && !proc.killedByAm) {
13047                     proc.kill(reason, true);
13048                     killed = true;
13049                 }
13050             }
13051         }
13052         return killed;
13053     }
13054
13055     @Override
13056     public void hang(final IBinder who, boolean allowRestart) {
13057         if (checkCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER)
13058                 != PackageManager.PERMISSION_GRANTED) {
13059             throw new SecurityException("Requires permission "
13060                     + android.Manifest.permission.SET_ACTIVITY_WATCHER);
13061         }
13062
13063         final IBinder.DeathRecipient death = new DeathRecipient() {
13064             @Override
13065             public void binderDied() {
13066                 synchronized (this) {
13067                     notifyAll();
13068                 }
13069             }
13070         };
13071
13072         try {
13073             who.linkToDeath(death, 0);
13074         } catch (RemoteException e) {
13075             Slog.w(TAG, "hang: given caller IBinder is already dead.");
13076             return;
13077         }
13078
13079         synchronized (this) {
13080             Watchdog.getInstance().setAllowRestart(allowRestart);
13081             Slog.i(TAG, "Hanging system process at request of pid " + Binder.getCallingPid());
13082             synchronized (death) {
13083                 while (who.isBinderAlive()) {
13084                     try {
13085                         death.wait();
13086                     } catch (InterruptedException e) {
13087                     }
13088                 }
13089             }
13090             Watchdog.getInstance().setAllowRestart(true);
13091         }
13092     }
13093
13094     @Override
13095     public void restart() {
13096         if (checkCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER)
13097                 != PackageManager.PERMISSION_GRANTED) {
13098             throw new SecurityException("Requires permission "
13099                     + android.Manifest.permission.SET_ACTIVITY_WATCHER);
13100         }
13101
13102         Log.i(TAG, "Sending shutdown broadcast...");
13103
13104         BroadcastReceiver br = new BroadcastReceiver() {
13105             @Override public void onReceive(Context context, Intent intent) {
13106                 // Now the broadcast is done, finish up the low-level shutdown.
13107                 Log.i(TAG, "Shutting down activity manager...");
13108                 shutdown(10000);
13109                 Log.i(TAG, "Shutdown complete, restarting!");
13110                 Process.killProcess(Process.myPid());
13111                 System.exit(10);
13112             }
13113         };
13114
13115         // First send the high-level shut down broadcast.
13116         Intent intent = new Intent(Intent.ACTION_SHUTDOWN);
13117         intent.addFlags(Intent.FLAG_RECEIVER_FOREGROUND);
13118         intent.putExtra(Intent.EXTRA_SHUTDOWN_USERSPACE_ONLY, true);
13119         /* For now we are not doing a clean shutdown, because things seem to get unhappy.
13120         mContext.sendOrderedBroadcastAsUser(intent,
13121                 UserHandle.ALL, null, br, mHandler, 0, null, null);
13122         */
13123         br.onReceive(mContext, intent);
13124     }
13125
13126     private long getLowRamTimeSinceIdle(long now) {
13127         return mLowRamTimeSinceLastIdle + (mLowRamStartTime > 0 ? (now-mLowRamStartTime) : 0);
13128     }
13129
13130     @Override
13131     public void performIdleMaintenance() {
13132         if (checkCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER)
13133                 != PackageManager.PERMISSION_GRANTED) {
13134             throw new SecurityException("Requires permission "
13135                     + android.Manifest.permission.SET_ACTIVITY_WATCHER);
13136         }
13137
13138         synchronized (this) {
13139             final long now = SystemClock.uptimeMillis();
13140             final long timeSinceLastIdle = now - mLastIdleTime;
13141             final long lowRamSinceLastIdle = getLowRamTimeSinceIdle(now);
13142             mLastIdleTime = now;
13143             mLowRamTimeSinceLastIdle = 0;
13144             if (mLowRamStartTime != 0) {
13145                 mLowRamStartTime = now;
13146             }
13147
13148             StringBuilder sb = new StringBuilder(128);
13149             sb.append("Idle maintenance over ");
13150             TimeUtils.formatDuration(timeSinceLastIdle, sb);
13151             sb.append(" low RAM for ");
13152             TimeUtils.formatDuration(lowRamSinceLastIdle, sb);
13153             Slog.i(TAG, sb.toString());
13154
13155             // If at least 1/3 of our time since the last idle period has been spent
13156             // with RAM low, then we want to kill processes.
13157             boolean doKilling = lowRamSinceLastIdle > (timeSinceLastIdle/3);
13158
13159             for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) {
13160                 ProcessRecord proc = mLruProcesses.get(i);
13161                 if (proc.notCachedSinceIdle) {
13162                     if (proc.setProcState != ActivityManager.PROCESS_STATE_TOP_SLEEPING
13163                             && proc.setProcState >= ActivityManager.PROCESS_STATE_FOREGROUND_SERVICE
13164                             && proc.setProcState <= ActivityManager.PROCESS_STATE_SERVICE) {
13165                         if (doKilling && proc.initialIdlePss != 0
13166                                 && proc.lastPss > ((proc.initialIdlePss*3)/2)) {
13167                             sb = new StringBuilder(128);
13168                             sb.append("Kill");
13169                             sb.append(proc.processName);
13170                             sb.append(" in idle maint: pss=");
13171                             sb.append(proc.lastPss);
13172                             sb.append(", swapPss=");
13173                             sb.append(proc.lastSwapPss);
13174                             sb.append(", initialPss=");
13175                             sb.append(proc.initialIdlePss);
13176                             sb.append(", period=");
13177                             TimeUtils.formatDuration(timeSinceLastIdle, sb);
13178                             sb.append(", lowRamPeriod=");
13179                             TimeUtils.formatDuration(lowRamSinceLastIdle, sb);
13180                             Slog.wtfQuiet(TAG, sb.toString());
13181                             proc.kill("idle maint (pss " + proc.lastPss
13182                                     + " from " + proc.initialIdlePss + ")", true);
13183                         }
13184                     }
13185                 } else if (proc.setProcState < ActivityManager.PROCESS_STATE_HOME
13186                         && proc.setProcState > ActivityManager.PROCESS_STATE_NONEXISTENT) {
13187                     proc.notCachedSinceIdle = true;
13188                     proc.initialIdlePss = 0;
13189                     proc.nextPssTime = ProcessList.computeNextPssTime(proc.setProcState, true,
13190                             mTestPssMode, isSleepingLocked(), now);
13191                 }
13192             }
13193
13194             mHandler.removeMessages(REQUEST_ALL_PSS_MSG);
13195             mHandler.sendEmptyMessageDelayed(REQUEST_ALL_PSS_MSG, 2*60*1000);
13196         }
13197     }
13198
13199     @Override
13200     public void sendIdleJobTrigger() {
13201         if (checkCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER)
13202                 != PackageManager.PERMISSION_GRANTED) {
13203             throw new SecurityException("Requires permission "
13204                     + android.Manifest.permission.SET_ACTIVITY_WATCHER);
13205         }
13206
13207         final long ident = Binder.clearCallingIdentity();
13208         try {
13209             Intent intent = new Intent(ACTION_TRIGGER_IDLE)
13210                     .setPackage("android")
13211                     .addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY);
13212             broadcastIntent(null, intent, null, null, 0, null, null, null,
13213                     android.app.AppOpsManager.OP_NONE, null, true, false, UserHandle.USER_ALL);
13214         } finally {
13215             Binder.restoreCallingIdentity(ident);
13216         }
13217     }
13218
13219     private void retrieveSettings() {
13220         final ContentResolver resolver = mContext.getContentResolver();
13221         final boolean freeformWindowManagement =
13222                 mContext.getPackageManager().hasSystemFeature(FEATURE_FREEFORM_WINDOW_MANAGEMENT)
13223                         || Settings.Global.getInt(
13224                                 resolver, DEVELOPMENT_ENABLE_FREEFORM_WINDOWS_SUPPORT, 0) != 0;
13225         final boolean supportsPictureInPicture =
13226                 mContext.getPackageManager().hasSystemFeature(FEATURE_PICTURE_IN_PICTURE);
13227
13228         final boolean supportsMultiWindow = ActivityManager.supportsMultiWindow();
13229         final String debugApp = Settings.Global.getString(resolver, DEBUG_APP);
13230         final boolean waitForDebugger = Settings.Global.getInt(resolver, WAIT_FOR_DEBUGGER, 0) != 0;
13231         final boolean alwaysFinishActivities =
13232                 Settings.Global.getInt(resolver, ALWAYS_FINISH_ACTIVITIES, 0) != 0;
13233         final boolean lenientBackgroundCheck =
13234                 Settings.Global.getInt(resolver, LENIENT_BACKGROUND_CHECK, 0) != 0;
13235         final boolean forceRtl = Settings.Global.getInt(resolver, DEVELOPMENT_FORCE_RTL, 0) != 0;
13236         final boolean forceResizable = Settings.Global.getInt(
13237                 resolver, DEVELOPMENT_FORCE_RESIZABLE_ACTIVITIES, 0) != 0;
13238         final boolean supportsLeanbackOnly =
13239                 mContext.getPackageManager().hasSystemFeature(FEATURE_LEANBACK_ONLY);
13240
13241         // Transfer any global setting for forcing RTL layout, into a System Property
13242         SystemProperties.set(DEVELOPMENT_FORCE_RTL, forceRtl ? "1":"0");
13243
13244         final Configuration configuration = new Configuration();
13245         Settings.System.getConfiguration(resolver, configuration);
13246         if (forceRtl) {
13247             // This will take care of setting the correct layout direction flags
13248             configuration.setLayoutDirection(configuration.locale);
13249         }
13250
13251         synchronized (this) {
13252             mDebugApp = mOrigDebugApp = debugApp;
13253             mWaitForDebugger = mOrigWaitForDebugger = waitForDebugger;
13254             mAlwaysFinishActivities = alwaysFinishActivities;
13255             mLenientBackgroundCheck = lenientBackgroundCheck;
13256             mSupportsLeanbackOnly = supportsLeanbackOnly;
13257             mForceResizableActivities = forceResizable;
13258             mWindowManager.setForceResizableTasks(mForceResizableActivities);
13259             if (supportsMultiWindow || forceResizable) {
13260                 mSupportsMultiWindow = true;
13261                 mSupportsFreeformWindowManagement = freeformWindowManagement || forceResizable;
13262                 mSupportsPictureInPicture = supportsPictureInPicture || forceResizable;
13263             } else {
13264                 mSupportsMultiWindow = false;
13265                 mSupportsFreeformWindowManagement = false;
13266                 mSupportsPictureInPicture = false;
13267             }
13268             // This happens before any activities are started, so we can
13269             // change mConfiguration in-place.
13270             updateConfigurationLocked(configuration, null, true);
13271             if (DEBUG_CONFIGURATION) Slog.v(TAG_CONFIGURATION,
13272                     "Initial config: " + mConfiguration);
13273
13274             // Load resources only after the current configuration has been set.
13275             final Resources res = mContext.getResources();
13276             mHasRecents = res.getBoolean(com.android.internal.R.bool.config_hasRecents);
13277             mThumbnailWidth = res.getDimensionPixelSize(
13278                     com.android.internal.R.dimen.thumbnail_width);
13279             mThumbnailHeight = res.getDimensionPixelSize(
13280                     com.android.internal.R.dimen.thumbnail_height);
13281             mDefaultPinnedStackBounds = Rect.unflattenFromString(res.getString(
13282                     com.android.internal.R.string.config_defaultPictureInPictureBounds));
13283             mAppErrors.loadAppsNotReportingCrashesFromConfigLocked(res.getString(
13284                     com.android.internal.R.string.config_appsNotReportingCrashes));
13285             if ((mConfiguration.uiMode & UI_MODE_TYPE_TELEVISION) == UI_MODE_TYPE_TELEVISION) {
13286                 mFullscreenThumbnailScale = (float) res
13287                     .getInteger(com.android.internal.R.integer.thumbnail_width_tv) /
13288                     (float) mConfiguration.screenWidthDp;
13289             } else {
13290                 mFullscreenThumbnailScale = res.getFraction(
13291                     com.android.internal.R.fraction.thumbnail_fullscreen_scale, 1, 1);
13292             }
13293         }
13294     }
13295
13296     public boolean testIsSystemReady() {
13297         // no need to synchronize(this) just to read & return the value
13298         return mSystemReady;
13299     }
13300
13301     public void systemReady(final Runnable goingCallback) {
13302         synchronized(this) {
13303             if (mSystemReady) {
13304                 // If we're done calling all the receivers, run the next "boot phase" passed in
13305                 // by the SystemServer
13306                 if (goingCallback != null) {
13307                     goingCallback.run();
13308                 }
13309                 return;
13310             }
13311
13312             mLocalDeviceIdleController
13313                     = LocalServices.getService(DeviceIdleController.LocalService.class);
13314
13315             // Make sure we have the current profile info, since it is needed for security checks.
13316             mUserController.onSystemReady();
13317             mRecentTasks.onSystemReadyLocked();
13318             mAppOpsService.systemReady();
13319             mSystemReady = true;
13320         }
13321
13322         ArrayList<ProcessRecord> procsToKill = null;
13323         synchronized(mPidsSelfLocked) {
13324             for (int i=mPidsSelfLocked.size()-1; i>=0; i--) {
13325                 ProcessRecord proc = mPidsSelfLocked.valueAt(i);
13326                 if (!isAllowedWhileBooting(proc.info)){
13327                     if (procsToKill == null) {
13328                         procsToKill = new ArrayList<ProcessRecord>();
13329                     }
13330                     procsToKill.add(proc);
13331                 }
13332             }
13333         }
13334
13335         synchronized(this) {
13336             if (procsToKill != null) {
13337                 for (int i=procsToKill.size()-1; i>=0; i--) {
13338                     ProcessRecord proc = procsToKill.get(i);
13339                     Slog.i(TAG, "Removing system update proc: " + proc);
13340                     removeProcessLocked(proc, true, false, "system update done");
13341                 }
13342             }
13343
13344             // Now that we have cleaned up any update processes, we
13345             // are ready to start launching real processes and know that
13346             // we won't trample on them any more.
13347             mProcessesReady = true;
13348         }
13349
13350         Slog.i(TAG, "System now ready");
13351         EventLog.writeEvent(EventLogTags.BOOT_PROGRESS_AMS_READY,
13352             SystemClock.uptimeMillis());
13353
13354         synchronized(this) {
13355             // Make sure we have no pre-ready processes sitting around.
13356
13357             if (mFactoryTest == FactoryTest.FACTORY_TEST_LOW_LEVEL) {
13358                 ResolveInfo ri = mContext.getPackageManager()
13359                         .resolveActivity(new Intent(Intent.ACTION_FACTORY_TEST),
13360                                 STOCK_PM_FLAGS);
13361                 CharSequence errorMsg = null;
13362                 if (ri != null) {
13363                     ActivityInfo ai = ri.activityInfo;
13364                     ApplicationInfo app = ai.applicationInfo;
13365                     if ((app.flags&ApplicationInfo.FLAG_SYSTEM) != 0) {
13366                         mTopAction = Intent.ACTION_FACTORY_TEST;
13367                         mTopData = null;
13368                         mTopComponent = new ComponentName(app.packageName,
13369                                 ai.name);
13370                     } else {
13371                         errorMsg = mContext.getResources().getText(
13372                                 com.android.internal.R.string.factorytest_not_system);
13373                     }
13374                 } else {
13375                     errorMsg = mContext.getResources().getText(
13376                             com.android.internal.R.string.factorytest_no_action);
13377                 }
13378                 if (errorMsg != null) {
13379                     mTopAction = null;
13380                     mTopData = null;
13381                     mTopComponent = null;
13382                     Message msg = Message.obtain();
13383                     msg.what = SHOW_FACTORY_ERROR_UI_MSG;
13384                     msg.getData().putCharSequence("msg", errorMsg);
13385                     mUiHandler.sendMessage(msg);
13386                 }
13387             }
13388         }
13389
13390         retrieveSettings();
13391         final int currentUserId;
13392         synchronized (this) {
13393             currentUserId = mUserController.getCurrentUserIdLocked();
13394             readGrantedUriPermissionsLocked();
13395         }
13396
13397         if (goingCallback != null) goingCallback.run();
13398
13399         mBatteryStatsService.noteEvent(BatteryStats.HistoryItem.EVENT_USER_RUNNING_START,
13400                 Integer.toString(currentUserId), currentUserId);
13401         mBatteryStatsService.noteEvent(BatteryStats.HistoryItem.EVENT_USER_FOREGROUND_START,
13402                 Integer.toString(currentUserId), currentUserId);
13403         mSystemServiceManager.startUser(currentUserId);
13404
13405         synchronized (this) {
13406             // Only start up encryption-aware persistent apps; once user is
13407             // unlocked we'll come back around and start unaware apps
13408             startPersistentApps(PackageManager.MATCH_DIRECT_BOOT_AWARE);
13409
13410             // Start up initial activity.
13411             mBooting = true;
13412             // Enable home activity for system user, so that the system can always boot
13413             if (UserManager.isSplitSystemUser()) {
13414                 ComponentName cName = new ComponentName(mContext, SystemUserHomeActivity.class);
13415                 try {
13416                     AppGlobals.getPackageManager().setComponentEnabledSetting(cName,
13417                             PackageManager.COMPONENT_ENABLED_STATE_ENABLED, 0,
13418                             UserHandle.USER_SYSTEM);
13419                 } catch (RemoteException e) {
13420                     throw e.rethrowAsRuntimeException();
13421                 }
13422             }
13423             startHomeActivityLocked(currentUserId, "systemReady");
13424
13425             try {
13426                 if (AppGlobals.getPackageManager().hasSystemUidErrors()) {
13427                     Slog.e(TAG, "UIDs on the system are inconsistent, you need to wipe your"
13428                             + " data partition or your device will be unstable.");
13429                     mUiHandler.obtainMessage(SHOW_UID_ERROR_UI_MSG).sendToTarget();
13430                 }
13431             } catch (RemoteException e) {
13432             }
13433
13434             if (!Build.isBuildConsistent()) {
13435                 Slog.e(TAG, "Build fingerprint is not consistent, warning user");
13436                 mUiHandler.obtainMessage(SHOW_FINGERPRINT_ERROR_UI_MSG).sendToTarget();
13437             }
13438
13439             long ident = Binder.clearCallingIdentity();
13440             try {
13441                 Intent intent = new Intent(Intent.ACTION_USER_STARTED);
13442                 intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY
13443                         | Intent.FLAG_RECEIVER_FOREGROUND);
13444                 intent.putExtra(Intent.EXTRA_USER_HANDLE, currentUserId);
13445                 broadcastIntentLocked(null, null, intent,
13446                         null, null, 0, null, null, null, AppOpsManager.OP_NONE,
13447                         null, false, false, MY_PID, Process.SYSTEM_UID,
13448                         currentUserId);
13449                 intent = new Intent(Intent.ACTION_USER_STARTING);
13450                 intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY);
13451                 intent.putExtra(Intent.EXTRA_USER_HANDLE, currentUserId);
13452                 broadcastIntentLocked(null, null, intent,
13453                         null, new IIntentReceiver.Stub() {
13454                             @Override
13455                             public void performReceive(Intent intent, int resultCode, String data,
13456                                     Bundle extras, boolean ordered, boolean sticky, int sendingUser)
13457                                     throws RemoteException {
13458                             }
13459                         }, 0, null, null,
13460                         new String[] {INTERACT_ACROSS_USERS}, AppOpsManager.OP_NONE,
13461                         null, true, false, MY_PID, Process.SYSTEM_UID, UserHandle.USER_ALL);
13462             } catch (Throwable t) {
13463                 Slog.wtf(TAG, "Failed sending first user broadcasts", t);
13464             } finally {
13465                 Binder.restoreCallingIdentity(ident);
13466             }
13467             mStackSupervisor.resumeFocusedStackTopActivityLocked();
13468             mUserController.sendUserSwitchBroadcastsLocked(-1, currentUserId);
13469         }
13470     }
13471
13472     void killAppAtUsersRequest(ProcessRecord app, Dialog fromDialog) {
13473         synchronized (this) {
13474             mAppErrors.killAppAtUserRequestLocked(app, fromDialog);
13475         }
13476     }
13477
13478     void skipCurrentReceiverLocked(ProcessRecord app) {
13479         for (BroadcastQueue queue : mBroadcastQueues) {
13480             queue.skipCurrentReceiverLocked(app);
13481         }
13482     }
13483
13484     /**
13485      * Used by {@link com.android.internal.os.RuntimeInit} to report when an application crashes.
13486      * The application process will exit immediately after this call returns.
13487      * @param app object of the crashing app, null for the system server
13488      * @param crashInfo describing the exception
13489      */
13490     public void handleApplicationCrash(IBinder app, ApplicationErrorReport.CrashInfo crashInfo) {
13491         ProcessRecord r = findAppProcess(app, "Crash");
13492         final String processName = app == null ? "system_server"
13493                 : (r == null ? "unknown" : r.processName);
13494
13495         handleApplicationCrashInner("crash", r, processName, crashInfo);
13496     }
13497
13498     /* Native crash reporting uses this inner version because it needs to be somewhat
13499      * decoupled from the AM-managed cleanup lifecycle
13500      */
13501     void handleApplicationCrashInner(String eventType, ProcessRecord r, String processName,
13502             ApplicationErrorReport.CrashInfo crashInfo) {
13503         EventLog.writeEvent(EventLogTags.AM_CRASH, Binder.getCallingPid(),
13504                 UserHandle.getUserId(Binder.getCallingUid()), processName,
13505                 r == null ? -1 : r.info.flags,
13506                 crashInfo.exceptionClassName,
13507                 crashInfo.exceptionMessage,
13508                 crashInfo.throwFileName,
13509                 crashInfo.throwLineNumber);
13510
13511         addErrorToDropBox(eventType, r, processName, null, null, null, null, null, crashInfo);
13512
13513         mAppErrors.crashApplication(r, crashInfo);
13514     }
13515
13516     public void handleApplicationStrictModeViolation(
13517             IBinder app,
13518             int violationMask,
13519             StrictMode.ViolationInfo info) {
13520         ProcessRecord r = findAppProcess(app, "StrictMode");
13521         if (r == null) {
13522             return;
13523         }
13524
13525         if ((violationMask & StrictMode.PENALTY_DROPBOX) != 0) {
13526             Integer stackFingerprint = info.hashCode();
13527             boolean logIt = true;
13528             synchronized (mAlreadyLoggedViolatedStacks) {
13529                 if (mAlreadyLoggedViolatedStacks.contains(stackFingerprint)) {
13530                     logIt = false;
13531                     // TODO: sub-sample into EventLog for these, with
13532                     // the info.durationMillis?  Then we'd get
13533                     // the relative pain numbers, without logging all
13534                     // the stack traces repeatedly.  We'd want to do
13535                     // likewise in the client code, which also does
13536                     // dup suppression, before the Binder call.
13537                 } else {
13538                     if (mAlreadyLoggedViolatedStacks.size() >= MAX_DUP_SUPPRESSED_STACKS) {
13539                         mAlreadyLoggedViolatedStacks.clear();
13540                     }
13541                     mAlreadyLoggedViolatedStacks.add(stackFingerprint);
13542                 }
13543             }
13544             if (logIt) {
13545                 logStrictModeViolationToDropBox(r, info);
13546             }
13547         }
13548
13549         if ((violationMask & StrictMode.PENALTY_DIALOG) != 0) {
13550             AppErrorResult result = new AppErrorResult();
13551             synchronized (this) {
13552                 final long origId = Binder.clearCallingIdentity();
13553
13554                 Message msg = Message.obtain();
13555                 msg.what = SHOW_STRICT_MODE_VIOLATION_UI_MSG;
13556                 HashMap<String, Object> data = new HashMap<String, Object>();
13557                 data.put("result", result);
13558                 data.put("app", r);
13559                 data.put("violationMask", violationMask);
13560                 data.put("info", info);
13561                 msg.obj = data;
13562                 mUiHandler.sendMessage(msg);
13563
13564                 Binder.restoreCallingIdentity(origId);
13565             }
13566             int res = result.get();
13567             Slog.w(TAG, "handleApplicationStrictModeViolation; res=" + res);
13568         }
13569     }
13570
13571     // Depending on the policy in effect, there could be a bunch of
13572     // these in quick succession so we try to batch these together to
13573     // minimize disk writes, number of dropbox entries, and maximize
13574     // compression, by having more fewer, larger records.
13575     private void logStrictModeViolationToDropBox(
13576             ProcessRecord process,
13577             StrictMode.ViolationInfo info) {
13578         if (info == null) {
13579             return;
13580         }
13581         final boolean isSystemApp = process == null ||
13582                 (process.info.flags & (ApplicationInfo.FLAG_SYSTEM |
13583                                        ApplicationInfo.FLAG_UPDATED_SYSTEM_APP)) != 0;
13584         final String processName = process == null ? "unknown" : process.processName;
13585         final String dropboxTag = isSystemApp ? "system_app_strictmode" : "data_app_strictmode";
13586         final DropBoxManager dbox = (DropBoxManager)
13587                 mContext.getSystemService(Context.DROPBOX_SERVICE);
13588
13589         // Exit early if the dropbox isn't configured to accept this report type.
13590         if (dbox == null || !dbox.isTagEnabled(dropboxTag)) return;
13591
13592         boolean bufferWasEmpty;
13593         boolean needsFlush;
13594         final StringBuilder sb = isSystemApp ? mStrictModeBuffer : new StringBuilder(1024);
13595         synchronized (sb) {
13596             bufferWasEmpty = sb.length() == 0;
13597             appendDropBoxProcessHeaders(process, processName, sb);
13598             sb.append("Build: ").append(Build.FINGERPRINT).append("\n");
13599             sb.append("System-App: ").append(isSystemApp).append("\n");
13600             sb.append("Uptime-Millis: ").append(info.violationUptimeMillis).append("\n");
13601             if (info.violationNumThisLoop != 0) {
13602                 sb.append("Loop-Violation-Number: ").append(info.violationNumThisLoop).append("\n");
13603             }
13604             if (info.numAnimationsRunning != 0) {
13605                 sb.append("Animations-Running: ").append(info.numAnimationsRunning).append("\n");
13606             }
13607             if (info.broadcastIntentAction != null) {
13608                 sb.append("Broadcast-Intent-Action: ").append(info.broadcastIntentAction).append("\n");
13609             }
13610             if (info.durationMillis != -1) {
13611                 sb.append("Duration-Millis: ").append(info.durationMillis).append("\n");
13612             }
13613             if (info.numInstances != -1) {
13614                 sb.append("Instance-Count: ").append(info.numInstances).append("\n");
13615             }
13616             if (info.tags != null) {
13617                 for (String tag : info.tags) {
13618                     sb.append("Span-Tag: ").append(tag).append("\n");
13619                 }
13620             }
13621             sb.append("\n");
13622             if (info.crashInfo != null && info.crashInfo.stackTrace != null) {
13623                 sb.append(info.crashInfo.stackTrace);
13624                 sb.append("\n");
13625             }
13626             if (info.message != null) {
13627                 sb.append(info.message);
13628                 sb.append("\n");
13629             }
13630
13631             // Only buffer up to ~64k.  Various logging bits truncate
13632             // things at 128k.
13633             needsFlush = (sb.length() > 64 * 1024);
13634         }
13635
13636         // Flush immediately if the buffer's grown too large, or this
13637         // is a non-system app.  Non-system apps are isolated with a
13638         // different tag & policy and not batched.
13639         //
13640         // Batching is useful during internal testing with
13641         // StrictMode settings turned up high.  Without batching,
13642         // thousands of separate files could be created on boot.
13643         if (!isSystemApp || needsFlush) {
13644             new Thread("Error dump: " + dropboxTag) {
13645                 @Override
13646                 public void run() {
13647                     String report;
13648                     synchronized (sb) {
13649                         report = sb.toString();
13650                         sb.delete(0, sb.length());
13651                         sb.trimToSize();
13652                     }
13653                     if (report.length() != 0) {
13654                         dbox.addText(dropboxTag, report);
13655                     }
13656                 }
13657             }.start();
13658             return;
13659         }
13660
13661         // System app batching:
13662         if (!bufferWasEmpty) {
13663             // An existing dropbox-writing thread is outstanding, so
13664             // we don't need to start it up.  The existing thread will
13665             // catch the buffer appends we just did.
13666             return;
13667         }
13668
13669         // Worker thread to both batch writes and to avoid blocking the caller on I/O.
13670         // (After this point, we shouldn't access AMS internal data structures.)
13671         new Thread("Error dump: " + dropboxTag) {
13672             @Override
13673             public void run() {
13674                 // 5 second sleep to let stacks arrive and be batched together
13675                 try {
13676                     Thread.sleep(5000);  // 5 seconds
13677                 } catch (InterruptedException e) {}
13678
13679                 String errorReport;
13680                 synchronized (mStrictModeBuffer) {
13681                     errorReport = mStrictModeBuffer.toString();
13682                     if (errorReport.length() == 0) {
13683                         return;
13684                     }
13685                     mStrictModeBuffer.delete(0, mStrictModeBuffer.length());
13686                     mStrictModeBuffer.trimToSize();
13687                 }
13688                 dbox.addText(dropboxTag, errorReport);
13689             }
13690         }.start();
13691     }
13692
13693     /**
13694      * Used by {@link Log} via {@link com.android.internal.os.RuntimeInit} to report serious errors.
13695      * @param app object of the crashing app, null for the system server
13696      * @param tag reported by the caller
13697      * @param system whether this wtf is coming from the system
13698      * @param crashInfo describing the context of the error
13699      * @return true if the process should exit immediately (WTF is fatal)
13700      */
13701     public boolean handleApplicationWtf(final IBinder app, final String tag, boolean system,
13702             final ApplicationErrorReport.CrashInfo crashInfo) {
13703         final int callingUid = Binder.getCallingUid();
13704         final int callingPid = Binder.getCallingPid();
13705
13706         if (system) {
13707             // If this is coming from the system, we could very well have low-level
13708             // system locks held, so we want to do this all asynchronously.  And we
13709             // never want this to become fatal, so there is that too.
13710             mHandler.post(new Runnable() {
13711                 @Override public void run() {
13712                     handleApplicationWtfInner(callingUid, callingPid, app, tag, crashInfo);
13713                 }
13714             });
13715             return false;
13716         }
13717
13718         final ProcessRecord r = handleApplicationWtfInner(callingUid, callingPid, app, tag,
13719                 crashInfo);
13720
13721         if (r != null && r.pid != Process.myPid() &&
13722                 Settings.Global.getInt(mContext.getContentResolver(),
13723                         Settings.Global.WTF_IS_FATAL, 0) != 0) {
13724             mAppErrors.crashApplication(r, crashInfo);
13725             return true;
13726         } else {
13727             return false;
13728         }
13729     }
13730
13731     ProcessRecord handleApplicationWtfInner(int callingUid, int callingPid, IBinder app, String tag,
13732             final ApplicationErrorReport.CrashInfo crashInfo) {
13733         final ProcessRecord r = findAppProcess(app, "WTF");
13734         final String processName = app == null ? "system_server"
13735                 : (r == null ? "unknown" : r.processName);
13736
13737         EventLog.writeEvent(EventLogTags.AM_WTF, UserHandle.getUserId(callingUid), callingPid,
13738                 processName, r == null ? -1 : r.info.flags, tag, crashInfo.exceptionMessage);
13739
13740         addErrorToDropBox("wtf", r, processName, null, null, tag, null, null, crashInfo);
13741
13742         return r;
13743     }
13744
13745     /**
13746      * @param app object of some object (as stored in {@link com.android.internal.os.RuntimeInit})
13747      * @return the corresponding {@link ProcessRecord} object, or null if none could be found
13748      */
13749     private ProcessRecord findAppProcess(IBinder app, String reason) {
13750         if (app == null) {
13751             return null;
13752         }
13753
13754         synchronized (this) {
13755             final int NP = mProcessNames.getMap().size();
13756             for (int ip=0; ip<NP; ip++) {
13757                 SparseArray<ProcessRecord> apps = mProcessNames.getMap().valueAt(ip);
13758                 final int NA = apps.size();
13759                 for (int ia=0; ia<NA; ia++) {
13760                     ProcessRecord p = apps.valueAt(ia);
13761                     if (p.thread != null && p.thread.asBinder() == app) {
13762                         return p;
13763                     }
13764                 }
13765             }
13766
13767             Slog.w(TAG, "Can't find mystery application for " + reason
13768                     + " from pid=" + Binder.getCallingPid()
13769                     + " uid=" + Binder.getCallingUid() + ": " + app);
13770             return null;
13771         }
13772     }
13773
13774     /**
13775      * Utility function for addErrorToDropBox and handleStrictModeViolation's logging
13776      * to append various headers to the dropbox log text.
13777      */
13778     private void appendDropBoxProcessHeaders(ProcessRecord process, String processName,
13779             StringBuilder sb) {
13780         // Watchdog thread ends up invoking this function (with
13781         // a null ProcessRecord) to add the stack file to dropbox.
13782         // Do not acquire a lock on this (am) in such cases, as it
13783         // could cause a potential deadlock, if and when watchdog
13784         // is invoked due to unavailability of lock on am and it
13785         // would prevent watchdog from killing system_server.
13786         if (process == null) {
13787             sb.append("Process: ").append(processName).append("\n");
13788             return;
13789         }
13790         // Note: ProcessRecord 'process' is guarded by the service
13791         // instance.  (notably process.pkgList, which could otherwise change
13792         // concurrently during execution of this method)
13793         synchronized (this) {
13794             sb.append("Process: ").append(processName).append("\n");
13795             int flags = process.info.flags;
13796             IPackageManager pm = AppGlobals.getPackageManager();
13797             sb.append("Flags: 0x").append(Integer.toHexString(flags)).append("\n");
13798             for (int ip=0; ip<process.pkgList.size(); ip++) {
13799                 String pkg = process.pkgList.keyAt(ip);
13800                 sb.append("Package: ").append(pkg);
13801                 try {
13802                     PackageInfo pi = pm.getPackageInfo(pkg, 0, UserHandle.getCallingUserId());
13803                     if (pi != null) {
13804                         sb.append(" v").append(pi.versionCode);
13805                         if (pi.versionName != null) {
13806                             sb.append(" (").append(pi.versionName).append(")");
13807                         }
13808                     }
13809                 } catch (RemoteException e) {
13810                     Slog.e(TAG, "Error getting package info: " + pkg, e);
13811                 }
13812                 sb.append("\n");
13813             }
13814         }
13815     }
13816
13817     private static String processClass(ProcessRecord process) {
13818         if (process == null || process.pid == MY_PID) {
13819             return "system_server";
13820         } else if ((process.info.flags & ApplicationInfo.FLAG_SYSTEM) != 0) {
13821             return "system_app";
13822         } else {
13823             return "data_app";
13824         }
13825     }
13826
13827     private volatile long mWtfClusterStart;
13828     private volatile int mWtfClusterCount;
13829
13830     /**
13831      * Write a description of an error (crash, WTF, ANR) to the drop box.
13832      * @param eventType to include in the drop box tag ("crash", "wtf", etc.)
13833      * @param process which caused the error, null means the system server
13834      * @param activity which triggered the error, null if unknown
13835      * @param parent activity related to the error, null if unknown
13836      * @param subject line related to the error, null if absent
13837      * @param report in long form describing the error, null if absent
13838      * @param dataFile text file to include in the report, null if none
13839      * @param crashInfo giving an application stack trace, null if absent
13840      */
13841     public void addErrorToDropBox(String eventType,
13842             ProcessRecord process, String processName, ActivityRecord activity,
13843             ActivityRecord parent, String subject,
13844             final String report, final File dataFile,
13845             final ApplicationErrorReport.CrashInfo crashInfo) {
13846         // NOTE -- this must never acquire the ActivityManagerService lock,
13847         // otherwise the watchdog may be prevented from resetting the system.
13848
13849         final String dropboxTag = processClass(process) + "_" + eventType;
13850         final DropBoxManager dbox = (DropBoxManager)
13851                 mContext.getSystemService(Context.DROPBOX_SERVICE);
13852
13853         // Exit early if the dropbox isn't configured to accept this report type.
13854         if (dbox == null || !dbox.isTagEnabled(dropboxTag)) return;
13855
13856         // Rate-limit how often we're willing to do the heavy lifting below to
13857         // collect and record logs; currently 5 logs per 10 second period.
13858         final long now = SystemClock.elapsedRealtime();
13859         if (now - mWtfClusterStart > 10 * DateUtils.SECOND_IN_MILLIS) {
13860             mWtfClusterStart = now;
13861             mWtfClusterCount = 1;
13862         } else {
13863             if (mWtfClusterCount++ >= 5) return;
13864         }
13865
13866         final StringBuilder sb = new StringBuilder(1024);
13867         appendDropBoxProcessHeaders(process, processName, sb);
13868         if (process != null) {
13869             sb.append("Foreground: ")
13870                     .append(process.isInterestingToUserLocked() ? "Yes" : "No")
13871                     .append("\n");
13872         }
13873         if (activity != null) {
13874             sb.append("Activity: ").append(activity.shortComponentName).append("\n");
13875         }
13876         if (parent != null && parent.app != null && parent.app.pid != process.pid) {
13877             sb.append("Parent-Process: ").append(parent.app.processName).append("\n");
13878         }
13879         if (parent != null && parent != activity) {
13880             sb.append("Parent-Activity: ").append(parent.shortComponentName).append("\n");
13881         }
13882         if (subject != null) {
13883             sb.append("Subject: ").append(subject).append("\n");
13884         }
13885         sb.append("Build: ").append(Build.FINGERPRINT).append("\n");
13886         if (Debug.isDebuggerConnected()) {
13887             sb.append("Debugger: Connected\n");
13888         }
13889         sb.append("\n");
13890
13891         // Do the rest in a worker thread to avoid blocking the caller on I/O
13892         // (After this point, we shouldn't access AMS internal data structures.)
13893         Thread worker = new Thread("Error dump: " + dropboxTag) {
13894             @Override
13895             public void run() {
13896                 if (report != null) {
13897                     sb.append(report);
13898                 }
13899
13900                 String setting = Settings.Global.ERROR_LOGCAT_PREFIX + dropboxTag;
13901                 int lines = Settings.Global.getInt(mContext.getContentResolver(), setting, 0);
13902                 int maxDataFileSize = DROPBOX_MAX_SIZE - sb.length()
13903                         - lines * RESERVED_BYTES_PER_LOGCAT_LINE;
13904
13905                 if (dataFile != null && maxDataFileSize > 0) {
13906                     try {
13907                         sb.append(FileUtils.readTextFile(dataFile, maxDataFileSize,
13908                                     "\n\n[[TRUNCATED]]"));
13909                     } catch (IOException e) {
13910                         Slog.e(TAG, "Error reading " + dataFile, e);
13911                     }
13912                 }
13913                 if (crashInfo != null && crashInfo.stackTrace != null) {
13914                     sb.append(crashInfo.stackTrace);
13915                 }
13916
13917                 if (lines > 0) {
13918                     sb.append("\n");
13919
13920                     // Merge several logcat streams, and take the last N lines
13921                     InputStreamReader input = null;
13922                     try {
13923                         java.lang.Process logcat = new ProcessBuilder(
13924                                 "/system/bin/timeout", "-k", "15s", "10s",
13925                                 "/system/bin/logcat", "-v", "threadtime", "-b", "events", "-b", "system",
13926                                 "-b", "main", "-b", "crash", "-t", String.valueOf(lines))
13927                                         .redirectErrorStream(true).start();
13928
13929                         try { logcat.getOutputStream().close(); } catch (IOException e) {}
13930                         try { logcat.getErrorStream().close(); } catch (IOException e) {}
13931                         input = new InputStreamReader(logcat.getInputStream());
13932
13933                         int num;
13934                         char[] buf = new char[8192];
13935                         while ((num = input.read(buf)) > 0) sb.append(buf, 0, num);
13936                     } catch (IOException e) {
13937                         Slog.e(TAG, "Error running logcat", e);
13938                     } finally {
13939                         if (input != null) try { input.close(); } catch (IOException e) {}
13940                     }
13941                 }
13942
13943                 dbox.addText(dropboxTag, sb.toString());
13944             }
13945         };
13946
13947         if (process == null) {
13948             // If process is null, we are being called from some internal code
13949             // and may be about to die -- run this synchronously.
13950             worker.run();
13951         } else {
13952             worker.start();
13953         }
13954     }
13955
13956     @Override
13957     public List<ActivityManager.ProcessErrorStateInfo> getProcessesInErrorState() {
13958         enforceNotIsolatedCaller("getProcessesInErrorState");
13959         // assume our apps are happy - lazy create the list
13960         List<ActivityManager.ProcessErrorStateInfo> errList = null;
13961
13962         final boolean allUsers = ActivityManager.checkUidPermission(INTERACT_ACROSS_USERS_FULL,
13963                 Binder.getCallingUid()) == PackageManager.PERMISSION_GRANTED;
13964         int userId = UserHandle.getUserId(Binder.getCallingUid());
13965
13966         synchronized (this) {
13967
13968             // iterate across all processes
13969             for (int i=mLruProcesses.size()-1; i>=0; i--) {
13970                 ProcessRecord app = mLruProcesses.get(i);
13971                 if (!allUsers && app.userId != userId) {
13972                     continue;
13973                 }
13974                 if ((app.thread != null) && (app.crashing || app.notResponding)) {
13975                     // This one's in trouble, so we'll generate a report for it
13976                     // crashes are higher priority (in case there's a crash *and* an anr)
13977                     ActivityManager.ProcessErrorStateInfo report = null;
13978                     if (app.crashing) {
13979                         report = app.crashingReport;
13980                     } else if (app.notResponding) {
13981                         report = app.notRespondingReport;
13982                     }
13983
13984                     if (report != null) {
13985                         if (errList == null) {
13986                             errList = new ArrayList<ActivityManager.ProcessErrorStateInfo>(1);
13987                         }
13988                         errList.add(report);
13989                     } else {
13990                         Slog.w(TAG, "Missing app error report, app = " + app.processName +
13991                                 " crashing = " + app.crashing +
13992                                 " notResponding = " + app.notResponding);
13993                     }
13994                 }
13995             }
13996         }
13997
13998         return errList;
13999     }
14000
14001     static int procStateToImportance(int procState, int memAdj,
14002             ActivityManager.RunningAppProcessInfo currApp) {
14003         int imp = ActivityManager.RunningAppProcessInfo.procStateToImportance(procState);
14004         if (imp == ActivityManager.RunningAppProcessInfo.IMPORTANCE_BACKGROUND) {
14005             currApp.lru = memAdj;
14006         } else {
14007             currApp.lru = 0;
14008         }
14009         return imp;
14010     }
14011
14012     private void fillInProcMemInfo(ProcessRecord app,
14013             ActivityManager.RunningAppProcessInfo outInfo) {
14014         outInfo.pid = app.pid;
14015         outInfo.uid = app.info.uid;
14016         if (mHeavyWeightProcess == app) {
14017             outInfo.flags |= ActivityManager.RunningAppProcessInfo.FLAG_CANT_SAVE_STATE;
14018         }
14019         if (app.persistent) {
14020             outInfo.flags |= ActivityManager.RunningAppProcessInfo.FLAG_PERSISTENT;
14021         }
14022         if (app.activities.size() > 0) {
14023             outInfo.flags |= ActivityManager.RunningAppProcessInfo.FLAG_HAS_ACTIVITIES;
14024         }
14025         outInfo.lastTrimLevel = app.trimMemoryLevel;
14026         int adj = app.curAdj;
14027         int procState = app.curProcState;
14028         outInfo.importance = procStateToImportance(procState, adj, outInfo);
14029         outInfo.importanceReasonCode = app.adjTypeCode;
14030         outInfo.processState = app.curProcState;
14031     }
14032
14033     @Override
14034     public List<ActivityManager.RunningAppProcessInfo> getRunningAppProcesses() {
14035         enforceNotIsolatedCaller("getRunningAppProcesses");
14036
14037         final int callingUid = Binder.getCallingUid();
14038
14039         // Lazy instantiation of list
14040         List<ActivityManager.RunningAppProcessInfo> runList = null;
14041         final boolean allUsers = ActivityManager.checkUidPermission(INTERACT_ACROSS_USERS_FULL,
14042                 callingUid) == PackageManager.PERMISSION_GRANTED;
14043         final int userId = UserHandle.getUserId(callingUid);
14044         final boolean allUids = isGetTasksAllowed(
14045                 "getRunningAppProcesses", Binder.getCallingPid(), callingUid);
14046
14047         synchronized (this) {
14048             // Iterate across all processes
14049             for (int i = mLruProcesses.size() - 1; i >= 0; i--) {
14050                 ProcessRecord app = mLruProcesses.get(i);
14051                 if ((!allUsers && app.userId != userId)
14052                         || (!allUids && app.uid != callingUid)) {
14053                     continue;
14054                 }
14055                 if ((app.thread != null) && (!app.crashing && !app.notResponding)) {
14056                     // Generate process state info for running application
14057                     ActivityManager.RunningAppProcessInfo currApp =
14058                         new ActivityManager.RunningAppProcessInfo(app.processName,
14059                                 app.pid, app.getPackageList());
14060                     fillInProcMemInfo(app, currApp);
14061                     if (app.adjSource instanceof ProcessRecord) {
14062                         currApp.importanceReasonPid = ((ProcessRecord)app.adjSource).pid;
14063                         currApp.importanceReasonImportance =
14064                                 ActivityManager.RunningAppProcessInfo.procStateToImportance(
14065                                         app.adjSourceProcState);
14066                     } else if (app.adjSource instanceof ActivityRecord) {
14067                         ActivityRecord r = (ActivityRecord)app.adjSource;
14068                         if (r.app != null) currApp.importanceReasonPid = r.app.pid;
14069                     }
14070                     if (app.adjTarget instanceof ComponentName) {
14071                         currApp.importanceReasonComponent = (ComponentName)app.adjTarget;
14072                     }
14073                     //Slog.v(TAG, "Proc " + app.processName + ": imp=" + currApp.importance
14074                     //        + " lru=" + currApp.lru);
14075                     if (runList == null) {
14076                         runList = new ArrayList<>();
14077                     }
14078                     runList.add(currApp);
14079                 }
14080             }
14081         }
14082         return runList;
14083     }
14084
14085     @Override
14086     public List<ApplicationInfo> getRunningExternalApplications() {
14087         enforceNotIsolatedCaller("getRunningExternalApplications");
14088         List<ActivityManager.RunningAppProcessInfo> runningApps = getRunningAppProcesses();
14089         List<ApplicationInfo> retList = new ArrayList<ApplicationInfo>();
14090         if (runningApps != null && runningApps.size() > 0) {
14091             Set<String> extList = new HashSet<String>();
14092             for (ActivityManager.RunningAppProcessInfo app : runningApps) {
14093                 if (app.pkgList != null) {
14094                     for (String pkg : app.pkgList) {
14095                         extList.add(pkg);
14096                     }
14097                 }
14098             }
14099             IPackageManager pm = AppGlobals.getPackageManager();
14100             for (String pkg : extList) {
14101                 try {
14102                     ApplicationInfo info = pm.getApplicationInfo(pkg, 0, UserHandle.getCallingUserId());
14103                     if ((info.flags & ApplicationInfo.FLAG_EXTERNAL_STORAGE) != 0) {
14104                         retList.add(info);
14105                     }
14106                 } catch (RemoteException e) {
14107                 }
14108             }
14109         }
14110         return retList;
14111     }
14112
14113     @Override
14114     public void getMyMemoryState(ActivityManager.RunningAppProcessInfo outInfo) {
14115         enforceNotIsolatedCaller("getMyMemoryState");
14116         synchronized (this) {
14117             ProcessRecord proc;
14118             synchronized (mPidsSelfLocked) {
14119                 proc = mPidsSelfLocked.get(Binder.getCallingPid());
14120             }
14121             fillInProcMemInfo(proc, outInfo);
14122         }
14123     }
14124
14125     @Override
14126     public int getMemoryTrimLevel() {
14127         enforceNotIsolatedCaller("getMyMemoryState");
14128         synchronized (this) {
14129             return mLastMemoryLevel;
14130         }
14131     }
14132
14133     @Override
14134     public void onShellCommand(FileDescriptor in, FileDescriptor out,
14135             FileDescriptor err, String[] args, ResultReceiver resultReceiver) {
14136         (new ActivityManagerShellCommand(this, false)).exec(
14137                 this, in, out, err, args, resultReceiver);
14138     }
14139
14140     @Override
14141     protected void dump(FileDescriptor fd, PrintWriter pw, String[] args) {
14142         if (checkCallingPermission(android.Manifest.permission.DUMP)
14143                 != PackageManager.PERMISSION_GRANTED) {
14144             pw.println("Permission Denial: can't dump ActivityManager from from pid="
14145                     + Binder.getCallingPid()
14146                     + ", uid=" + Binder.getCallingUid()
14147                     + " without permission "
14148                     + android.Manifest.permission.DUMP);
14149             return;
14150         }
14151
14152         boolean dumpAll = false;
14153         boolean dumpClient = false;
14154         boolean dumpCheckin = false;
14155         boolean dumpCheckinFormat = false;
14156         String dumpPackage = null;
14157
14158         int opti = 0;
14159         while (opti < args.length) {
14160             String opt = args[opti];
14161             if (opt == null || opt.length() <= 0 || opt.charAt(0) != '-') {
14162                 break;
14163             }
14164             opti++;
14165             if ("-a".equals(opt)) {
14166                 dumpAll = true;
14167             } else if ("-c".equals(opt)) {
14168                 dumpClient = true;
14169             } else if ("-p".equals(opt)) {
14170                 if (opti < args.length) {
14171                     dumpPackage = args[opti];
14172                     opti++;
14173                 } else {
14174                     pw.println("Error: -p option requires package argument");
14175                     return;
14176                 }
14177                 dumpClient = true;
14178             } else if ("--checkin".equals(opt)) {
14179                 dumpCheckin = dumpCheckinFormat = true;
14180             } else if ("-C".equals(opt)) {
14181                 dumpCheckinFormat = true;
14182             } else if ("-h".equals(opt)) {
14183                 ActivityManagerShellCommand.dumpHelp(pw, true);
14184                 return;
14185             } else {
14186                 pw.println("Unknown argument: " + opt + "; use -h for help");
14187             }
14188         }
14189
14190         long origId = Binder.clearCallingIdentity();
14191         boolean more = false;
14192         // Is the caller requesting to dump a particular piece of data?
14193         if (opti < args.length) {
14194             String cmd = args[opti];
14195             opti++;
14196             if ("activities".equals(cmd) || "a".equals(cmd)) {
14197                 synchronized (this) {
14198                     dumpActivitiesLocked(fd, pw, args, opti, true, dumpClient, dumpPackage);
14199                 }
14200             } else if ("recents".equals(cmd) || "r".equals(cmd)) {
14201                 synchronized (this) {
14202                     dumpRecentsLocked(fd, pw, args, opti, true, dumpPackage);
14203                 }
14204             } else if ("broadcasts".equals(cmd) || "b".equals(cmd)) {
14205                 String[] newArgs;
14206                 String name;
14207                 if (opti >= args.length) {
14208                     name = null;
14209                     newArgs = EMPTY_STRING_ARRAY;
14210                 } else {
14211                     dumpPackage = args[opti];
14212                     opti++;
14213                     newArgs = new String[args.length - opti];
14214                     if (args.length > 2) System.arraycopy(args, opti, newArgs, 0,
14215                             args.length - opti);
14216                 }
14217                 synchronized (this) {
14218                     dumpBroadcastsLocked(fd, pw, args, opti, true, dumpPackage);
14219                 }
14220             } else if ("broadcast-stats".equals(cmd)) {
14221                 String[] newArgs;
14222                 String name;
14223                 if (opti >= args.length) {
14224                     name = null;
14225                     newArgs = EMPTY_STRING_ARRAY;
14226                 } else {
14227                     dumpPackage = args[opti];
14228                     opti++;
14229                     newArgs = new String[args.length - opti];
14230                     if (args.length > 2) System.arraycopy(args, opti, newArgs, 0,
14231                             args.length - opti);
14232                 }
14233                 synchronized (this) {
14234                     if (dumpCheckinFormat) {
14235                         dumpBroadcastStatsCheckinLocked(fd, pw, args, opti, dumpCheckin,
14236                                 dumpPackage);
14237                     } else {
14238                         dumpBroadcastStatsLocked(fd, pw, args, opti, true, dumpPackage);
14239                     }
14240                 }
14241             } else if ("intents".equals(cmd) || "i".equals(cmd)) {
14242                 String[] newArgs;
14243                 String name;
14244                 if (opti >= args.length) {
14245                     name = null;
14246                     newArgs = EMPTY_STRING_ARRAY;
14247                 } else {
14248                     dumpPackage = args[opti];
14249                     opti++;
14250                     newArgs = new String[args.length - opti];
14251                     if (args.length > 2) System.arraycopy(args, opti, newArgs, 0,
14252                             args.length - opti);
14253                 }
14254                 synchronized (this) {
14255                     dumpPendingIntentsLocked(fd, pw, args, opti, true, dumpPackage);
14256                 }
14257             } else if ("processes".equals(cmd) || "p".equals(cmd)) {
14258                 String[] newArgs;
14259                 String name;
14260                 if (opti >= args.length) {
14261                     name = null;
14262                     newArgs = EMPTY_STRING_ARRAY;
14263                 } else {
14264                     dumpPackage = args[opti];
14265                     opti++;
14266                     newArgs = new String[args.length - opti];
14267                     if (args.length > 2) System.arraycopy(args, opti, newArgs, 0,
14268                             args.length - opti);
14269                 }
14270                 synchronized (this) {
14271                     dumpProcessesLocked(fd, pw, args, opti, true, dumpPackage);
14272                 }
14273             } else if ("oom".equals(cmd) || "o".equals(cmd)) {
14274                 synchronized (this) {
14275                     dumpOomLocked(fd, pw, args, opti, true);
14276                 }
14277             } else if ("permissions".equals(cmd) || "perm".equals(cmd)) {
14278                 synchronized (this) {
14279                     dumpPermissionsLocked(fd, pw, args, opti, true, null);
14280                 }
14281             } else if ("provider".equals(cmd)) {
14282                 String[] newArgs;
14283                 String name;
14284                 if (opti >= args.length) {
14285                     name = null;
14286                     newArgs = EMPTY_STRING_ARRAY;
14287                 } else {
14288                     name = args[opti];
14289                     opti++;
14290                     newArgs = new String[args.length - opti];
14291                     if (args.length > 2) System.arraycopy(args, opti, newArgs, 0, args.length - opti);
14292                 }
14293                 if (!dumpProvider(fd, pw, name, newArgs, 0, dumpAll)) {
14294                     pw.println("No providers match: " + name);
14295                     pw.println("Use -h for help.");
14296                 }
14297             } else if ("providers".equals(cmd) || "prov".equals(cmd)) {
14298                 synchronized (this) {
14299                     dumpProvidersLocked(fd, pw, args, opti, true, null);
14300                 }
14301             } else if ("service".equals(cmd)) {
14302                 String[] newArgs;
14303                 String name;
14304                 if (opti >= args.length) {
14305                     name = null;
14306                     newArgs = EMPTY_STRING_ARRAY;
14307                 } else {
14308                     name = args[opti];
14309                     opti++;
14310                     newArgs = new String[args.length - opti];
14311                     if (args.length > 2) System.arraycopy(args, opti, newArgs, 0,
14312                             args.length - opti);
14313                 }
14314                 if (!mServices.dumpService(fd, pw, name, newArgs, 0, dumpAll)) {
14315                     pw.println("No services match: " + name);
14316                     pw.println("Use -h for help.");
14317                 }
14318             } else if ("package".equals(cmd)) {
14319                 String[] newArgs;
14320                 if (opti >= args.length) {
14321                     pw.println("package: no package name specified");
14322                     pw.println("Use -h for help.");
14323                 } else {
14324                     dumpPackage = args[opti];
14325                     opti++;
14326                     newArgs = new String[args.length - opti];
14327                     if (args.length > 2) System.arraycopy(args, opti, newArgs, 0,
14328                             args.length - opti);
14329                     args = newArgs;
14330                     opti = 0;
14331                     more = true;
14332                 }
14333             } else if ("associations".equals(cmd) || "as".equals(cmd)) {
14334                 synchronized (this) {
14335                     dumpAssociationsLocked(fd, pw, args, opti, true, dumpClient, dumpPackage);
14336                 }
14337             } else if ("services".equals(cmd) || "s".equals(cmd)) {
14338                 if (dumpClient) {
14339                     ActiveServices.ServiceDumper dumper;
14340                     synchronized (this) {
14341                         dumper = mServices.newServiceDumperLocked(fd, pw, args, opti, true,
14342                                 dumpPackage);
14343                     }
14344                     dumper.dumpWithClient();
14345                 } else {
14346                     synchronized (this) {
14347                         mServices.newServiceDumperLocked(fd, pw, args, opti, true,
14348                                 dumpPackage).dumpLocked();
14349                     }
14350                 }
14351             } else if ("locks".equals(cmd)) {
14352                 LockGuard.dump(fd, pw, args);
14353             } else {
14354                 // Dumping a single activity?
14355                 if (!dumpActivity(fd, pw, cmd, args, opti, dumpAll)) {
14356                     ActivityManagerShellCommand shell = new ActivityManagerShellCommand(this, true);
14357                     int res = shell.exec(this, null, fd, null, args, new ResultReceiver(null));
14358                     if (res < 0) {
14359                         pw.println("Bad activity command, or no activities match: " + cmd);
14360                         pw.println("Use -h for help.");
14361                     }
14362                 }
14363             }
14364             if (!more) {
14365                 Binder.restoreCallingIdentity(origId);
14366                 return;
14367             }
14368         }
14369
14370         // No piece of data specified, dump everything.
14371         if (dumpCheckinFormat) {
14372             dumpBroadcastStatsCheckinLocked(fd, pw, args, opti, dumpCheckin, dumpPackage);
14373         } else if (dumpClient) {
14374             ActiveServices.ServiceDumper sdumper;
14375             synchronized (this) {
14376                 dumpPendingIntentsLocked(fd, pw, args, opti, dumpAll, dumpPackage);
14377                 pw.println();
14378                 if (dumpAll) {
14379                     pw.println("-------------------------------------------------------------------------------");
14380                 }
14381                 dumpBroadcastsLocked(fd, pw, args, opti, dumpAll, dumpPackage);
14382                 pw.println();
14383                 if (dumpAll) {
14384                     pw.println("-------------------------------------------------------------------------------");
14385                 }
14386                 if (dumpAll || dumpPackage != null) {
14387                     dumpBroadcastStatsLocked(fd, pw, args, opti, dumpAll, dumpPackage);
14388                     pw.println();
14389                     if (dumpAll) {
14390                         pw.println("-------------------------------------------------------------------------------");
14391                     }
14392                 }
14393                 dumpProvidersLocked(fd, pw, args, opti, dumpAll, dumpPackage);
14394                 pw.println();
14395                 if (dumpAll) {
14396                     pw.println("-------------------------------------------------------------------------------");
14397                 }
14398                 dumpPermissionsLocked(fd, pw, args, opti, dumpAll, dumpPackage);
14399                 pw.println();
14400                 if (dumpAll) {
14401                     pw.println("-------------------------------------------------------------------------------");
14402                 }
14403                 sdumper = mServices.newServiceDumperLocked(fd, pw, args, opti, dumpAll,
14404                         dumpPackage);
14405             }
14406             sdumper.dumpWithClient();
14407             pw.println();
14408             synchronized (this) {
14409                 if (dumpAll) {
14410                     pw.println("-------------------------------------------------------------------------------");
14411                 }
14412                 dumpRecentsLocked(fd, pw, args, opti, dumpAll, dumpPackage);
14413                 pw.println();
14414                 if (dumpAll) {
14415                     pw.println("-------------------------------------------------------------------------------");
14416                 }
14417                 dumpActivitiesLocked(fd, pw, args, opti, dumpAll, dumpClient, dumpPackage);
14418                 if (mAssociations.size() > 0) {
14419                     pw.println();
14420                     if (dumpAll) {
14421                         pw.println("-------------------------------------------------------------------------------");
14422                     }
14423                     dumpAssociationsLocked(fd, pw, args, opti, dumpAll, dumpClient, dumpPackage);
14424                 }
14425                 pw.println();
14426                 if (dumpAll) {
14427                     pw.println("-------------------------------------------------------------------------------");
14428                 }
14429                 dumpProcessesLocked(fd, pw, args, opti, dumpAll, dumpPackage);
14430             }
14431
14432         } else {
14433             synchronized (this) {
14434                 dumpPendingIntentsLocked(fd, pw, args, opti, dumpAll, dumpPackage);
14435                 pw.println();
14436                 if (dumpAll) {
14437                     pw.println("-------------------------------------------------------------------------------");
14438                 }
14439                 dumpBroadcastsLocked(fd, pw, args, opti, dumpAll, dumpPackage);
14440                 pw.println();
14441                 if (dumpAll) {
14442                     pw.println("-------------------------------------------------------------------------------");
14443                 }
14444                 if (dumpAll || dumpPackage != null) {
14445                     dumpBroadcastStatsLocked(fd, pw, args, opti, dumpAll, dumpPackage);
14446                     pw.println();
14447                     if (dumpAll) {
14448                         pw.println("-------------------------------------------------------------------------------");
14449                     }
14450                 }
14451                 dumpProvidersLocked(fd, pw, args, opti, dumpAll, dumpPackage);
14452                 pw.println();
14453                 if (dumpAll) {
14454                     pw.println("-------------------------------------------------------------------------------");
14455                 }
14456                 dumpPermissionsLocked(fd, pw, args, opti, dumpAll, dumpPackage);
14457                 pw.println();
14458                 if (dumpAll) {
14459                     pw.println("-------------------------------------------------------------------------------");
14460                 }
14461                 mServices.newServiceDumperLocked(fd, pw, args, opti, dumpAll, dumpPackage)
14462                         .dumpLocked();
14463                 pw.println();
14464                 if (dumpAll) {
14465                     pw.println("-------------------------------------------------------------------------------");
14466                 }
14467                 dumpRecentsLocked(fd, pw, args, opti, dumpAll, dumpPackage);
14468                 pw.println();
14469                 if (dumpAll) {
14470                     pw.println("-------------------------------------------------------------------------------");
14471                 }
14472                 dumpActivitiesLocked(fd, pw, args, opti, dumpAll, dumpClient, dumpPackage);
14473                 if (mAssociations.size() > 0) {
14474                     pw.println();
14475                     if (dumpAll) {
14476                         pw.println("-------------------------------------------------------------------------------");
14477                     }
14478                     dumpAssociationsLocked(fd, pw, args, opti, dumpAll, dumpClient, dumpPackage);
14479                 }
14480                 pw.println();
14481                 if (dumpAll) {
14482                     pw.println("-------------------------------------------------------------------------------");
14483                 }
14484                 dumpProcessesLocked(fd, pw, args, opti, dumpAll, dumpPackage);
14485             }
14486         }
14487         Binder.restoreCallingIdentity(origId);
14488     }
14489
14490     void dumpActivitiesLocked(FileDescriptor fd, PrintWriter pw, String[] args,
14491             int opti, boolean dumpAll, boolean dumpClient, String dumpPackage) {
14492         pw.println("ACTIVITY MANAGER ACTIVITIES (dumpsys activity activities)");
14493
14494         boolean printedAnything = mStackSupervisor.dumpActivitiesLocked(fd, pw, dumpAll, dumpClient,
14495                 dumpPackage);
14496         boolean needSep = printedAnything;
14497
14498         boolean printed = ActivityStackSupervisor.printThisActivity(pw, mFocusedActivity,
14499                 dumpPackage, needSep, "  mFocusedActivity: ");
14500         if (printed) {
14501             printedAnything = true;
14502             needSep = false;
14503         }
14504
14505         if (dumpPackage == null) {
14506             if (needSep) {
14507                 pw.println();
14508             }
14509             needSep = true;
14510             printedAnything = true;
14511             mStackSupervisor.dump(pw, "  ");
14512         }
14513
14514         if (!printedAnything) {
14515             pw.println("  (nothing)");
14516         }
14517     }
14518
14519     void dumpRecentsLocked(FileDescriptor fd, PrintWriter pw, String[] args,
14520             int opti, boolean dumpAll, String dumpPackage) {
14521         pw.println("ACTIVITY MANAGER RECENT TASKS (dumpsys activity recents)");
14522
14523         boolean printedAnything = false;
14524
14525         if (mRecentTasks != null && mRecentTasks.size() > 0) {
14526             boolean printedHeader = false;
14527
14528             final int N = mRecentTasks.size();
14529             for (int i=0; i<N; i++) {
14530                 TaskRecord tr = mRecentTasks.get(i);
14531                 if (dumpPackage != null) {
14532                     if (tr.realActivity == null ||
14533                             !dumpPackage.equals(tr.realActivity)) {
14534                         continue;
14535                     }
14536                 }
14537                 if (!printedHeader) {
14538                     pw.println("  Recent tasks:");
14539                     printedHeader = true;
14540                     printedAnything = true;
14541                 }
14542                 pw.print("  * Recent #"); pw.print(i); pw.print(": ");
14543                         pw.println(tr);
14544                 if (dumpAll) {
14545                     mRecentTasks.get(i).dump(pw, "    ");
14546                 }
14547             }
14548         }
14549
14550         if (!printedAnything) {
14551             pw.println("  (nothing)");
14552         }
14553     }
14554
14555     void dumpAssociationsLocked(FileDescriptor fd, PrintWriter pw, String[] args,
14556             int opti, boolean dumpAll, boolean dumpClient, String dumpPackage) {
14557         pw.println("ACTIVITY MANAGER ASSOCIATIONS (dumpsys activity associations)");
14558
14559         int dumpUid = 0;
14560         if (dumpPackage != null) {
14561             IPackageManager pm = AppGlobals.getPackageManager();
14562             try {
14563                 dumpUid = pm.getPackageUid(dumpPackage, MATCH_UNINSTALLED_PACKAGES, 0);
14564             } catch (RemoteException e) {
14565             }
14566         }
14567
14568         boolean printedAnything = false;
14569
14570         final long now = SystemClock.uptimeMillis();
14571
14572         for (int i1=0, N1=mAssociations.size(); i1<N1; i1++) {
14573             ArrayMap<ComponentName, SparseArray<ArrayMap<String, Association>>> targetComponents
14574                     = mAssociations.valueAt(i1);
14575             for (int i2=0, N2=targetComponents.size(); i2<N2; i2++) {
14576                 SparseArray<ArrayMap<String, Association>> sourceUids
14577                         = targetComponents.valueAt(i2);
14578                 for (int i3=0, N3=sourceUids.size(); i3<N3; i3++) {
14579                     ArrayMap<String, Association> sourceProcesses = sourceUids.valueAt(i3);
14580                     for (int i4=0, N4=sourceProcesses.size(); i4<N4; i4++) {
14581                         Association ass = sourceProcesses.valueAt(i4);
14582                         if (dumpPackage != null) {
14583                             if (!ass.mTargetComponent.getPackageName().equals(dumpPackage)
14584                                     && UserHandle.getAppId(ass.mSourceUid) != dumpUid) {
14585                                 continue;
14586                             }
14587                         }
14588                         printedAnything = true;
14589                         pw.print("  ");
14590                         pw.print(ass.mTargetProcess);
14591                         pw.print("/");
14592                         UserHandle.formatUid(pw, ass.mTargetUid);
14593                         pw.print(" <- ");
14594                         pw.print(ass.mSourceProcess);
14595                         pw.print("/");
14596                         UserHandle.formatUid(pw, ass.mSourceUid);
14597                         pw.println();
14598                         pw.print("    via ");
14599                         pw.print(ass.mTargetComponent.flattenToShortString());
14600                         pw.println();
14601                         pw.print("    ");
14602                         long dur = ass.mTime;
14603                         if (ass.mNesting > 0) {
14604                             dur += now - ass.mStartTime;
14605                         }
14606                         TimeUtils.formatDuration(dur, pw);
14607                         pw.print(" (");
14608                         pw.print(ass.mCount);
14609                         pw.print(" times)");
14610                         pw.print("  ");
14611                         for (int i=0; i<ass.mStateTimes.length; i++) {
14612                             long amt = ass.mStateTimes[i];
14613                             if (ass.mLastState-ActivityManager.MIN_PROCESS_STATE == i) {
14614                                 amt += now - ass.mLastStateUptime;
14615                             }
14616                             if (amt != 0) {
14617                                 pw.print(" ");
14618                                 pw.print(ProcessList.makeProcStateString(
14619                                             i + ActivityManager.MIN_PROCESS_STATE));
14620                                 pw.print("=");
14621                                 TimeUtils.formatDuration(amt, pw);
14622                                 if (ass.mLastState-ActivityManager.MIN_PROCESS_STATE == i) {
14623                                     pw.print("*");
14624                                 }
14625                             }
14626                         }
14627                         pw.println();
14628                         if (ass.mNesting > 0) {
14629                             pw.print("    Currently active: ");
14630                             TimeUtils.formatDuration(now - ass.mStartTime, pw);
14631                             pw.println();
14632                         }
14633                     }
14634                 }
14635             }
14636
14637         }
14638
14639         if (!printedAnything) {
14640             pw.println("  (nothing)");
14641         }
14642     }
14643
14644     boolean dumpUids(PrintWriter pw, String dumpPackage, SparseArray<UidRecord> uids,
14645             String header, boolean needSep) {
14646         boolean printed = false;
14647         int whichAppId = -1;
14648         if (dumpPackage != null) {
14649             try {
14650                 ApplicationInfo info = mContext.getPackageManager().getApplicationInfo(
14651                         dumpPackage, 0);
14652                 whichAppId = UserHandle.getAppId(info.uid);
14653             } catch (NameNotFoundException e) {
14654                 e.printStackTrace();
14655             }
14656         }
14657         for (int i=0; i<uids.size(); i++) {
14658             UidRecord uidRec = uids.valueAt(i);
14659             if (dumpPackage != null && UserHandle.getAppId(uidRec.uid) != whichAppId) {
14660                 continue;
14661             }
14662             if (!printed) {
14663                 printed = true;
14664                 if (needSep) {
14665                     pw.println();
14666                 }
14667                 pw.print("  ");
14668                 pw.println(header);
14669                 needSep = true;
14670             }
14671             pw.print("    UID "); UserHandle.formatUid(pw, uidRec.uid);
14672             pw.print(": "); pw.println(uidRec);
14673         }
14674         return printed;
14675     }
14676
14677     void dumpProcessesLocked(FileDescriptor fd, PrintWriter pw, String[] args,
14678             int opti, boolean dumpAll, String dumpPackage) {
14679         boolean needSep = false;
14680         boolean printedAnything = false;
14681         int numPers = 0;
14682
14683         pw.println("ACTIVITY MANAGER RUNNING PROCESSES (dumpsys activity processes)");
14684
14685         if (dumpAll) {
14686             final int NP = mProcessNames.getMap().size();
14687             for (int ip=0; ip<NP; ip++) {
14688                 SparseArray<ProcessRecord> procs = mProcessNames.getMap().valueAt(ip);
14689                 final int NA = procs.size();
14690                 for (int ia=0; ia<NA; ia++) {
14691                     ProcessRecord r = procs.valueAt(ia);
14692                     if (dumpPackage != null && !r.pkgList.containsKey(dumpPackage)) {
14693                         continue;
14694                     }
14695                     if (!needSep) {
14696                         pw.println("  All known processes:");
14697                         needSep = true;
14698                         printedAnything = true;
14699                     }
14700                     pw.print(r.persistent ? "  *PERS*" : "  *APP*");
14701                         pw.print(" UID "); pw.print(procs.keyAt(ia));
14702                         pw.print(" "); pw.println(r);
14703                     r.dump(pw, "    ");
14704                     if (r.persistent) {
14705                         numPers++;
14706                     }
14707                 }
14708             }
14709         }
14710
14711         if (mIsolatedProcesses.size() > 0) {
14712             boolean printed = false;
14713             for (int i=0; i<mIsolatedProcesses.size(); i++) {
14714                 ProcessRecord r = mIsolatedProcesses.valueAt(i);
14715                 if (dumpPackage != null && !r.pkgList.containsKey(dumpPackage)) {
14716                     continue;
14717                 }
14718                 if (!printed) {
14719                     if (needSep) {
14720                         pw.println();
14721                     }
14722                     pw.println("  Isolated process list (sorted by uid):");
14723                     printedAnything = true;
14724                     printed = true;
14725                     needSep = true;
14726                 }
14727                 pw.println(String.format("%sIsolated #%2d: %s",
14728                         "    ", i, r.toString()));
14729             }
14730         }
14731
14732         if (mActiveUids.size() > 0) {
14733             if (dumpUids(pw, dumpPackage, mActiveUids, "UID states:", needSep)) {
14734                 printedAnything = needSep = true;
14735             }
14736         }
14737         if (mValidateUids.size() > 0) {
14738             if (dumpUids(pw, dumpPackage, mValidateUids, "UID validation:", needSep)) {
14739                 printedAnything = needSep = true;
14740             }
14741         }
14742
14743         if (mLruProcesses.size() > 0) {
14744             if (needSep) {
14745                 pw.println();
14746             }
14747             pw.print("  Process LRU list (sorted by oom_adj, "); pw.print(mLruProcesses.size());
14748                     pw.print(" total, non-act at ");
14749                     pw.print(mLruProcesses.size()-mLruProcessActivityStart);
14750                     pw.print(", non-svc at ");
14751                     pw.print(mLruProcesses.size()-mLruProcessServiceStart);
14752                     pw.println("):");
14753             dumpProcessOomList(pw, this, mLruProcesses, "    ", "Proc", "PERS", false, dumpPackage);
14754             needSep = true;
14755             printedAnything = true;
14756         }
14757
14758         if (dumpAll || dumpPackage != null) {
14759             synchronized (mPidsSelfLocked) {
14760                 boolean printed = false;
14761                 for (int i=0; i<mPidsSelfLocked.size(); i++) {
14762                     ProcessRecord r = mPidsSelfLocked.valueAt(i);
14763                     if (dumpPackage != null && !r.pkgList.containsKey(dumpPackage)) {
14764                         continue;
14765                     }
14766                     if (!printed) {
14767                         if (needSep) pw.println();
14768                         needSep = true;
14769                         pw.println("  PID mappings:");
14770                         printed = true;
14771                         printedAnything = true;
14772                     }
14773                     pw.print("    PID #"); pw.print(mPidsSelfLocked.keyAt(i));
14774                         pw.print(": "); pw.println(mPidsSelfLocked.valueAt(i));
14775                 }
14776             }
14777         }
14778
14779         if (mForegroundProcesses.size() > 0) {
14780             synchronized (mPidsSelfLocked) {
14781                 boolean printed = false;
14782                 for (int i=0; i<mForegroundProcesses.size(); i++) {
14783                     ProcessRecord r = mPidsSelfLocked.get(
14784                             mForegroundProcesses.valueAt(i).pid);
14785                     if (dumpPackage != null && (r == null
14786                             || !r.pkgList.containsKey(dumpPackage))) {
14787                         continue;
14788                     }
14789                     if (!printed) {
14790                         if (needSep) pw.println();
14791                         needSep = true;
14792                         pw.println("  Foreground Processes:");
14793                         printed = true;
14794                         printedAnything = true;
14795                     }
14796                     pw.print("    PID #"); pw.print(mForegroundProcesses.keyAt(i));
14797                             pw.print(": "); pw.println(mForegroundProcesses.valueAt(i));
14798                 }
14799             }
14800         }
14801
14802         if (mPersistentStartingProcesses.size() > 0) {
14803             if (needSep) pw.println();
14804             needSep = true;
14805             printedAnything = true;
14806             pw.println("  Persisent processes that are starting:");
14807             dumpProcessList(pw, this, mPersistentStartingProcesses, "    ",
14808                     "Starting Norm", "Restarting PERS", dumpPackage);
14809         }
14810
14811         if (mRemovedProcesses.size() > 0) {
14812             if (needSep) pw.println();
14813             needSep = true;
14814             printedAnything = true;
14815             pw.println("  Processes that are being removed:");
14816             dumpProcessList(pw, this, mRemovedProcesses, "    ",
14817                     "Removed Norm", "Removed PERS", dumpPackage);
14818         }
14819
14820         if (mProcessesOnHold.size() > 0) {
14821             if (needSep) pw.println();
14822             needSep = true;
14823             printedAnything = true;
14824             pw.println("  Processes that are on old until the system is ready:");
14825             dumpProcessList(pw, this, mProcessesOnHold, "    ",
14826                     "OnHold Norm", "OnHold PERS", dumpPackage);
14827         }
14828
14829         needSep = dumpProcessesToGc(fd, pw, args, opti, needSep, dumpAll, dumpPackage);
14830
14831         needSep = mAppErrors.dumpLocked(fd, pw, needSep, dumpPackage);
14832         if (needSep) {
14833             printedAnything = true;
14834         }
14835
14836         if (dumpPackage == null) {
14837             pw.println();
14838             needSep = false;
14839             mUserController.dump(pw, dumpAll);
14840         }
14841         if (mHomeProcess != null && (dumpPackage == null
14842                 || mHomeProcess.pkgList.containsKey(dumpPackage))) {
14843             if (needSep) {
14844                 pw.println();
14845                 needSep = false;
14846             }
14847             pw.println("  mHomeProcess: " + mHomeProcess);
14848         }
14849         if (mPreviousProcess != null && (dumpPackage == null
14850                 || mPreviousProcess.pkgList.containsKey(dumpPackage))) {
14851             if (needSep) {
14852                 pw.println();
14853                 needSep = false;
14854             }
14855             pw.println("  mPreviousProcess: " + mPreviousProcess);
14856         }
14857         if (dumpAll) {
14858             StringBuilder sb = new StringBuilder(128);
14859             sb.append("  mPreviousProcessVisibleTime: ");
14860             TimeUtils.formatDuration(mPreviousProcessVisibleTime, sb);
14861             pw.println(sb);
14862         }
14863         if (mHeavyWeightProcess != null && (dumpPackage == null
14864                 || mHeavyWeightProcess.pkgList.containsKey(dumpPackage))) {
14865             if (needSep) {
14866                 pw.println();
14867                 needSep = false;
14868             }
14869             pw.println("  mHeavyWeightProcess: " + mHeavyWeightProcess);
14870         }
14871         if (dumpPackage == null) {
14872             pw.println("  mConfiguration: " + mConfiguration);
14873         }
14874         if (dumpAll) {
14875             pw.println("  mConfigWillChange: " + getFocusedStack().mConfigWillChange);
14876             if (mCompatModePackages.getPackages().size() > 0) {
14877                 boolean printed = false;
14878                 for (Map.Entry<String, Integer> entry
14879                         : mCompatModePackages.getPackages().entrySet()) {
14880                     String pkg = entry.getKey();
14881                     int mode = entry.getValue();
14882                     if (dumpPackage != null && !dumpPackage.equals(pkg)) {
14883                         continue;
14884                     }
14885                     if (!printed) {
14886                         pw.println("  mScreenCompatPackages:");
14887                         printed = true;
14888                     }
14889                     pw.print("    "); pw.print(pkg); pw.print(": ");
14890                             pw.print(mode); pw.println();
14891                 }
14892             }
14893         }
14894         if (dumpPackage == null) {
14895             pw.println("  mWakefulness="
14896                     + PowerManagerInternal.wakefulnessToString(mWakefulness));
14897             pw.println("  mSleepTokens=" + mSleepTokens);
14898             pw.println("  mSleeping=" + mSleeping + " mLockScreenShown="
14899                     + lockScreenShownToString());
14900             pw.println("  mShuttingDown=" + mShuttingDown + " mTestPssMode=" + mTestPssMode);
14901             if (mRunningVoice != null) {
14902                 pw.println("  mRunningVoice=" + mRunningVoice);
14903                 pw.println("  mVoiceWakeLock" + mVoiceWakeLock);
14904             }
14905         }
14906         if (mDebugApp != null || mOrigDebugApp != null || mDebugTransient
14907                 || mOrigWaitForDebugger) {
14908             if (dumpPackage == null || dumpPackage.equals(mDebugApp)
14909                     || dumpPackage.equals(mOrigDebugApp)) {
14910                 if (needSep) {
14911                     pw.println();
14912                     needSep = false;
14913                 }
14914                 pw.println("  mDebugApp=" + mDebugApp + "/orig=" + mOrigDebugApp
14915                         + " mDebugTransient=" + mDebugTransient
14916                         + " mOrigWaitForDebugger=" + mOrigWaitForDebugger);
14917             }
14918         }
14919         if (mCurAppTimeTracker != null) {
14920             mCurAppTimeTracker.dumpWithHeader(pw, "  ", true);
14921         }
14922         if (mMemWatchProcesses.getMap().size() > 0) {
14923             pw.println("  Mem watch processes:");
14924             final ArrayMap<String, SparseArray<Pair<Long, String>>> procs
14925                     = mMemWatchProcesses.getMap();
14926             for (int i=0; i<procs.size(); i++) {
14927                 final String proc = procs.keyAt(i);
14928                 final SparseArray<Pair<Long, String>> uids = procs.valueAt(i);
14929                 for (int j=0; j<uids.size(); j++) {
14930                     if (needSep) {
14931                         pw.println();
14932                         needSep = false;
14933                     }
14934                     StringBuilder sb = new StringBuilder();
14935                     sb.append("    ").append(proc).append('/');
14936                     UserHandle.formatUid(sb, uids.keyAt(j));
14937                     Pair<Long, String> val = uids.valueAt(j);
14938                     sb.append(": "); DebugUtils.sizeValueToString(val.first, sb);
14939                     if (val.second != null) {
14940                         sb.append(", report to ").append(val.second);
14941                     }
14942                     pw.println(sb.toString());
14943                 }
14944             }
14945             pw.print("  mMemWatchDumpProcName="); pw.println(mMemWatchDumpProcName);
14946             pw.print("  mMemWatchDumpFile="); pw.println(mMemWatchDumpFile);
14947             pw.print("  mMemWatchDumpPid="); pw.print(mMemWatchDumpPid);
14948                     pw.print(" mMemWatchDumpUid="); pw.println(mMemWatchDumpUid);
14949         }
14950         if (mTrackAllocationApp != null) {
14951             if (dumpPackage == null || dumpPackage.equals(mTrackAllocationApp)) {
14952                 if (needSep) {
14953                     pw.println();
14954                     needSep = false;
14955                 }
14956                 pw.println("  mTrackAllocationApp=" + mTrackAllocationApp);
14957             }
14958         }
14959         if (mProfileApp != null || mProfileProc != null || mProfileFile != null
14960                 || mProfileFd != null) {
14961             if (dumpPackage == null || dumpPackage.equals(mProfileApp)) {
14962                 if (needSep) {
14963                     pw.println();
14964                     needSep = false;
14965                 }
14966                 pw.println("  mProfileApp=" + mProfileApp + " mProfileProc=" + mProfileProc);
14967                 pw.println("  mProfileFile=" + mProfileFile + " mProfileFd=" + mProfileFd);
14968                 pw.println("  mSamplingInterval=" + mSamplingInterval + " mAutoStopProfiler="
14969                         + mAutoStopProfiler);
14970                 pw.println("  mProfileType=" + mProfileType);
14971             }
14972         }
14973         if (mNativeDebuggingApp != null) {
14974             if (dumpPackage == null || dumpPackage.equals(mNativeDebuggingApp)) {
14975                 if (needSep) {
14976                     pw.println();
14977                     needSep = false;
14978                 }
14979                 pw.println("  mNativeDebuggingApp=" + mNativeDebuggingApp);
14980             }
14981         }
14982         if (dumpPackage == null) {
14983             if (mAlwaysFinishActivities || mLenientBackgroundCheck) {
14984                 pw.println("  mAlwaysFinishActivities=" + mAlwaysFinishActivities
14985                         + " mLenientBackgroundCheck=" + mLenientBackgroundCheck);
14986             }
14987             if (mController != null) {
14988                 pw.println("  mController=" + mController
14989                         + " mControllerIsAMonkey=" + mControllerIsAMonkey);
14990             }
14991             if (dumpAll) {
14992                 pw.println("  Total persistent processes: " + numPers);
14993                 pw.println("  mProcessesReady=" + mProcessesReady
14994                         + " mSystemReady=" + mSystemReady
14995                         + " mBooted=" + mBooted
14996                         + " mFactoryTest=" + mFactoryTest);
14997                 pw.println("  mBooting=" + mBooting
14998                         + " mCallFinishBooting=" + mCallFinishBooting
14999                         + " mBootAnimationComplete=" + mBootAnimationComplete);
15000                 pw.print("  mLastPowerCheckRealtime=");
15001                         TimeUtils.formatDuration(mLastPowerCheckRealtime, pw);
15002                         pw.println("");
15003                 pw.print("  mLastPowerCheckUptime=");
15004                         TimeUtils.formatDuration(mLastPowerCheckUptime, pw);
15005                         pw.println("");
15006                 pw.println("  mGoingToSleep=" + mStackSupervisor.mGoingToSleep);
15007                 pw.println("  mLaunchingActivity=" + mStackSupervisor.mLaunchingActivity);
15008                 pw.println("  mAdjSeq=" + mAdjSeq + " mLruSeq=" + mLruSeq);
15009                 pw.println("  mNumNonCachedProcs=" + mNumNonCachedProcs
15010                         + " (" + mLruProcesses.size() + " total)"
15011                         + " mNumCachedHiddenProcs=" + mNumCachedHiddenProcs
15012                         + " mNumServiceProcs=" + mNumServiceProcs
15013                         + " mNewNumServiceProcs=" + mNewNumServiceProcs);
15014                 pw.println("  mAllowLowerMemLevel=" + mAllowLowerMemLevel
15015                         + " mLastMemoryLevel=" + mLastMemoryLevel
15016                         + " mLastNumProcesses=" + mLastNumProcesses);
15017                 long now = SystemClock.uptimeMillis();
15018                 pw.print("  mLastIdleTime=");
15019                         TimeUtils.formatDuration(now, mLastIdleTime, pw);
15020                         pw.print(" mLowRamSinceLastIdle=");
15021                         TimeUtils.formatDuration(getLowRamTimeSinceIdle(now), pw);
15022                         pw.println();
15023             }
15024         }
15025
15026         if (!printedAnything) {
15027             pw.println("  (nothing)");
15028         }
15029     }
15030
15031     boolean dumpProcessesToGc(FileDescriptor fd, PrintWriter pw, String[] args,
15032             int opti, boolean needSep, boolean dumpAll, String dumpPackage) {
15033         if (mProcessesToGc.size() > 0) {
15034             boolean printed = false;
15035             long now = SystemClock.uptimeMillis();
15036             for (int i=0; i<mProcessesToGc.size(); i++) {
15037                 ProcessRecord proc = mProcessesToGc.get(i);
15038                 if (dumpPackage != null && !dumpPackage.equals(proc.info.packageName)) {
15039                     continue;
15040                 }
15041                 if (!printed) {
15042                     if (needSep) pw.println();
15043                     needSep = true;
15044                     pw.println("  Processes that are waiting to GC:");
15045                     printed = true;
15046                 }
15047                 pw.print("    Process "); pw.println(proc);
15048                 pw.print("      lowMem="); pw.print(proc.reportLowMemory);
15049                         pw.print(", last gced=");
15050                         pw.print(now-proc.lastRequestedGc);
15051                         pw.print(" ms ago, last lowMem=");
15052                         pw.print(now-proc.lastLowMemory);
15053                         pw.println(" ms ago");
15054
15055             }
15056         }
15057         return needSep;
15058     }
15059
15060     void printOomLevel(PrintWriter pw, String name, int adj) {
15061         pw.print("    ");
15062         if (adj >= 0) {
15063             pw.print(' ');
15064             if (adj < 10) pw.print(' ');
15065         } else {
15066             if (adj > -10) pw.print(' ');
15067         }
15068         pw.print(adj);
15069         pw.print(": ");
15070         pw.print(name);
15071         pw.print(" (");
15072         pw.print(stringifySize(mProcessList.getMemLevel(adj), 1024));
15073         pw.println(")");
15074     }
15075
15076     boolean dumpOomLocked(FileDescriptor fd, PrintWriter pw, String[] args,
15077             int opti, boolean dumpAll) {
15078         boolean needSep = false;
15079
15080         if (mLruProcesses.size() > 0) {
15081             if (needSep) pw.println();
15082             needSep = true;
15083             pw.println("  OOM levels:");
15084             printOomLevel(pw, "SYSTEM_ADJ", ProcessList.SYSTEM_ADJ);
15085             printOomLevel(pw, "PERSISTENT_PROC_ADJ", ProcessList.PERSISTENT_PROC_ADJ);
15086             printOomLevel(pw, "PERSISTENT_SERVICE_ADJ", ProcessList.PERSISTENT_SERVICE_ADJ);
15087             printOomLevel(pw, "FOREGROUND_APP_ADJ", ProcessList.FOREGROUND_APP_ADJ);
15088             printOomLevel(pw, "VISIBLE_APP_ADJ", ProcessList.VISIBLE_APP_ADJ);
15089             printOomLevel(pw, "PERCEPTIBLE_APP_ADJ", ProcessList.PERCEPTIBLE_APP_ADJ);
15090             printOomLevel(pw, "BACKUP_APP_ADJ", ProcessList.BACKUP_APP_ADJ);
15091             printOomLevel(pw, "HEAVY_WEIGHT_APP_ADJ", ProcessList.HEAVY_WEIGHT_APP_ADJ);
15092             printOomLevel(pw, "SERVICE_ADJ", ProcessList.SERVICE_ADJ);
15093             printOomLevel(pw, "HOME_APP_ADJ", ProcessList.HOME_APP_ADJ);
15094             printOomLevel(pw, "PREVIOUS_APP_ADJ", ProcessList.PREVIOUS_APP_ADJ);
15095             printOomLevel(pw, "SERVICE_B_ADJ", ProcessList.SERVICE_B_ADJ);
15096             printOomLevel(pw, "CACHED_APP_MIN_ADJ", ProcessList.CACHED_APP_MIN_ADJ);
15097             printOomLevel(pw, "CACHED_APP_MAX_ADJ", ProcessList.CACHED_APP_MAX_ADJ);
15098
15099             if (needSep) pw.println();
15100             pw.print("  Process OOM control ("); pw.print(mLruProcesses.size());
15101                     pw.print(" total, non-act at ");
15102                     pw.print(mLruProcesses.size()-mLruProcessActivityStart);
15103                     pw.print(", non-svc at ");
15104                     pw.print(mLruProcesses.size()-mLruProcessServiceStart);
15105                     pw.println("):");
15106             dumpProcessOomList(pw, this, mLruProcesses, "    ", "Proc", "PERS", true, null);
15107             needSep = true;
15108         }
15109
15110         dumpProcessesToGc(fd, pw, args, opti, needSep, dumpAll, null);
15111
15112         pw.println();
15113         pw.println("  mHomeProcess: " + mHomeProcess);
15114         pw.println("  mPreviousProcess: " + mPreviousProcess);
15115         if (mHeavyWeightProcess != null) {
15116             pw.println("  mHeavyWeightProcess: " + mHeavyWeightProcess);
15117         }
15118
15119         return true;
15120     }
15121
15122     /**
15123      * There are three ways to call this:
15124      *  - no provider specified: dump all the providers
15125      *  - a flattened component name that matched an existing provider was specified as the
15126      *    first arg: dump that one provider
15127      *  - the first arg isn't the flattened component name of an existing provider:
15128      *    dump all providers whose component contains the first arg as a substring
15129      */
15130     protected boolean dumpProvider(FileDescriptor fd, PrintWriter pw, String name, String[] args,
15131             int opti, boolean dumpAll) {
15132         return mProviderMap.dumpProvider(fd, pw, name, args, opti, dumpAll);
15133     }
15134
15135     static class ItemMatcher {
15136         ArrayList<ComponentName> components;
15137         ArrayList<String> strings;
15138         ArrayList<Integer> objects;
15139         boolean all;
15140
15141         ItemMatcher() {
15142             all = true;
15143         }
15144
15145         void build(String name) {
15146             ComponentName componentName = ComponentName.unflattenFromString(name);
15147             if (componentName != null) {
15148                 if (components == null) {
15149                     components = new ArrayList<ComponentName>();
15150                 }
15151                 components.add(componentName);
15152                 all = false;
15153             } else {
15154                 int objectId = 0;
15155                 // Not a '/' separated full component name; maybe an object ID?
15156                 try {
15157                     objectId = Integer.parseInt(name, 16);
15158                     if (objects == null) {
15159                         objects = new ArrayList<Integer>();
15160                     }
15161                     objects.add(objectId);
15162                     all = false;
15163                 } catch (RuntimeException e) {
15164                     // Not an integer; just do string match.
15165                     if (strings == null) {
15166                         strings = new ArrayList<String>();
15167                     }
15168                     strings.add(name);
15169                     all = false;
15170                 }
15171             }
15172         }
15173
15174         int build(String[] args, int opti) {
15175             for (; opti<args.length; opti++) {
15176                 String name = args[opti];
15177                 if ("--".equals(name)) {
15178                     return opti+1;
15179                 }
15180                 build(name);
15181             }
15182             return opti;
15183         }
15184
15185         boolean match(Object object, ComponentName comp) {
15186             if (all) {
15187                 return true;
15188             }
15189             if (components != null) {
15190                 for (int i=0; i<components.size(); i++) {
15191                     if (components.get(i).equals(comp)) {
15192                         return true;
15193                     }
15194                 }
15195             }
15196             if (objects != null) {
15197                 for (int i=0; i<objects.size(); i++) {
15198                     if (System.identityHashCode(object) == objects.get(i)) {
15199                         return true;
15200                     }
15201                 }
15202             }
15203             if (strings != null) {
15204                 String flat = comp.flattenToString();
15205                 for (int i=0; i<strings.size(); i++) {
15206                     if (flat.contains(strings.get(i))) {
15207                         return true;
15208                     }
15209                 }
15210             }
15211             return false;
15212         }
15213     }
15214
15215     /**
15216      * There are three things that cmd can be:
15217      *  - a flattened component name that matches an existing activity
15218      *  - the cmd arg isn't the flattened component name of an existing activity:
15219      *    dump all activity whose component contains the cmd as a substring
15220      *  - A hex number of the ActivityRecord object instance.
15221      */
15222     protected boolean dumpActivity(FileDescriptor fd, PrintWriter pw, String name, String[] args,
15223             int opti, boolean dumpAll) {
15224         ArrayList<ActivityRecord> activities;
15225
15226         synchronized (this) {
15227             activities = mStackSupervisor.getDumpActivitiesLocked(name);
15228         }
15229
15230         if (activities.size() <= 0) {
15231             return false;
15232         }
15233
15234         String[] newArgs = new String[args.length - opti];
15235         System.arraycopy(args, opti, newArgs, 0, args.length - opti);
15236
15237         TaskRecord lastTask = null;
15238         boolean needSep = false;
15239         for (int i=activities.size()-1; i>=0; i--) {
15240             ActivityRecord r = activities.get(i);
15241             if (needSep) {
15242                 pw.println();
15243             }
15244             needSep = true;
15245             synchronized (this) {
15246                 if (lastTask != r.task) {
15247                     lastTask = r.task;
15248                     pw.print("TASK "); pw.print(lastTask.affinity);
15249                             pw.print(" id="); pw.println(lastTask.taskId);
15250                     if (dumpAll) {
15251                         lastTask.dump(pw, "  ");
15252                     }
15253                 }
15254             }
15255             dumpActivity("  ", fd, pw, activities.get(i), newArgs, dumpAll);
15256         }
15257         return true;
15258     }
15259
15260     /**
15261      * Invokes IApplicationThread.dumpActivity() on the thread of the specified activity if
15262      * there is a thread associated with the activity.
15263      */
15264     private void dumpActivity(String prefix, FileDescriptor fd, PrintWriter pw,
15265             final ActivityRecord r, String[] args, boolean dumpAll) {
15266         String innerPrefix = prefix + "  ";
15267         synchronized (this) {
15268             pw.print(prefix); pw.print("ACTIVITY "); pw.print(r.shortComponentName);
15269                     pw.print(" "); pw.print(Integer.toHexString(System.identityHashCode(r)));
15270                     pw.print(" pid=");
15271                     if (r.app != null) pw.println(r.app.pid);
15272                     else pw.println("(not running)");
15273             if (dumpAll) {
15274                 r.dump(pw, innerPrefix);
15275             }
15276         }
15277         if (r.app != null && r.app.thread != null) {
15278             // flush anything that is already in the PrintWriter since the thread is going
15279             // to write to the file descriptor directly
15280             pw.flush();
15281             try {
15282                 TransferPipe tp = new TransferPipe();
15283                 try {
15284                     r.app.thread.dumpActivity(tp.getWriteFd().getFileDescriptor(),
15285                             r.appToken, innerPrefix, args);
15286                     tp.go(fd);
15287                 } finally {
15288                     tp.kill();
15289                 }
15290             } catch (IOException e) {
15291                 pw.println(innerPrefix + "Failure while dumping the activity: " + e);
15292             } catch (RemoteException e) {
15293                 pw.println(innerPrefix + "Got a RemoteException while dumping the activity");
15294             }
15295         }
15296     }
15297
15298     void dumpBroadcastsLocked(FileDescriptor fd, PrintWriter pw, String[] args,
15299             int opti, boolean dumpAll, String dumpPackage) {
15300         boolean needSep = false;
15301         boolean onlyHistory = false;
15302         boolean printedAnything = false;
15303
15304         if ("history".equals(dumpPackage)) {
15305             if (opti < args.length && "-s".equals(args[opti])) {
15306                 dumpAll = false;
15307             }
15308             onlyHistory = true;
15309             dumpPackage = null;
15310         }
15311
15312         pw.println("ACTIVITY MANAGER BROADCAST STATE (dumpsys activity broadcasts)");
15313         if (!onlyHistory && dumpAll) {
15314             if (mRegisteredReceivers.size() > 0) {
15315                 boolean printed = false;
15316                 Iterator it = mRegisteredReceivers.values().iterator();
15317                 while (it.hasNext()) {
15318                     ReceiverList r = (ReceiverList)it.next();
15319                     if (dumpPackage != null && (r.app == null ||
15320                             !dumpPackage.equals(r.app.info.packageName))) {
15321                         continue;
15322                     }
15323                     if (!printed) {
15324                         pw.println("  Registered Receivers:");
15325                         needSep = true;
15326                         printed = true;
15327                         printedAnything = true;
15328                     }
15329                     pw.print("  * "); pw.println(r);
15330                     r.dump(pw, "    ");
15331                 }
15332             }
15333
15334             if (mReceiverResolver.dump(pw, needSep ?
15335                     "\n  Receiver Resolver Table:" : "  Receiver Resolver Table:",
15336                     "    ", dumpPackage, false, false)) {
15337                 needSep = true;
15338                 printedAnything = true;
15339             }
15340         }
15341
15342         for (BroadcastQueue q : mBroadcastQueues) {
15343             needSep = q.dumpLocked(fd, pw, args, opti, dumpAll, dumpPackage, needSep);
15344             printedAnything |= needSep;
15345         }
15346
15347         needSep = true;
15348
15349         if (!onlyHistory && mStickyBroadcasts != null && dumpPackage == null) {
15350             for (int user=0; user<mStickyBroadcasts.size(); user++) {
15351                 if (needSep) {
15352                     pw.println();
15353                 }
15354                 needSep = true;
15355                 printedAnything = true;
15356                 pw.print("  Sticky broadcasts for user ");
15357                         pw.print(mStickyBroadcasts.keyAt(user)); pw.println(":");
15358                 StringBuilder sb = new StringBuilder(128);
15359                 for (Map.Entry<String, ArrayList<Intent>> ent
15360                         : mStickyBroadcasts.valueAt(user).entrySet()) {
15361                     pw.print("  * Sticky action "); pw.print(ent.getKey());
15362                     if (dumpAll) {
15363                         pw.println(":");
15364                         ArrayList<Intent> intents = ent.getValue();
15365                         final int N = intents.size();
15366                         for (int i=0; i<N; i++) {
15367                             sb.setLength(0);
15368                             sb.append("    Intent: ");
15369                             intents.get(i).toShortString(sb, false, true, false, false);
15370                             pw.println(sb.toString());
15371                             Bundle bundle = intents.get(i).getExtras();
15372                             if (bundle != null) {
15373                                 pw.print("      ");
15374                                 pw.println(bundle.toString());
15375                             }
15376                         }
15377                     } else {
15378                         pw.println("");
15379                     }
15380                 }
15381             }
15382         }
15383
15384         if (!onlyHistory && dumpAll) {
15385             pw.println();
15386             for (BroadcastQueue queue : mBroadcastQueues) {
15387                 pw.println("  mBroadcastsScheduled [" + queue.mQueueName + "]="
15388                         + queue.mBroadcastsScheduled);
15389             }
15390             pw.println("  mHandler:");
15391             mHandler.dump(new PrintWriterPrinter(pw), "    ");
15392             needSep = true;
15393             printedAnything = true;
15394         }
15395
15396         if (!printedAnything) {
15397             pw.println("  (nothing)");
15398         }
15399     }
15400
15401     void dumpBroadcastStatsLocked(FileDescriptor fd, PrintWriter pw, String[] args,
15402             int opti, boolean dumpAll, String dumpPackage) {
15403         if (mCurBroadcastStats == null) {
15404             return;
15405         }
15406
15407         pw.println("ACTIVITY MANAGER BROADCAST STATS STATE (dumpsys activity broadcast-stats)");
15408         final long now = SystemClock.elapsedRealtime();
15409         if (mLastBroadcastStats != null) {
15410             pw.print("  Last stats (from ");
15411             TimeUtils.formatDuration(mLastBroadcastStats.mStartRealtime, now, pw);
15412             pw.print(" to ");
15413             TimeUtils.formatDuration(mLastBroadcastStats.mEndRealtime, now, pw);
15414             pw.print(", ");
15415             TimeUtils.formatDuration(mLastBroadcastStats.mEndUptime
15416                     - mLastBroadcastStats.mStartUptime, pw);
15417             pw.println(" uptime):");
15418             if (!mLastBroadcastStats.dumpStats(pw, "    ", dumpPackage)) {
15419                 pw.println("    (nothing)");
15420             }
15421             pw.println();
15422         }
15423         pw.print("  Current stats (from ");
15424         TimeUtils.formatDuration(mCurBroadcastStats.mStartRealtime, now, pw);
15425         pw.print(" to now, ");
15426         TimeUtils.formatDuration(SystemClock.uptimeMillis()
15427                 - mCurBroadcastStats.mStartUptime, pw);
15428         pw.println(" uptime):");
15429         if (!mCurBroadcastStats.dumpStats(pw, "    ", dumpPackage)) {
15430             pw.println("    (nothing)");
15431         }
15432     }
15433
15434     void dumpBroadcastStatsCheckinLocked(FileDescriptor fd, PrintWriter pw, String[] args,
15435             int opti, boolean fullCheckin, String dumpPackage) {
15436         if (mCurBroadcastStats == null) {
15437             return;
15438         }
15439
15440         if (mLastBroadcastStats != null) {
15441             mLastBroadcastStats.dumpCheckinStats(pw, dumpPackage);
15442             if (fullCheckin) {
15443                 mLastBroadcastStats = null;
15444                 return;
15445             }
15446         }
15447         mCurBroadcastStats.dumpCheckinStats(pw, dumpPackage);
15448         if (fullCheckin) {
15449             mCurBroadcastStats = null;
15450         }
15451     }
15452
15453     void dumpProvidersLocked(FileDescriptor fd, PrintWriter pw, String[] args,
15454             int opti, boolean dumpAll, String dumpPackage) {
15455         boolean needSep;
15456         boolean printedAnything = false;
15457
15458         ItemMatcher matcher = new ItemMatcher();
15459         matcher.build(args, opti);
15460
15461         pw.println("ACTIVITY MANAGER CONTENT PROVIDERS (dumpsys activity providers)");
15462
15463         needSep = mProviderMap.dumpProvidersLocked(pw, dumpAll, dumpPackage);
15464         printedAnything |= needSep;
15465
15466         if (mLaunchingProviders.size() > 0) {
15467             boolean printed = false;
15468             for (int i=mLaunchingProviders.size()-1; i>=0; i--) {
15469                 ContentProviderRecord r = mLaunchingProviders.get(i);
15470                 if (dumpPackage != null && !dumpPackage.equals(r.name.getPackageName())) {
15471                     continue;
15472                 }
15473                 if (!printed) {
15474                     if (needSep) pw.println();
15475                     needSep = true;
15476                     pw.println("  Launching content providers:");
15477                     printed = true;
15478                     printedAnything = true;
15479                 }
15480                 pw.print("  Launching #"); pw.print(i); pw.print(": ");
15481                         pw.println(r);
15482             }
15483         }
15484
15485         if (!printedAnything) {
15486             pw.println("  (nothing)");
15487         }
15488     }
15489
15490     void dumpPermissionsLocked(FileDescriptor fd, PrintWriter pw, String[] args,
15491             int opti, boolean dumpAll, String dumpPackage) {
15492         boolean needSep = false;
15493         boolean printedAnything = false;
15494
15495         pw.println("ACTIVITY MANAGER URI PERMISSIONS (dumpsys activity permissions)");
15496
15497         if (mGrantedUriPermissions.size() > 0) {
15498             boolean printed = false;
15499             int dumpUid = -2;
15500             if (dumpPackage != null) {
15501                 try {
15502                     dumpUid = mContext.getPackageManager().getPackageUidAsUser(dumpPackage,
15503                             MATCH_UNINSTALLED_PACKAGES, 0);
15504                 } catch (NameNotFoundException e) {
15505                     dumpUid = -1;
15506                 }
15507             }
15508             for (int i=0; i<mGrantedUriPermissions.size(); i++) {
15509                 int uid = mGrantedUriPermissions.keyAt(i);
15510                 if (dumpUid >= -1 && UserHandle.getAppId(uid) != dumpUid) {
15511                     continue;
15512                 }
15513                 final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.valueAt(i);
15514                 if (!printed) {
15515                     if (needSep) pw.println();
15516                     needSep = true;
15517                     pw.println("  Granted Uri Permissions:");
15518                     printed = true;
15519                     printedAnything = true;
15520                 }
15521                 pw.print("  * UID "); pw.print(uid); pw.println(" holds:");
15522                 for (UriPermission perm : perms.values()) {
15523                     pw.print("    "); pw.println(perm);
15524                     if (dumpAll) {
15525                         perm.dump(pw, "      ");
15526                     }
15527                 }
15528             }
15529         }
15530
15531         if (!printedAnything) {
15532             pw.println("  (nothing)");
15533         }
15534     }
15535
15536     void dumpPendingIntentsLocked(FileDescriptor fd, PrintWriter pw, String[] args,
15537             int opti, boolean dumpAll, String dumpPackage) {
15538         boolean printed = false;
15539
15540         pw.println("ACTIVITY MANAGER PENDING INTENTS (dumpsys activity intents)");
15541
15542         if (mIntentSenderRecords.size() > 0) {
15543             Iterator<WeakReference<PendingIntentRecord>> it
15544                     = mIntentSenderRecords.values().iterator();
15545             while (it.hasNext()) {
15546                 WeakReference<PendingIntentRecord> ref = it.next();
15547                 PendingIntentRecord rec = ref != null ? ref.get(): null;
15548                 if (dumpPackage != null && (rec == null
15549                         || !dumpPackage.equals(rec.key.packageName))) {
15550                     continue;
15551                 }
15552                 printed = true;
15553                 if (rec != null) {
15554                     pw.print("  * "); pw.println(rec);
15555                     if (dumpAll) {
15556                         rec.dump(pw, "    ");
15557                     }
15558                 } else {
15559                     pw.print("  * "); pw.println(ref);
15560                 }
15561             }
15562         }
15563
15564         if (!printed) {
15565             pw.println("  (nothing)");
15566         }
15567     }
15568
15569     private static final int dumpProcessList(PrintWriter pw,
15570             ActivityManagerService service, List list,
15571             String prefix, String normalLabel, String persistentLabel,
15572             String dumpPackage) {
15573         int numPers = 0;
15574         final int N = list.size()-1;
15575         for (int i=N; i>=0; i--) {
15576             ProcessRecord r = (ProcessRecord)list.get(i);
15577             if (dumpPackage != null && !dumpPackage.equals(r.info.packageName)) {
15578                 continue;
15579             }
15580             pw.println(String.format("%s%s #%2d: %s",
15581                     prefix, (r.persistent ? persistentLabel : normalLabel),
15582                     i, r.toString()));
15583             if (r.persistent) {
15584                 numPers++;
15585             }
15586         }
15587         return numPers;
15588     }
15589
15590     private static final boolean dumpProcessOomList(PrintWriter pw,
15591             ActivityManagerService service, List<ProcessRecord> origList,
15592             String prefix, String normalLabel, String persistentLabel,
15593             boolean inclDetails, String dumpPackage) {
15594
15595         ArrayList<Pair<ProcessRecord, Integer>> list
15596                 = new ArrayList<Pair<ProcessRecord, Integer>>(origList.size());
15597         for (int i=0; i<origList.size(); i++) {
15598             ProcessRecord r = origList.get(i);
15599             if (dumpPackage != null && !r.pkgList.containsKey(dumpPackage)) {
15600                 continue;
15601             }
15602             list.add(new Pair<ProcessRecord, Integer>(origList.get(i), i));
15603         }
15604
15605         if (list.size() <= 0) {
15606             return false;
15607         }
15608
15609         Comparator<Pair<ProcessRecord, Integer>> comparator
15610                 = new Comparator<Pair<ProcessRecord, Integer>>() {
15611             @Override
15612             public int compare(Pair<ProcessRecord, Integer> object1,
15613                     Pair<ProcessRecord, Integer> object2) {
15614                 if (object1.first.setAdj != object2.first.setAdj) {
15615                     return object1.first.setAdj > object2.first.setAdj ? -1 : 1;
15616                 }
15617                 if (object1.first.setProcState != object2.first.setProcState) {
15618                     return object1.first.setProcState > object2.first.setProcState ? -1 : 1;
15619                 }
15620                 if (object1.second.intValue() != object2.second.intValue()) {
15621                     return object1.second.intValue() > object2.second.intValue() ? -1 : 1;
15622                 }
15623                 return 0;
15624             }
15625         };
15626
15627         Collections.sort(list, comparator);
15628
15629         final long curRealtime = SystemClock.elapsedRealtime();
15630         final long realtimeSince = curRealtime - service.mLastPowerCheckRealtime;
15631         final long curUptime = SystemClock.uptimeMillis();
15632         final long uptimeSince = curUptime - service.mLastPowerCheckUptime;
15633
15634         for (int i=list.size()-1; i>=0; i--) {
15635             ProcessRecord r = list.get(i).first;
15636             String oomAdj = ProcessList.makeOomAdjString(r.setAdj);
15637             char schedGroup;
15638             switch (r.setSchedGroup) {
15639                 case ProcessList.SCHED_GROUP_BACKGROUND:
15640                     schedGroup = 'B';
15641                     break;
15642                 case ProcessList.SCHED_GROUP_DEFAULT:
15643                     schedGroup = 'F';
15644                     break;
15645                 case ProcessList.SCHED_GROUP_TOP_APP:
15646                     schedGroup = 'T';
15647                     break;
15648                 default:
15649                     schedGroup = '?';
15650                     break;
15651             }
15652             char foreground;
15653             if (r.foregroundActivities) {
15654                 foreground = 'A';
15655             } else if (r.foregroundServices) {
15656                 foreground = 'S';
15657             } else {
15658                 foreground = ' ';
15659             }
15660             String procState = ProcessList.makeProcStateString(r.curProcState);
15661             pw.print(prefix);
15662             pw.print(r.persistent ? persistentLabel : normalLabel);
15663             pw.print(" #");
15664             int num = (origList.size()-1)-list.get(i).second;
15665             if (num < 10) pw.print(' ');
15666             pw.print(num);
15667             pw.print(": ");
15668             pw.print(oomAdj);
15669             pw.print(' ');
15670             pw.print(schedGroup);
15671             pw.print('/');
15672             pw.print(foreground);
15673             pw.print('/');
15674             pw.print(procState);
15675             pw.print(" trm:");
15676             if (r.trimMemoryLevel < 10) pw.print(' ');
15677             pw.print(r.trimMemoryLevel);
15678             pw.print(' ');
15679             pw.print(r.toShortString());
15680             pw.print(" (");
15681             pw.print(r.adjType);
15682             pw.println(')');
15683             if (r.adjSource != null || r.adjTarget != null) {
15684                 pw.print(prefix);
15685                 pw.print("    ");
15686                 if (r.adjTarget instanceof ComponentName) {
15687                     pw.print(((ComponentName)r.adjTarget).flattenToShortString());
15688                 } else if (r.adjTarget != null) {
15689                     pw.print(r.adjTarget.toString());
15690                 } else {
15691                     pw.print("{null}");
15692                 }
15693                 pw.print("<=");
15694                 if (r.adjSource instanceof ProcessRecord) {
15695                     pw.print("Proc{");
15696                     pw.print(((ProcessRecord)r.adjSource).toShortString());
15697                     pw.println("}");
15698                 } else if (r.adjSource != null) {
15699                     pw.println(r.adjSource.toString());
15700                 } else {
15701                     pw.println("{null}");
15702                 }
15703             }
15704             if (inclDetails) {
15705                 pw.print(prefix);
15706                 pw.print("    ");
15707                 pw.print("oom: max="); pw.print(r.maxAdj);
15708                 pw.print(" curRaw="); pw.print(r.curRawAdj);
15709                 pw.print(" setRaw="); pw.print(r.setRawAdj);
15710                 pw.print(" cur="); pw.print(r.curAdj);
15711                 pw.print(" set="); pw.println(r.setAdj);
15712                 pw.print(prefix);
15713                 pw.print("    ");
15714                 pw.print("state: cur="); pw.print(ProcessList.makeProcStateString(r.curProcState));
15715                 pw.print(" set="); pw.print(ProcessList.makeProcStateString(r.setProcState));
15716                 pw.print(" lastPss="); DebugUtils.printSizeValue(pw, r.lastPss*1024);
15717                 pw.print(" lastSwapPss="); DebugUtils.printSizeValue(pw, r.lastSwapPss*1024);
15718                 pw.print(" lastCachedPss="); DebugUtils.printSizeValue(pw, r.lastCachedPss*1024);
15719                 pw.println();
15720                 pw.print(prefix);
15721                 pw.print("    ");
15722                 pw.print("cached="); pw.print(r.cached);
15723                 pw.print(" empty="); pw.print(r.empty);
15724                 pw.print(" hasAboveClient="); pw.println(r.hasAboveClient);
15725
15726                 if (r.setProcState >= ActivityManager.PROCESS_STATE_SERVICE) {
15727                     if (r.lastWakeTime != 0) {
15728                         long wtime;
15729                         BatteryStatsImpl stats = service.mBatteryStatsService.getActiveStatistics();
15730                         synchronized (stats) {
15731                             wtime = stats.getProcessWakeTime(r.info.uid,
15732                                     r.pid, curRealtime);
15733                         }
15734                         long timeUsed = wtime - r.lastWakeTime;
15735                         pw.print(prefix);
15736                         pw.print("    ");
15737                         pw.print("keep awake over ");
15738                         TimeUtils.formatDuration(realtimeSince, pw);
15739                         pw.print(" used ");
15740                         TimeUtils.formatDuration(timeUsed, pw);
15741                         pw.print(" (");
15742                         pw.print((timeUsed*100)/realtimeSince);
15743                         pw.println("%)");
15744                     }
15745                     if (r.lastCpuTime != 0) {
15746                         long timeUsed = r.curCpuTime - r.lastCpuTime;
15747                         pw.print(prefix);
15748                         pw.print("    ");
15749                         pw.print("run cpu over ");
15750                         TimeUtils.formatDuration(uptimeSince, pw);
15751                         pw.print(" used ");
15752                         TimeUtils.formatDuration(timeUsed, pw);
15753                         pw.print(" (");
15754                         pw.print((timeUsed*100)/uptimeSince);
15755                         pw.println("%)");
15756                     }
15757                 }
15758             }
15759         }
15760         return true;
15761     }
15762
15763     ArrayList<ProcessRecord> collectProcesses(PrintWriter pw, int start, boolean allPkgs,
15764             String[] args) {
15765         ArrayList<ProcessRecord> procs;
15766         synchronized (this) {
15767             if (args != null && args.length > start
15768                     && args[start].charAt(0) != '-') {
15769                 procs = new ArrayList<ProcessRecord>();
15770                 int pid = -1;
15771                 try {
15772                     pid = Integer.parseInt(args[start]);
15773                 } catch (NumberFormatException e) {
15774                 }
15775                 for (int i=mLruProcesses.size()-1; i>=0; i--) {
15776                     ProcessRecord proc = mLruProcesses.get(i);
15777                     if (proc.pid == pid) {
15778                         procs.add(proc);
15779                     } else if (allPkgs && proc.pkgList != null
15780                             && proc.pkgList.containsKey(args[start])) {
15781                         procs.add(proc);
15782                     } else if (proc.processName.equals(args[start])) {
15783                         procs.add(proc);
15784                     }
15785                 }
15786                 if (procs.size() <= 0) {
15787                     return null;
15788                 }
15789             } else {
15790                 procs = new ArrayList<ProcessRecord>(mLruProcesses);
15791             }
15792         }
15793         return procs;
15794     }
15795
15796     final void dumpGraphicsHardwareUsage(FileDescriptor fd,
15797             PrintWriter pw, String[] args) {
15798         ArrayList<ProcessRecord> procs = collectProcesses(pw, 0, false, args);
15799         if (procs == null) {
15800             pw.println("No process found for: " + args[0]);
15801             return;
15802         }
15803
15804         long uptime = SystemClock.uptimeMillis();
15805         long realtime = SystemClock.elapsedRealtime();
15806         pw.println("Applications Graphics Acceleration Info:");
15807         pw.println("Uptime: " + uptime + " Realtime: " + realtime);
15808
15809         for (int i = procs.size() - 1 ; i >= 0 ; i--) {
15810             ProcessRecord r = procs.get(i);
15811             if (r.thread != null) {
15812                 pw.println("\n** Graphics info for pid " + r.pid + " [" + r.processName + "] **");
15813                 pw.flush();
15814                 try {
15815                     TransferPipe tp = new TransferPipe();
15816                     try {
15817                         r.thread.dumpGfxInfo(tp.getWriteFd().getFileDescriptor(), args);
15818                         tp.go(fd);
15819                     } finally {
15820                         tp.kill();
15821                     }
15822                 } catch (IOException e) {
15823                     pw.println("Failure while dumping the app: " + r);
15824                     pw.flush();
15825                 } catch (RemoteException e) {
15826                     pw.println("Got a RemoteException while dumping the app " + r);
15827                     pw.flush();
15828                 }
15829             }
15830         }
15831     }
15832
15833     final void dumpDbInfo(FileDescriptor fd, PrintWriter pw, String[] args) {
15834         ArrayList<ProcessRecord> procs = collectProcesses(pw, 0, false, args);
15835         if (procs == null) {
15836             pw.println("No process found for: " + args[0]);
15837             return;
15838         }
15839
15840         pw.println("Applications Database Info:");
15841
15842         for (int i = procs.size() - 1 ; i >= 0 ; i--) {
15843             ProcessRecord r = procs.get(i);
15844             if (r.thread != null) {
15845                 pw.println("\n** Database info for pid " + r.pid + " [" + r.processName + "] **");
15846                 pw.flush();
15847                 try {
15848                     TransferPipe tp = new TransferPipe();
15849                     try {
15850                         r.thread.dumpDbInfo(tp.getWriteFd().getFileDescriptor(), args);
15851                         tp.go(fd);
15852                     } finally {
15853                         tp.kill();
15854                     }
15855                 } catch (IOException e) {
15856                     pw.println("Failure while dumping the app: " + r);
15857                     pw.flush();
15858                 } catch (RemoteException e) {
15859                     pw.println("Got a RemoteException while dumping the app " + r);
15860                     pw.flush();
15861                 }
15862             }
15863         }
15864     }
15865
15866     final static class MemItem {
15867         final boolean isProc;
15868         final String label;
15869         final String shortLabel;
15870         final long pss;
15871         final long swapPss;
15872         final int id;
15873         final boolean hasActivities;
15874         ArrayList<MemItem> subitems;
15875
15876         public MemItem(String _label, String _shortLabel, long _pss, long _swapPss, int _id,
15877                 boolean _hasActivities) {
15878             isProc = true;
15879             label = _label;
15880             shortLabel = _shortLabel;
15881             pss = _pss;
15882             swapPss = _swapPss;
15883             id = _id;
15884             hasActivities = _hasActivities;
15885         }
15886
15887         public MemItem(String _label, String _shortLabel, long _pss, long _swapPss, int _id) {
15888             isProc = false;
15889             label = _label;
15890             shortLabel = _shortLabel;
15891             pss = _pss;
15892             swapPss = _swapPss;
15893             id = _id;
15894             hasActivities = false;
15895         }
15896     }
15897
15898     static final void dumpMemItems(PrintWriter pw, String prefix, String tag,
15899             ArrayList<MemItem> items, boolean sort, boolean isCompact, boolean dumpSwapPss) {
15900         if (sort && !isCompact) {
15901             Collections.sort(items, new Comparator<MemItem>() {
15902                 @Override
15903                 public int compare(MemItem lhs, MemItem rhs) {
15904                     if (lhs.pss < rhs.pss) {
15905                         return 1;
15906                     } else if (lhs.pss > rhs.pss) {
15907                         return -1;
15908                     }
15909                     return 0;
15910                 }
15911             });
15912         }
15913
15914         for (int i=0; i<items.size(); i++) {
15915             MemItem mi = items.get(i);
15916             if (!isCompact) {
15917                 if (dumpSwapPss) {
15918                     pw.printf("%s%s: %-60s (%s in swap)\n", prefix, stringifyKBSize(mi.pss),
15919                             mi.label, stringifyKBSize(mi.swapPss));
15920                 } else {
15921                     pw.printf("%s%s: %s\n", prefix, stringifyKBSize(mi.pss), mi.label);
15922                 }
15923             } else if (mi.isProc) {
15924                 pw.print("proc,"); pw.print(tag); pw.print(","); pw.print(mi.shortLabel);
15925                 pw.print(","); pw.print(mi.id); pw.print(","); pw.print(mi.pss); pw.print(",");
15926                 pw.print(dumpSwapPss ? mi.swapPss : "N/A");
15927                 pw.println(mi.hasActivities ? ",a" : ",e");
15928             } else {
15929                 pw.print(tag); pw.print(","); pw.print(mi.shortLabel); pw.print(",");
15930                 pw.print(mi.pss); pw.print(","); pw.println(dumpSwapPss ? mi.swapPss : "N/A");
15931             }
15932             if (mi.subitems != null) {
15933                 dumpMemItems(pw, prefix + "    ", mi.shortLabel, mi.subitems,
15934                         true, isCompact, dumpSwapPss);
15935             }
15936         }
15937     }
15938
15939     // These are in KB.
15940     static final long[] DUMP_MEM_BUCKETS = new long[] {
15941         5*1024, 7*1024, 10*1024, 15*1024, 20*1024, 30*1024, 40*1024, 80*1024,
15942         120*1024, 160*1024, 200*1024,
15943         250*1024, 300*1024, 350*1024, 400*1024, 500*1024, 600*1024, 800*1024,
15944         1*1024*1024, 2*1024*1024, 5*1024*1024, 10*1024*1024, 20*1024*1024
15945     };
15946
15947     static final void appendMemBucket(StringBuilder out, long memKB, String label,
15948             boolean stackLike) {
15949         int start = label.lastIndexOf('.');
15950         if (start >= 0) start++;
15951         else start = 0;
15952         int end = label.length();
15953         for (int i=0; i<DUMP_MEM_BUCKETS.length; i++) {
15954             if (DUMP_MEM_BUCKETS[i] >= memKB) {
15955                 long bucket = DUMP_MEM_BUCKETS[i]/1024;
15956                 out.append(bucket);
15957                 out.append(stackLike ? "MB." : "MB ");
15958                 out.append(label, start, end);
15959                 return;
15960             }
15961         }
15962         out.append(memKB/1024);
15963         out.append(stackLike ? "MB." : "MB ");
15964         out.append(label, start, end);
15965     }
15966
15967     static final int[] DUMP_MEM_OOM_ADJ = new int[] {
15968             ProcessList.NATIVE_ADJ,
15969             ProcessList.SYSTEM_ADJ, ProcessList.PERSISTENT_PROC_ADJ,
15970             ProcessList.PERSISTENT_SERVICE_ADJ, ProcessList.FOREGROUND_APP_ADJ,
15971             ProcessList.VISIBLE_APP_ADJ, ProcessList.PERCEPTIBLE_APP_ADJ,
15972             ProcessList.BACKUP_APP_ADJ, ProcessList.HEAVY_WEIGHT_APP_ADJ,
15973             ProcessList.SERVICE_ADJ, ProcessList.HOME_APP_ADJ,
15974             ProcessList.PREVIOUS_APP_ADJ, ProcessList.SERVICE_B_ADJ, ProcessList.CACHED_APP_MIN_ADJ
15975     };
15976     static final String[] DUMP_MEM_OOM_LABEL = new String[] {
15977             "Native",
15978             "System", "Persistent", "Persistent Service", "Foreground",
15979             "Visible", "Perceptible",
15980             "Heavy Weight", "Backup",
15981             "A Services", "Home",
15982             "Previous", "B Services", "Cached"
15983     };
15984     static final String[] DUMP_MEM_OOM_COMPACT_LABEL = new String[] {
15985             "native",
15986             "sys", "pers", "persvc", "fore",
15987             "vis", "percept",
15988             "heavy", "backup",
15989             "servicea", "home",
15990             "prev", "serviceb", "cached"
15991     };
15992
15993     private final void dumpApplicationMemoryUsageHeader(PrintWriter pw, long uptime,
15994             long realtime, boolean isCheckinRequest, boolean isCompact) {
15995         if (isCompact) {
15996             pw.print("version,"); pw.println(MEMINFO_COMPACT_VERSION);
15997         }
15998         if (isCheckinRequest || isCompact) {
15999             // short checkin version
16000             pw.print("time,"); pw.print(uptime); pw.print(","); pw.println(realtime);
16001         } else {
16002             pw.println("Applications Memory Usage (in Kilobytes):");
16003             pw.println("Uptime: " + uptime + " Realtime: " + realtime);
16004         }
16005     }
16006
16007     private static final int KSM_SHARED = 0;
16008     private static final int KSM_SHARING = 1;
16009     private static final int KSM_UNSHARED = 2;
16010     private static final int KSM_VOLATILE = 3;
16011
16012     private final long[] getKsmInfo() {
16013         long[] longOut = new long[4];
16014         final int[] SINGLE_LONG_FORMAT = new int[] {
16015             Process.PROC_SPACE_TERM|Process.PROC_OUT_LONG
16016         };
16017         long[] longTmp = new long[1];
16018         Process.readProcFile("/sys/kernel/mm/ksm/pages_shared",
16019                 SINGLE_LONG_FORMAT, null, longTmp, null);
16020         longOut[KSM_SHARED] = longTmp[0] * ProcessList.PAGE_SIZE / 1024;
16021         longTmp[0] = 0;
16022         Process.readProcFile("/sys/kernel/mm/ksm/pages_sharing",
16023                 SINGLE_LONG_FORMAT, null, longTmp, null);
16024         longOut[KSM_SHARING] = longTmp[0] * ProcessList.PAGE_SIZE / 1024;
16025         longTmp[0] = 0;
16026         Process.readProcFile("/sys/kernel/mm/ksm/pages_unshared",
16027                 SINGLE_LONG_FORMAT, null, longTmp, null);
16028         longOut[KSM_UNSHARED] = longTmp[0] * ProcessList.PAGE_SIZE / 1024;
16029         longTmp[0] = 0;
16030         Process.readProcFile("/sys/kernel/mm/ksm/pages_volatile",
16031                 SINGLE_LONG_FORMAT, null, longTmp, null);
16032         longOut[KSM_VOLATILE] = longTmp[0] * ProcessList.PAGE_SIZE / 1024;
16033         return longOut;
16034     }
16035
16036     private static String stringifySize(long size, int order) {
16037         Locale locale = Locale.US;
16038         switch (order) {
16039             case 1:
16040                 return String.format(locale, "%,13d", size);
16041             case 1024:
16042                 return String.format(locale, "%,9dK", size / 1024);
16043             case 1024 * 1024:
16044                 return String.format(locale, "%,5dM", size / 1024 / 1024);
16045             case 1024 * 1024 * 1024:
16046                 return String.format(locale, "%,1dG", size / 1024 / 1024 / 1024);
16047             default:
16048                 throw new IllegalArgumentException("Invalid size order");
16049         }
16050     }
16051
16052     private static String stringifyKBSize(long size) {
16053         return stringifySize(size * 1024, 1024);
16054     }
16055
16056     // Update this version number in case you change the 'compact' format
16057     private static final int MEMINFO_COMPACT_VERSION = 1;
16058
16059     final void dumpApplicationMemoryUsage(FileDescriptor fd,
16060             PrintWriter pw, String prefix, String[] args, boolean brief, PrintWriter categoryPw) {
16061         boolean dumpDetails = false;
16062         boolean dumpFullDetails = false;
16063         boolean dumpDalvik = false;
16064         boolean dumpSummaryOnly = false;
16065         boolean dumpUnreachable = false;
16066         boolean oomOnly = false;
16067         boolean isCompact = false;
16068         boolean localOnly = false;
16069         boolean packages = false;
16070         boolean isCheckinRequest = false;
16071         boolean dumpSwapPss = false;
16072
16073         int opti = 0;
16074         while (opti < args.length) {
16075             String opt = args[opti];
16076             if (opt == null || opt.length() <= 0 || opt.charAt(0) != '-') {
16077                 break;
16078             }
16079             opti++;
16080             if ("-a".equals(opt)) {
16081                 dumpDetails = true;
16082                 dumpFullDetails = true;
16083                 dumpDalvik = true;
16084                 dumpSwapPss = true;
16085             } else if ("-d".equals(opt)) {
16086                 dumpDalvik = true;
16087             } else if ("-c".equals(opt)) {
16088                 isCompact = true;
16089             } else if ("-s".equals(opt)) {
16090                 dumpDetails = true;
16091                 dumpSummaryOnly = true;
16092             } else if ("-S".equals(opt)) {
16093                 dumpSwapPss = true;
16094             } else if ("--unreachable".equals(opt)) {
16095                 dumpUnreachable = true;
16096             } else if ("--oom".equals(opt)) {
16097                 oomOnly = true;
16098             } else if ("--local".equals(opt)) {
16099                 localOnly = true;
16100             } else if ("--package".equals(opt)) {
16101                 packages = true;
16102             } else if ("--checkin".equals(opt)) {
16103                 isCheckinRequest = true;
16104
16105             } else if ("-h".equals(opt)) {
16106                 pw.println("meminfo dump options: [-a] [-d] [-c] [-s] [--oom] [process]");
16107                 pw.println("  -a: include all available information for each process.");
16108                 pw.println("  -d: include dalvik details.");
16109                 pw.println("  -c: dump in a compact machine-parseable representation.");
16110                 pw.println("  -s: dump only summary of application memory usage.");
16111                 pw.println("  -S: dump also SwapPss.");
16112                 pw.println("  --oom: only show processes organized by oom adj.");
16113                 pw.println("  --local: only collect details locally, don't call process.");
16114                 pw.println("  --package: interpret process arg as package, dumping all");
16115                 pw.println("             processes that have loaded that package.");
16116                 pw.println("  --checkin: dump data for a checkin");
16117                 pw.println("If [process] is specified it can be the name or ");
16118                 pw.println("pid of a specific process to dump.");
16119                 return;
16120             } else {
16121                 pw.println("Unknown argument: " + opt + "; use -h for help");
16122             }
16123         }
16124
16125         long uptime = SystemClock.uptimeMillis();
16126         long realtime = SystemClock.elapsedRealtime();
16127         final long[] tmpLong = new long[1];
16128
16129         ArrayList<ProcessRecord> procs = collectProcesses(pw, opti, packages, args);
16130         if (procs == null) {
16131             // No Java processes.  Maybe they want to print a native process.
16132             if (args != null && args.length > opti
16133                     && args[opti].charAt(0) != '-') {
16134                 ArrayList<ProcessCpuTracker.Stats> nativeProcs
16135                         = new ArrayList<ProcessCpuTracker.Stats>();
16136                 updateCpuStatsNow();
16137                 int findPid = -1;
16138                 try {
16139                     findPid = Integer.parseInt(args[opti]);
16140                 } catch (NumberFormatException e) {
16141                 }
16142                 synchronized (mProcessCpuTracker) {
16143                     final int N = mProcessCpuTracker.countStats();
16144                     for (int i=0; i<N; i++) {
16145                         ProcessCpuTracker.Stats st = mProcessCpuTracker.getStats(i);
16146                         if (st.pid == findPid || (st.baseName != null
16147                                 && st.baseName.equals(args[opti]))) {
16148                             nativeProcs.add(st);
16149                         }
16150                     }
16151                 }
16152                 if (nativeProcs.size() > 0) {
16153                     dumpApplicationMemoryUsageHeader(pw, uptime, realtime, isCheckinRequest,
16154                             isCompact);
16155                     Debug.MemoryInfo mi = null;
16156                     for (int i = nativeProcs.size() - 1 ; i >= 0 ; i--) {
16157                         final ProcessCpuTracker.Stats r = nativeProcs.get(i);
16158                         final int pid = r.pid;
16159                         if (!isCheckinRequest && dumpDetails) {
16160                             pw.println("\n** MEMINFO in pid " + pid + " [" + r.baseName + "] **");
16161                         }
16162                         if (mi == null) {
16163                             mi = new Debug.MemoryInfo();
16164                         }
16165                         if (dumpDetails || (!brief && !oomOnly)) {
16166                             Debug.getMemoryInfo(pid, mi);
16167                         } else {
16168                             mi.dalvikPss = (int)Debug.getPss(pid, tmpLong, null);
16169                             mi.dalvikPrivateDirty = (int)tmpLong[0];
16170                         }
16171                         ActivityThread.dumpMemInfoTable(pw, mi, isCheckinRequest, dumpFullDetails,
16172                                 dumpDalvik, dumpSummaryOnly, pid, r.baseName, 0, 0, 0, 0, 0, 0);
16173                         if (isCheckinRequest) {
16174                             pw.println();
16175                         }
16176                     }
16177                     return;
16178                 }
16179             }
16180             pw.println("No process found for: " + args[opti]);
16181             return;
16182         }
16183
16184         if (!brief && !oomOnly && (procs.size() == 1 || isCheckinRequest || packages)) {
16185             dumpDetails = true;
16186         }
16187
16188         dumpApplicationMemoryUsageHeader(pw, uptime, realtime, isCheckinRequest, isCompact);
16189
16190         String[] innerArgs = new String[args.length-opti];
16191         System.arraycopy(args, opti, innerArgs, 0, args.length-opti);
16192
16193         ArrayList<MemItem> procMems = new ArrayList<MemItem>();
16194         final SparseArray<MemItem> procMemsMap = new SparseArray<MemItem>();
16195         long nativePss = 0;
16196         long nativeSwapPss = 0;
16197         long dalvikPss = 0;
16198         long dalvikSwapPss = 0;
16199         long[] dalvikSubitemPss = dumpDalvik ? new long[Debug.MemoryInfo.NUM_DVK_STATS] :
16200                 EmptyArray.LONG;
16201         long[] dalvikSubitemSwapPss = dumpDalvik ? new long[Debug.MemoryInfo.NUM_DVK_STATS] :
16202                 EmptyArray.LONG;
16203         long otherPss = 0;
16204         long otherSwapPss = 0;
16205         long[] miscPss = new long[Debug.MemoryInfo.NUM_OTHER_STATS];
16206         long[] miscSwapPss = new long[Debug.MemoryInfo.NUM_OTHER_STATS];
16207
16208         long oomPss[] = new long[DUMP_MEM_OOM_LABEL.length];
16209         long oomSwapPss[] = new long[DUMP_MEM_OOM_LABEL.length];
16210         ArrayList<MemItem>[] oomProcs = (ArrayList<MemItem>[])
16211                 new ArrayList[DUMP_MEM_OOM_LABEL.length];
16212
16213         long totalPss = 0;
16214         long totalSwapPss = 0;
16215         long cachedPss = 0;
16216         long cachedSwapPss = 0;
16217         boolean hasSwapPss = false;
16218
16219         Debug.MemoryInfo mi = null;
16220         for (int i = procs.size() - 1 ; i >= 0 ; i--) {
16221             final ProcessRecord r = procs.get(i);
16222             final IApplicationThread thread;
16223             final int pid;
16224             final int oomAdj;
16225             final boolean hasActivities;
16226             synchronized (this) {
16227                 thread = r.thread;
16228                 pid = r.pid;
16229                 oomAdj = r.getSetAdjWithServices();
16230                 hasActivities = r.activities.size() > 0;
16231             }
16232             if (thread != null) {
16233                 if (!isCheckinRequest && dumpDetails) {
16234                     pw.println("\n** MEMINFO in pid " + pid + " [" + r.processName + "] **");
16235                 }
16236                 if (mi == null) {
16237                     mi = new Debug.MemoryInfo();
16238                 }
16239                 if (dumpDetails || (!brief && !oomOnly)) {
16240                     Debug.getMemoryInfo(pid, mi);
16241                     hasSwapPss = mi.hasSwappedOutPss;
16242                 } else {
16243                     mi.dalvikPss = (int)Debug.getPss(pid, tmpLong, null);
16244                     mi.dalvikPrivateDirty = (int)tmpLong[0];
16245                 }
16246                 if (dumpDetails) {
16247                     if (localOnly) {
16248                         ActivityThread.dumpMemInfoTable(pw, mi, isCheckinRequest, dumpFullDetails,
16249                                 dumpDalvik, dumpSummaryOnly, pid, r.processName, 0, 0, 0, 0, 0, 0);
16250                         if (isCheckinRequest) {
16251                             pw.println();
16252                         }
16253                     } else {
16254                         try {
16255                             pw.flush();
16256                             thread.dumpMemInfo(fd, mi, isCheckinRequest, dumpFullDetails,
16257                                     dumpDalvik, dumpSummaryOnly, dumpUnreachable, innerArgs);
16258                         } catch (RemoteException e) {
16259                             if (!isCheckinRequest) {
16260                                 pw.println("Got RemoteException!");
16261                                 pw.flush();
16262                             }
16263                         }
16264                     }
16265                 }
16266
16267                 final long myTotalPss = mi.getTotalPss();
16268                 final long myTotalUss = mi.getTotalUss();
16269                 final long myTotalSwapPss = mi.getTotalSwappedOutPss();
16270
16271                 synchronized (this) {
16272                     if (r.thread != null && oomAdj == r.getSetAdjWithServices()) {
16273                         // Record this for posterity if the process has been stable.
16274                         r.baseProcessTracker.addPss(myTotalPss, myTotalUss, true, r.pkgList);
16275                     }
16276                 }
16277
16278                 if (!isCheckinRequest && mi != null) {
16279                     totalPss += myTotalPss;
16280                     totalSwapPss += myTotalSwapPss;
16281                     MemItem pssItem = new MemItem(r.processName + " (pid " + pid +
16282                             (hasActivities ? " / activities)" : ")"), r.processName, myTotalPss,
16283                             myTotalSwapPss, pid, hasActivities);
16284                     procMems.add(pssItem);
16285                     procMemsMap.put(pid, pssItem);
16286
16287                     nativePss += mi.nativePss;
16288                     nativeSwapPss += mi.nativeSwappedOutPss;
16289                     dalvikPss += mi.dalvikPss;
16290                     dalvikSwapPss += mi.dalvikSwappedOutPss;
16291                     for (int j=0; j<dalvikSubitemPss.length; j++) {
16292                         dalvikSubitemPss[j] += mi.getOtherPss(Debug.MemoryInfo.NUM_OTHER_STATS + j);
16293                         dalvikSubitemSwapPss[j] +=
16294                                 mi.getOtherSwappedOutPss(Debug.MemoryInfo.NUM_OTHER_STATS + j);
16295                     }
16296                     otherPss += mi.otherPss;
16297                     otherSwapPss += mi.otherSwappedOutPss;
16298                     for (int j=0; j<Debug.MemoryInfo.NUM_OTHER_STATS; j++) {
16299                         long mem = mi.getOtherPss(j);
16300                         miscPss[j] += mem;
16301                         otherPss -= mem;
16302                         mem = mi.getOtherSwappedOutPss(j);
16303                         miscSwapPss[j] += mem;
16304                         otherSwapPss -= mem;
16305                     }
16306
16307                     if (oomAdj >= ProcessList.CACHED_APP_MIN_ADJ) {
16308                         cachedPss += myTotalPss;
16309                         cachedSwapPss += myTotalSwapPss;
16310                     }
16311
16312                     for (int oomIndex=0; oomIndex<oomPss.length; oomIndex++) {
16313                         if (oomIndex == (oomPss.length - 1)
16314                                 || (oomAdj >= DUMP_MEM_OOM_ADJ[oomIndex]
16315                                         && oomAdj < DUMP_MEM_OOM_ADJ[oomIndex + 1])) {
16316                             oomPss[oomIndex] += myTotalPss;
16317                             oomSwapPss[oomIndex] += myTotalSwapPss;
16318                             if (oomProcs[oomIndex] == null) {
16319                                 oomProcs[oomIndex] = new ArrayList<MemItem>();
16320                             }
16321                             oomProcs[oomIndex].add(pssItem);
16322                             break;
16323                         }
16324                     }
16325                 }
16326             }
16327         }
16328
16329         long nativeProcTotalPss = 0;
16330
16331         if (!isCheckinRequest && procs.size() > 1 && !packages) {
16332             // If we are showing aggregations, also look for native processes to
16333             // include so that our aggregations are more accurate.
16334             updateCpuStatsNow();
16335             mi = null;
16336             synchronized (mProcessCpuTracker) {
16337                 final int N = mProcessCpuTracker.countStats();
16338                 for (int i=0; i<N; i++) {
16339                     ProcessCpuTracker.Stats st = mProcessCpuTracker.getStats(i);
16340                     if (st.vsize > 0 && procMemsMap.indexOfKey(st.pid) < 0) {
16341                         if (mi == null) {
16342                             mi = new Debug.MemoryInfo();
16343                         }
16344                         if (!brief && !oomOnly) {
16345                             Debug.getMemoryInfo(st.pid, mi);
16346                         } else {
16347                             mi.nativePss = (int)Debug.getPss(st.pid, tmpLong, null);
16348                             mi.nativePrivateDirty = (int)tmpLong[0];
16349                         }
16350
16351                         final long myTotalPss = mi.getTotalPss();
16352                         final long myTotalSwapPss = mi.getTotalSwappedOutPss();
16353                         totalPss += myTotalPss;
16354                         nativeProcTotalPss += myTotalPss;
16355
16356                         MemItem pssItem = new MemItem(st.name + " (pid " + st.pid + ")",
16357                                 st.name, myTotalPss, mi.getSummaryTotalSwapPss(), st.pid, false);
16358                         procMems.add(pssItem);
16359
16360                         nativePss += mi.nativePss;
16361                         nativeSwapPss += mi.nativeSwappedOutPss;
16362                         dalvikPss += mi.dalvikPss;
16363                         dalvikSwapPss += mi.dalvikSwappedOutPss;
16364                         for (int j=0; j<dalvikSubitemPss.length; j++) {
16365                             dalvikSubitemPss[j] += mi.getOtherPss(Debug.MemoryInfo.NUM_OTHER_STATS + j);
16366                             dalvikSubitemSwapPss[j] +=
16367                                     mi.getOtherSwappedOutPss(Debug.MemoryInfo.NUM_OTHER_STATS + j);
16368                         }
16369                         otherPss += mi.otherPss;
16370                         otherSwapPss += mi.otherSwappedOutPss;
16371                         for (int j=0; j<Debug.MemoryInfo.NUM_OTHER_STATS; j++) {
16372                             long mem = mi.getOtherPss(j);
16373                             miscPss[j] += mem;
16374                             otherPss -= mem;
16375                             mem = mi.getOtherSwappedOutPss(j);
16376                             miscSwapPss[j] += mem;
16377                             otherSwapPss -= mem;
16378                         }
16379                         oomPss[0] += myTotalPss;
16380                         oomSwapPss[0] += myTotalSwapPss;
16381                         if (oomProcs[0] == null) {
16382                             oomProcs[0] = new ArrayList<MemItem>();
16383                         }
16384                         oomProcs[0].add(pssItem);
16385                     }
16386                 }
16387             }
16388
16389             ArrayList<MemItem> catMems = new ArrayList<MemItem>();
16390
16391             catMems.add(new MemItem("Native", "Native", nativePss, nativeSwapPss, -1));
16392             final MemItem dalvikItem =
16393                     new MemItem("Dalvik", "Dalvik", dalvikPss, dalvikSwapPss, -2);
16394             if (dalvikSubitemPss.length > 0) {
16395                 dalvikItem.subitems = new ArrayList<MemItem>();
16396                 for (int j=0; j<dalvikSubitemPss.length; j++) {
16397                     final String name = Debug.MemoryInfo.getOtherLabel(
16398                             Debug.MemoryInfo.NUM_OTHER_STATS + j);
16399                     dalvikItem.subitems.add(new MemItem(name, name, dalvikSubitemPss[j],
16400                                     dalvikSubitemSwapPss[j], j));
16401                 }
16402             }
16403             catMems.add(dalvikItem);
16404             catMems.add(new MemItem("Unknown", "Unknown", otherPss, otherSwapPss, -3));
16405             for (int j=0; j<Debug.MemoryInfo.NUM_OTHER_STATS; j++) {
16406                 String label = Debug.MemoryInfo.getOtherLabel(j);
16407                 catMems.add(new MemItem(label, label, miscPss[j], miscSwapPss[j], j));
16408             }
16409
16410             ArrayList<MemItem> oomMems = new ArrayList<MemItem>();
16411             for (int j=0; j<oomPss.length; j++) {
16412                 if (oomPss[j] != 0) {
16413                     String label = isCompact ? DUMP_MEM_OOM_COMPACT_LABEL[j]
16414                             : DUMP_MEM_OOM_LABEL[j];
16415                     MemItem item = new MemItem(label, label, oomPss[j], oomSwapPss[j],
16416                             DUMP_MEM_OOM_ADJ[j]);
16417                     item.subitems = oomProcs[j];
16418                     oomMems.add(item);
16419                 }
16420             }
16421
16422             dumpSwapPss = dumpSwapPss && hasSwapPss && totalSwapPss != 0;
16423             if (!brief && !oomOnly && !isCompact) {
16424                 pw.println();
16425                 pw.println("Total PSS by process:");
16426                 dumpMemItems(pw, "  ", "proc", procMems, true, isCompact, dumpSwapPss);
16427                 pw.println();
16428             }
16429             if (!isCompact) {
16430                 pw.println("Total PSS by OOM adjustment:");
16431             }
16432             dumpMemItems(pw, "  ", "oom", oomMems, false, isCompact, dumpSwapPss);
16433             if (!brief && !oomOnly) {
16434                 PrintWriter out = categoryPw != null ? categoryPw : pw;
16435                 if (!isCompact) {
16436                     out.println();
16437                     out.println("Total PSS by category:");
16438                 }
16439                 dumpMemItems(out, "  ", "cat", catMems, true, isCompact, dumpSwapPss);
16440             }
16441             if (!isCompact) {
16442                 pw.println();
16443             }
16444             MemInfoReader memInfo = new MemInfoReader();
16445             memInfo.readMemInfo();
16446             if (nativeProcTotalPss > 0) {
16447                 synchronized (this) {
16448                     final long cachedKb = memInfo.getCachedSizeKb();
16449                     final long freeKb = memInfo.getFreeSizeKb();
16450                     final long zramKb = memInfo.getZramTotalSizeKb();
16451                     final long kernelKb = memInfo.getKernelUsedSizeKb();
16452                     EventLogTags.writeAmMeminfo(cachedKb*1024, freeKb*1024, zramKb*1024,
16453                             kernelKb*1024, nativeProcTotalPss*1024);
16454                     mProcessStats.addSysMemUsageLocked(cachedKb, freeKb, zramKb, kernelKb,
16455                             nativeProcTotalPss);
16456                 }
16457             }
16458             if (!brief) {
16459                 if (!isCompact) {
16460                     pw.print("Total RAM: "); pw.print(stringifyKBSize(memInfo.getTotalSizeKb()));
16461                     pw.print(" (status ");
16462                     switch (mLastMemoryLevel) {
16463                         case ProcessStats.ADJ_MEM_FACTOR_NORMAL:
16464                             pw.println("normal)");
16465                             break;
16466                         case ProcessStats.ADJ_MEM_FACTOR_MODERATE:
16467                             pw.println("moderate)");
16468                             break;
16469                         case ProcessStats.ADJ_MEM_FACTOR_LOW:
16470                             pw.println("low)");
16471                             break;
16472                         case ProcessStats.ADJ_MEM_FACTOR_CRITICAL:
16473                             pw.println("critical)");
16474                             break;
16475                         default:
16476                             pw.print(mLastMemoryLevel);
16477                             pw.println(")");
16478                             break;
16479                     }
16480                     pw.print(" Free RAM: ");
16481                     pw.print(stringifyKBSize(cachedPss + memInfo.getCachedSizeKb()
16482                             + memInfo.getFreeSizeKb()));
16483                     pw.print(" (");
16484                     pw.print(stringifyKBSize(cachedPss));
16485                     pw.print(" cached pss + ");
16486                     pw.print(stringifyKBSize(memInfo.getCachedSizeKb()));
16487                     pw.print(" cached kernel + ");
16488                     pw.print(stringifyKBSize(memInfo.getFreeSizeKb()));
16489                     pw.println(" free)");
16490                 } else {
16491                     pw.print("ram,"); pw.print(memInfo.getTotalSizeKb()); pw.print(",");
16492                     pw.print(cachedPss + memInfo.getCachedSizeKb()
16493                             + memInfo.getFreeSizeKb()); pw.print(",");
16494                     pw.println(totalPss - cachedPss);
16495                 }
16496             }
16497             long lostRAM = memInfo.getTotalSizeKb() - (totalPss - totalSwapPss)
16498                     - memInfo.getFreeSizeKb() - memInfo.getCachedSizeKb()
16499                     - memInfo.getKernelUsedSizeKb() - memInfo.getZramTotalSizeKb();
16500             if (!isCompact) {
16501                 pw.print(" Used RAM: "); pw.print(stringifyKBSize(totalPss - cachedPss
16502                         + memInfo.getKernelUsedSizeKb())); pw.print(" (");
16503                 pw.print(stringifyKBSize(totalPss - cachedPss)); pw.print(" used pss + ");
16504                 pw.print(stringifyKBSize(memInfo.getKernelUsedSizeKb())); pw.print(" kernel)\n");
16505                 pw.print(" Lost RAM: "); pw.println(stringifyKBSize(lostRAM));
16506             } else {
16507                 pw.print("lostram,"); pw.println(lostRAM);
16508             }
16509             if (!brief) {
16510                 if (memInfo.getZramTotalSizeKb() != 0) {
16511                     if (!isCompact) {
16512                         pw.print("     ZRAM: ");
16513                         pw.print(stringifyKBSize(memInfo.getZramTotalSizeKb()));
16514                                 pw.print(" physical used for ");
16515                                 pw.print(stringifyKBSize(memInfo.getSwapTotalSizeKb()
16516                                         - memInfo.getSwapFreeSizeKb()));
16517                                 pw.print(" in swap (");
16518                                 pw.print(stringifyKBSize(memInfo.getSwapTotalSizeKb()));
16519                                 pw.println(" total swap)");
16520                     } else {
16521                         pw.print("zram,"); pw.print(memInfo.getZramTotalSizeKb()); pw.print(",");
16522                                 pw.print(memInfo.getSwapTotalSizeKb()); pw.print(",");
16523                                 pw.println(memInfo.getSwapFreeSizeKb());
16524                     }
16525                 }
16526                 final long[] ksm = getKsmInfo();
16527                 if (!isCompact) {
16528                     if (ksm[KSM_SHARING] != 0 || ksm[KSM_SHARED] != 0 || ksm[KSM_UNSHARED] != 0
16529                             || ksm[KSM_VOLATILE] != 0) {
16530                         pw.print("      KSM: "); pw.print(stringifyKBSize(ksm[KSM_SHARING]));
16531                                 pw.print(" saved from shared ");
16532                                 pw.print(stringifyKBSize(ksm[KSM_SHARED]));
16533                         pw.print("           "); pw.print(stringifyKBSize(ksm[KSM_UNSHARED]));
16534                                 pw.print(" unshared; ");
16535                                 pw.print(stringifyKBSize(
16536                                              ksm[KSM_VOLATILE])); pw.println(" volatile");
16537                     }
16538                     pw.print("   Tuning: ");
16539                     pw.print(ActivityManager.staticGetMemoryClass());
16540                     pw.print(" (large ");
16541                     pw.print(ActivityManager.staticGetLargeMemoryClass());
16542                     pw.print("), oom ");
16543                     pw.print(stringifySize(
16544                                 mProcessList.getMemLevel(ProcessList.CACHED_APP_MAX_ADJ), 1024));
16545                     pw.print(", restore limit ");
16546                     pw.print(stringifyKBSize(mProcessList.getCachedRestoreThresholdKb()));
16547                     if (ActivityManager.isLowRamDeviceStatic()) {
16548                         pw.print(" (low-ram)");
16549                     }
16550                     if (ActivityManager.isHighEndGfx()) {
16551                         pw.print(" (high-end-gfx)");
16552                     }
16553                     pw.println();
16554                 } else {
16555                     pw.print("ksm,"); pw.print(ksm[KSM_SHARING]); pw.print(",");
16556                     pw.print(ksm[KSM_SHARED]); pw.print(","); pw.print(ksm[KSM_UNSHARED]);
16557                     pw.print(","); pw.println(ksm[KSM_VOLATILE]);
16558                     pw.print("tuning,");
16559                     pw.print(ActivityManager.staticGetMemoryClass());
16560                     pw.print(',');
16561                     pw.print(ActivityManager.staticGetLargeMemoryClass());
16562                     pw.print(',');
16563                     pw.print(mProcessList.getMemLevel(ProcessList.CACHED_APP_MAX_ADJ)/1024);
16564                     if (ActivityManager.isLowRamDeviceStatic()) {
16565                         pw.print(",low-ram");
16566                     }
16567                     if (ActivityManager.isHighEndGfx()) {
16568                         pw.print(",high-end-gfx");
16569                     }
16570                     pw.println();
16571                 }
16572             }
16573         }
16574     }
16575
16576     private void appendBasicMemEntry(StringBuilder sb, int oomAdj, int procState, long pss,
16577             long memtrack, String name) {
16578         sb.append("  ");
16579         sb.append(ProcessList.makeOomAdjString(oomAdj));
16580         sb.append(' ');
16581         sb.append(ProcessList.makeProcStateString(procState));
16582         sb.append(' ');
16583         ProcessList.appendRamKb(sb, pss);
16584         sb.append(": ");
16585         sb.append(name);
16586         if (memtrack > 0) {
16587             sb.append(" (");
16588             sb.append(stringifyKBSize(memtrack));
16589             sb.append(" memtrack)");
16590         }
16591     }
16592
16593     private void appendMemInfo(StringBuilder sb, ProcessMemInfo mi) {
16594         appendBasicMemEntry(sb, mi.oomAdj, mi.procState, mi.pss, mi.memtrack, mi.name);
16595         sb.append(" (pid ");
16596         sb.append(mi.pid);
16597         sb.append(") ");
16598         sb.append(mi.adjType);
16599         sb.append('\n');
16600         if (mi.adjReason != null) {
16601             sb.append("                      ");
16602             sb.append(mi.adjReason);
16603             sb.append('\n');
16604         }
16605     }
16606
16607     void reportMemUsage(ArrayList<ProcessMemInfo> memInfos) {
16608         final SparseArray<ProcessMemInfo> infoMap = new SparseArray<>(memInfos.size());
16609         for (int i=0, N=memInfos.size(); i<N; i++) {
16610             ProcessMemInfo mi = memInfos.get(i);
16611             infoMap.put(mi.pid, mi);
16612         }
16613         updateCpuStatsNow();
16614         long[] memtrackTmp = new long[1];
16615         final List<ProcessCpuTracker.Stats> stats;
16616         // Get a list of Stats that have vsize > 0
16617         synchronized (mProcessCpuTracker) {
16618             stats = mProcessCpuTracker.getStats((st) -> {
16619                 return st.vsize > 0;
16620             });
16621         }
16622         final int statsCount = stats.size();
16623         for (int i = 0; i < statsCount; i++) {
16624             ProcessCpuTracker.Stats st = stats.get(i);
16625             long pss = Debug.getPss(st.pid, null, memtrackTmp);
16626             if (pss > 0) {
16627                 if (infoMap.indexOfKey(st.pid) < 0) {
16628                     ProcessMemInfo mi = new ProcessMemInfo(st.name, st.pid,
16629                             ProcessList.NATIVE_ADJ, -1, "native", null);
16630                     mi.pss = pss;
16631                     mi.memtrack = memtrackTmp[0];
16632                     memInfos.add(mi);
16633                 }
16634             }
16635         }
16636
16637         long totalPss = 0;
16638         long totalMemtrack = 0;
16639         for (int i=0, N=memInfos.size(); i<N; i++) {
16640             ProcessMemInfo mi = memInfos.get(i);
16641             if (mi.pss == 0) {
16642                 mi.pss = Debug.getPss(mi.pid, null, memtrackTmp);
16643                 mi.memtrack = memtrackTmp[0];
16644             }
16645             totalPss += mi.pss;
16646             totalMemtrack += mi.memtrack;
16647         }
16648         Collections.sort(memInfos, new Comparator<ProcessMemInfo>() {
16649             @Override public int compare(ProcessMemInfo lhs, ProcessMemInfo rhs) {
16650                 if (lhs.oomAdj != rhs.oomAdj) {
16651                     return lhs.oomAdj < rhs.oomAdj ? -1 : 1;
16652                 }
16653                 if (lhs.pss != rhs.pss) {
16654                     return lhs.pss < rhs.pss ? 1 : -1;
16655                 }
16656                 return 0;
16657             }
16658         });
16659
16660         StringBuilder tag = new StringBuilder(128);
16661         StringBuilder stack = new StringBuilder(128);
16662         tag.append("Low on memory -- ");
16663         appendMemBucket(tag, totalPss, "total", false);
16664         appendMemBucket(stack, totalPss, "total", true);
16665
16666         StringBuilder fullNativeBuilder = new StringBuilder(1024);
16667         StringBuilder shortNativeBuilder = new StringBuilder(1024);
16668         StringBuilder fullJavaBuilder = new StringBuilder(1024);
16669
16670         boolean firstLine = true;
16671         int lastOomAdj = Integer.MIN_VALUE;
16672         long extraNativeRam = 0;
16673         long extraNativeMemtrack = 0;
16674         long cachedPss = 0;
16675         for (int i=0, N=memInfos.size(); i<N; i++) {
16676             ProcessMemInfo mi = memInfos.get(i);
16677
16678             if (mi.oomAdj >= ProcessList.CACHED_APP_MIN_ADJ) {
16679                 cachedPss += mi.pss;
16680             }
16681
16682             if (mi.oomAdj != ProcessList.NATIVE_ADJ
16683                     && (mi.oomAdj < ProcessList.SERVICE_ADJ
16684                             || mi.oomAdj == ProcessList.HOME_APP_ADJ
16685                             || mi.oomAdj == ProcessList.PREVIOUS_APP_ADJ)) {
16686                 if (lastOomAdj != mi.oomAdj) {
16687                     lastOomAdj = mi.oomAdj;
16688                     if (mi.oomAdj <= ProcessList.FOREGROUND_APP_ADJ) {
16689                         tag.append(" / ");
16690                     }
16691                     if (mi.oomAdj >= ProcessList.FOREGROUND_APP_ADJ) {
16692                         if (firstLine) {
16693                             stack.append(":");
16694                             firstLine = false;
16695                         }
16696                         stack.append("\n\t at ");
16697                     } else {
16698                         stack.append("$");
16699                     }
16700                 } else {
16701                     tag.append(" ");
16702                     stack.append("$");
16703                 }
16704                 if (mi.oomAdj <= ProcessList.FOREGROUND_APP_ADJ) {
16705                     appendMemBucket(tag, mi.pss, mi.name, false);
16706                 }
16707                 appendMemBucket(stack, mi.pss, mi.name, true);
16708                 if (mi.oomAdj >= ProcessList.FOREGROUND_APP_ADJ
16709                         && ((i+1) >= N || memInfos.get(i+1).oomAdj != lastOomAdj)) {
16710                     stack.append("(");
16711                     for (int k=0; k<DUMP_MEM_OOM_ADJ.length; k++) {
16712                         if (DUMP_MEM_OOM_ADJ[k] == mi.oomAdj) {
16713                             stack.append(DUMP_MEM_OOM_LABEL[k]);
16714                             stack.append(":");
16715                             stack.append(DUMP_MEM_OOM_ADJ[k]);
16716                         }
16717                     }
16718                     stack.append(")");
16719                 }
16720             }
16721
16722             appendMemInfo(fullNativeBuilder, mi);
16723             if (mi.oomAdj == ProcessList.NATIVE_ADJ) {
16724                 // The short form only has native processes that are >= 512K.
16725                 if (mi.pss >= 512) {
16726                     appendMemInfo(shortNativeBuilder, mi);
16727                 } else {
16728                     extraNativeRam += mi.pss;
16729                     extraNativeMemtrack += mi.memtrack;
16730                 }
16731             } else {
16732                 // Short form has all other details, but if we have collected RAM
16733                 // from smaller native processes let's dump a summary of that.
16734                 if (extraNativeRam > 0) {
16735                     appendBasicMemEntry(shortNativeBuilder, ProcessList.NATIVE_ADJ,
16736                             -1, extraNativeRam, extraNativeMemtrack, "(Other native)");
16737                     shortNativeBuilder.append('\n');
16738                     extraNativeRam = 0;
16739                 }
16740                 appendMemInfo(fullJavaBuilder, mi);
16741             }
16742         }
16743
16744         fullJavaBuilder.append("           ");
16745         ProcessList.appendRamKb(fullJavaBuilder, totalPss);
16746         fullJavaBuilder.append(": TOTAL");
16747         if (totalMemtrack > 0) {
16748             fullJavaBuilder.append(" (");
16749             fullJavaBuilder.append(stringifyKBSize(totalMemtrack));
16750             fullJavaBuilder.append(" memtrack)");
16751         } else {
16752         }
16753         fullJavaBuilder.append("\n");
16754
16755         MemInfoReader memInfo = new MemInfoReader();
16756         memInfo.readMemInfo();
16757         final long[] infos = memInfo.getRawInfo();
16758
16759         StringBuilder memInfoBuilder = new StringBuilder(1024);
16760         Debug.getMemInfo(infos);
16761         memInfoBuilder.append("  MemInfo: ");
16762         memInfoBuilder.append(stringifyKBSize(infos[Debug.MEMINFO_SLAB])).append(" slab, ");
16763         memInfoBuilder.append(stringifyKBSize(infos[Debug.MEMINFO_SHMEM])).append(" shmem, ");
16764         memInfoBuilder.append(stringifyKBSize(
16765                                   infos[Debug.MEMINFO_VM_ALLOC_USED])).append(" vm alloc, ");
16766         memInfoBuilder.append(stringifyKBSize(
16767                                   infos[Debug.MEMINFO_PAGE_TABLES])).append(" page tables ");
16768         memInfoBuilder.append(stringifyKBSize(
16769                                   infos[Debug.MEMINFO_KERNEL_STACK])).append(" kernel stack\n");
16770         memInfoBuilder.append("           ");
16771         memInfoBuilder.append(stringifyKBSize(infos[Debug.MEMINFO_BUFFERS])).append(" buffers, ");
16772         memInfoBuilder.append(stringifyKBSize(infos[Debug.MEMINFO_CACHED])).append(" cached, ");
16773         memInfoBuilder.append(stringifyKBSize(infos[Debug.MEMINFO_MAPPED])).append(" mapped, ");
16774         memInfoBuilder.append(stringifyKBSize(infos[Debug.MEMINFO_FREE])).append(" free\n");
16775         if (infos[Debug.MEMINFO_ZRAM_TOTAL] != 0) {
16776             memInfoBuilder.append("  ZRAM: ");
16777             memInfoBuilder.append(stringifyKBSize(infos[Debug.MEMINFO_ZRAM_TOTAL]));
16778             memInfoBuilder.append(" RAM, ");
16779             memInfoBuilder.append(stringifyKBSize(infos[Debug.MEMINFO_SWAP_TOTAL]));
16780             memInfoBuilder.append(" swap total, ");
16781             memInfoBuilder.append(stringifyKBSize(infos[Debug.MEMINFO_SWAP_FREE]));
16782             memInfoBuilder.append(" swap free\n");
16783         }
16784         final long[] ksm = getKsmInfo();
16785         if (ksm[KSM_SHARING] != 0 || ksm[KSM_SHARED] != 0 || ksm[KSM_UNSHARED] != 0
16786                 || ksm[KSM_VOLATILE] != 0) {
16787             memInfoBuilder.append("  KSM: ");
16788             memInfoBuilder.append(stringifyKBSize(ksm[KSM_SHARING]));
16789             memInfoBuilder.append(" saved from shared ");
16790             memInfoBuilder.append(stringifyKBSize(ksm[KSM_SHARED]));
16791             memInfoBuilder.append("\n       ");
16792             memInfoBuilder.append(stringifyKBSize(ksm[KSM_UNSHARED]));
16793             memInfoBuilder.append(" unshared; ");
16794             memInfoBuilder.append(stringifyKBSize(ksm[KSM_VOLATILE]));
16795             memInfoBuilder.append(" volatile\n");
16796         }
16797         memInfoBuilder.append("  Free RAM: ");
16798         memInfoBuilder.append(stringifyKBSize(cachedPss + memInfo.getCachedSizeKb()
16799                 + memInfo.getFreeSizeKb()));
16800         memInfoBuilder.append("\n");
16801         memInfoBuilder.append("  Used RAM: ");
16802         memInfoBuilder.append(stringifyKBSize(
16803                                   totalPss - cachedPss + memInfo.getKernelUsedSizeKb()));
16804         memInfoBuilder.append("\n");
16805         memInfoBuilder.append("  Lost RAM: ");
16806         memInfoBuilder.append(stringifyKBSize(memInfo.getTotalSizeKb()
16807                 - totalPss - memInfo.getFreeSizeKb() - memInfo.getCachedSizeKb()
16808                 - memInfo.getKernelUsedSizeKb() - memInfo.getZramTotalSizeKb()));
16809         memInfoBuilder.append("\n");
16810         Slog.i(TAG, "Low on memory:");
16811         Slog.i(TAG, shortNativeBuilder.toString());
16812         Slog.i(TAG, fullJavaBuilder.toString());
16813         Slog.i(TAG, memInfoBuilder.toString());
16814
16815         StringBuilder dropBuilder = new StringBuilder(1024);
16816         /*
16817         StringWriter oomSw = new StringWriter();
16818         PrintWriter oomPw = new FastPrintWriter(oomSw, false, 256);
16819         StringWriter catSw = new StringWriter();
16820         PrintWriter catPw = new FastPrintWriter(catSw, false, 256);
16821         String[] emptyArgs = new String[] { };
16822         dumpApplicationMemoryUsage(null, oomPw, "  ", emptyArgs, true, catPw);
16823         oomPw.flush();
16824         String oomString = oomSw.toString();
16825         */
16826         dropBuilder.append("Low on memory:");
16827         dropBuilder.append(stack);
16828         dropBuilder.append('\n');
16829         dropBuilder.append(fullNativeBuilder);
16830         dropBuilder.append(fullJavaBuilder);
16831         dropBuilder.append('\n');
16832         dropBuilder.append(memInfoBuilder);
16833         dropBuilder.append('\n');
16834         /*
16835         dropBuilder.append(oomString);
16836         dropBuilder.append('\n');
16837         */
16838         StringWriter catSw = new StringWriter();
16839         synchronized (ActivityManagerService.this) {
16840             PrintWriter catPw = new FastPrintWriter(catSw, false, 256);
16841             String[] emptyArgs = new String[] { };
16842             catPw.println();
16843             dumpProcessesLocked(null, catPw, emptyArgs, 0, false, null);
16844             catPw.println();
16845             mServices.newServiceDumperLocked(null, catPw, emptyArgs, 0,
16846                     false, null).dumpLocked();
16847             catPw.println();
16848             dumpActivitiesLocked(null, catPw, emptyArgs, 0, false, false, null);
16849             catPw.flush();
16850         }
16851         dropBuilder.append(catSw.toString());
16852         addErrorToDropBox("lowmem", null, "system_server", null,
16853                 null, tag.toString(), dropBuilder.toString(), null, null);
16854         //Slog.i(TAG, "Sent to dropbox:");
16855         //Slog.i(TAG, dropBuilder.toString());
16856         synchronized (ActivityManagerService.this) {
16857             long now = SystemClock.uptimeMillis();
16858             if (mLastMemUsageReportTime < now) {
16859                 mLastMemUsageReportTime = now;
16860             }
16861         }
16862     }
16863
16864     /**
16865      * Searches array of arguments for the specified string
16866      * @param args array of argument strings
16867      * @param value value to search for
16868      * @return true if the value is contained in the array
16869      */
16870     private static boolean scanArgs(String[] args, String value) {
16871         if (args != null) {
16872             for (String arg : args) {
16873                 if (value.equals(arg)) {
16874                     return true;
16875                 }
16876             }
16877         }
16878         return false;
16879     }
16880
16881     private final boolean removeDyingProviderLocked(ProcessRecord proc,
16882             ContentProviderRecord cpr, boolean always) {
16883         final boolean inLaunching = mLaunchingProviders.contains(cpr);
16884
16885         if (!inLaunching || always) {
16886             synchronized (cpr) {
16887                 cpr.launchingApp = null;
16888                 cpr.notifyAll();
16889             }
16890             mProviderMap.removeProviderByClass(cpr.name, UserHandle.getUserId(cpr.uid));
16891             String names[] = cpr.info.authority.split(";");
16892             for (int j = 0; j < names.length; j++) {
16893                 mProviderMap.removeProviderByName(names[j], UserHandle.getUserId(cpr.uid));
16894             }
16895         }
16896
16897         for (int i = cpr.connections.size() - 1; i >= 0; i--) {
16898             ContentProviderConnection conn = cpr.connections.get(i);
16899             if (conn.waiting) {
16900                 // If this connection is waiting for the provider, then we don't
16901                 // need to mess with its process unless we are always removing
16902                 // or for some reason the provider is not currently launching.
16903                 if (inLaunching && !always) {
16904                     continue;
16905                 }
16906             }
16907             ProcessRecord capp = conn.client;
16908             conn.dead = true;
16909             if (conn.stableCount > 0) {
16910                 if (!capp.persistent && capp.thread != null
16911                         && capp.pid != 0
16912                         && capp.pid != MY_PID) {
16913                     capp.kill("depends on provider "
16914                             + cpr.name.flattenToShortString()
16915                             + " in dying proc " + (proc != null ? proc.processName : "??")
16916                             + " (adj " + (proc != null ? proc.setAdj : "??") + ")", true);
16917                 }
16918             } else if (capp.thread != null && conn.provider.provider != null) {
16919                 try {
16920                     capp.thread.unstableProviderDied(conn.provider.provider.asBinder());
16921                 } catch (RemoteException e) {
16922                 }
16923                 // In the protocol here, we don't expect the client to correctly
16924                 // clean up this connection, we'll just remove it.
16925                 cpr.connections.remove(i);
16926                 if (conn.client.conProviders.remove(conn)) {
16927                     stopAssociationLocked(capp.uid, capp.processName, cpr.uid, cpr.name);
16928                 }
16929             }
16930         }
16931
16932         if (inLaunching && always) {
16933             mLaunchingProviders.remove(cpr);
16934         }
16935         return inLaunching;
16936     }
16937
16938     /**
16939      * Main code for cleaning up a process when it has gone away.  This is
16940      * called both as a result of the process dying, or directly when stopping
16941      * a process when running in single process mode.
16942      *
16943      * @return Returns true if the given process has been restarted, so the
16944      * app that was passed in must remain on the process lists.
16945      */
16946     private final boolean cleanUpApplicationRecordLocked(ProcessRecord app,
16947             boolean restarting, boolean allowRestart, int index, boolean replacingPid) {
16948         Slog.d(TAG, "cleanUpApplicationRecord -- " + app.pid);
16949         if (index >= 0) {
16950             removeLruProcessLocked(app);
16951             ProcessList.remove(app.pid);
16952         }
16953
16954         mProcessesToGc.remove(app);
16955         mPendingPssProcesses.remove(app);
16956
16957         // Dismiss any open dialogs.
16958         if (app.crashDialog != null && !app.forceCrashReport) {
16959             app.crashDialog.dismiss();
16960             app.crashDialog = null;
16961         }
16962         if (app.anrDialog != null) {
16963             app.anrDialog.dismiss();
16964             app.anrDialog = null;
16965         }
16966         if (app.waitDialog != null) {
16967             app.waitDialog.dismiss();
16968             app.waitDialog = null;
16969         }
16970
16971         app.crashing = false;
16972         app.notResponding = false;
16973
16974         app.resetPackageList(mProcessStats);
16975         app.unlinkDeathRecipient();
16976         app.makeInactive(mProcessStats);
16977         app.waitingToKill = null;
16978         app.forcingToForeground = null;
16979         updateProcessForegroundLocked(app, false, false);
16980         app.foregroundActivities = false;
16981         app.hasShownUi = false;
16982         app.treatLikeActivity = false;
16983         app.hasAboveClient = false;
16984         app.hasClientActivities = false;
16985
16986         mServices.killServicesLocked(app, allowRestart);
16987
16988         boolean restart = false;
16989
16990         // Remove published content providers.
16991         for (int i = app.pubProviders.size() - 1; i >= 0; i--) {
16992             ContentProviderRecord cpr = app.pubProviders.valueAt(i);
16993             final boolean always = app.bad || !allowRestart;
16994             boolean inLaunching = removeDyingProviderLocked(app, cpr, always);
16995             if ((inLaunching || always) && cpr.hasConnectionOrHandle()) {
16996                 // We left the provider in the launching list, need to
16997                 // restart it.
16998                 restart = true;
16999             }
17000
17001             cpr.provider = null;
17002             cpr.proc = null;
17003         }
17004         app.pubProviders.clear();
17005
17006         // Take care of any launching providers waiting for this process.
17007         if (cleanupAppInLaunchingProvidersLocked(app, false)) {
17008             restart = true;
17009         }
17010
17011         // Unregister from connected content providers.
17012         if (!app.conProviders.isEmpty()) {
17013             for (int i = app.conProviders.size() - 1; i >= 0; i--) {
17014                 ContentProviderConnection conn = app.conProviders.get(i);
17015                 conn.provider.connections.remove(conn);
17016                 stopAssociationLocked(app.uid, app.processName, conn.provider.uid,
17017                         conn.provider.name);
17018             }
17019             app.conProviders.clear();
17020         }
17021
17022         // At this point there may be remaining entries in mLaunchingProviders
17023         // where we were the only one waiting, so they are no longer of use.
17024         // Look for these and clean up if found.
17025         // XXX Commented out for now.  Trying to figure out a way to reproduce
17026         // the actual situation to identify what is actually going on.
17027         if (false) {
17028             for (int i = mLaunchingProviders.size() - 1; i >= 0; i--) {
17029                 ContentProviderRecord cpr = mLaunchingProviders.get(i);
17030                 if (cpr.connections.size() <= 0 && !cpr.hasExternalProcessHandles()) {
17031                     synchronized (cpr) {
17032                         cpr.launchingApp = null;
17033                         cpr.notifyAll();
17034                     }
17035                 }
17036             }
17037         }
17038
17039         skipCurrentReceiverLocked(app);
17040
17041         // Unregister any receivers.
17042         for (int i = app.receivers.size() - 1; i >= 0; i--) {
17043             removeReceiverLocked(app.receivers.valueAt(i));
17044         }
17045         app.receivers.clear();
17046
17047         // If the app is undergoing backup, tell the backup manager about it
17048         if (mBackupTarget != null && app.pid == mBackupTarget.app.pid) {
17049             if (DEBUG_BACKUP || DEBUG_CLEANUP) Slog.d(TAG_CLEANUP, "App "
17050                     + mBackupTarget.appInfo + " died during backup");
17051             try {
17052                 IBackupManager bm = IBackupManager.Stub.asInterface(
17053                         ServiceManager.getService(Context.BACKUP_SERVICE));
17054                 bm.agentDisconnected(app.info.packageName);
17055             } catch (RemoteException e) {
17056                 // can't happen; backup manager is local
17057             }
17058         }
17059
17060         for (int i = mPendingProcessChanges.size() - 1; i >= 0; i--) {
17061             ProcessChangeItem item = mPendingProcessChanges.get(i);
17062             if (item.pid == app.pid) {
17063                 mPendingProcessChanges.remove(i);
17064                 mAvailProcessChanges.add(item);
17065             }
17066         }
17067         mUiHandler.obtainMessage(DISPATCH_PROCESS_DIED_UI_MSG, app.pid, app.info.uid,
17068                 null).sendToTarget();
17069
17070         // If the caller is restarting this app, then leave it in its
17071         // current lists and let the caller take care of it.
17072         if (restarting) {
17073             return false;
17074         }
17075
17076         if (!app.persistent || app.isolated) {
17077             if (DEBUG_PROCESSES || DEBUG_CLEANUP) Slog.v(TAG_CLEANUP,
17078                     "Removing non-persistent process during cleanup: " + app);
17079             if (!replacingPid) {
17080                 removeProcessNameLocked(app.processName, app.uid, app);
17081             }
17082             if (mHeavyWeightProcess == app) {
17083                 mHandler.sendMessage(mHandler.obtainMessage(CANCEL_HEAVY_NOTIFICATION_MSG,
17084                         mHeavyWeightProcess.userId, 0));
17085                 mHeavyWeightProcess = null;
17086             }
17087         } else if (!app.removed) {
17088             // This app is persistent, so we need to keep its record around.
17089             // If it is not already on the pending app list, add it there
17090             // and start a new process for it.
17091             if (mPersistentStartingProcesses.indexOf(app) < 0) {
17092                 mPersistentStartingProcesses.add(app);
17093                 restart = true;
17094             }
17095         }
17096         if ((DEBUG_PROCESSES || DEBUG_CLEANUP) && mProcessesOnHold.contains(app)) Slog.v(
17097                 TAG_CLEANUP, "Clean-up removing on hold: " + app);
17098         mProcessesOnHold.remove(app);
17099
17100         if (app == mHomeProcess) {
17101             mHomeProcess = null;
17102         }
17103         if (app == mPreviousProcess) {
17104             mPreviousProcess = null;
17105         }
17106
17107         if (restart && !app.isolated) {
17108             // We have components that still need to be running in the
17109             // process, so re-launch it.
17110             if (index < 0) {
17111                 ProcessList.remove(app.pid);
17112             }
17113             addProcessNameLocked(app);
17114             startProcessLocked(app, "restart", app.processName);
17115             return true;
17116         } else if (app.pid > 0 && app.pid != MY_PID) {
17117             // Goodbye!
17118             boolean removed;
17119             synchronized (mPidsSelfLocked) {
17120                 mPidsSelfLocked.remove(app.pid);
17121                 mHandler.removeMessages(PROC_START_TIMEOUT_MSG, app);
17122             }
17123             mBatteryStatsService.noteProcessFinish(app.processName, app.info.uid);
17124             if (app.isolated) {
17125                 mBatteryStatsService.removeIsolatedUid(app.uid, app.info.uid);
17126             }
17127             app.setPid(0);
17128         }
17129         return false;
17130     }
17131
17132     boolean checkAppInLaunchingProvidersLocked(ProcessRecord app) {
17133         for (int i = mLaunchingProviders.size() - 1; i >= 0; i--) {
17134             ContentProviderRecord cpr = mLaunchingProviders.get(i);
17135             if (cpr.launchingApp == app) {
17136                 return true;
17137             }
17138         }
17139         return false;
17140     }
17141
17142     boolean cleanupAppInLaunchingProvidersLocked(ProcessRecord app, boolean alwaysBad) {
17143         // Look through the content providers we are waiting to have launched,
17144         // and if any run in this process then either schedule a restart of
17145         // the process or kill the client waiting for it if this process has
17146         // gone bad.
17147         boolean restart = false;
17148         for (int i = mLaunchingProviders.size() - 1; i >= 0; i--) {
17149             ContentProviderRecord cpr = mLaunchingProviders.get(i);
17150             if (cpr.launchingApp == app) {
17151                 if (!alwaysBad && !app.bad && cpr.hasConnectionOrHandle()) {
17152                     restart = true;
17153                 } else {
17154                     removeDyingProviderLocked(app, cpr, true);
17155                 }
17156             }
17157         }
17158         return restart;
17159     }
17160
17161     // =========================================================
17162     // SERVICES
17163     // =========================================================
17164
17165     @Override
17166     public List<ActivityManager.RunningServiceInfo> getServices(int maxNum,
17167             int flags) {
17168         enforceNotIsolatedCaller("getServices");
17169         synchronized (this) {
17170             return mServices.getRunningServiceInfoLocked(maxNum, flags);
17171         }
17172     }
17173
17174     @Override
17175     public PendingIntent getRunningServiceControlPanel(ComponentName name) {
17176         enforceNotIsolatedCaller("getRunningServiceControlPanel");
17177         synchronized (this) {
17178             return mServices.getRunningServiceControlPanelLocked(name);
17179         }
17180     }
17181
17182     @Override
17183     public ComponentName startService(IApplicationThread caller, Intent service,
17184             String resolvedType, String callingPackage, int userId)
17185             throws TransactionTooLargeException {
17186         enforceNotIsolatedCaller("startService");
17187         // Refuse possible leaked file descriptors
17188         if (service != null && service.hasFileDescriptors() == true) {
17189             throw new IllegalArgumentException("File descriptors passed in Intent");
17190         }
17191
17192         if (callingPackage == null) {
17193             throw new IllegalArgumentException("callingPackage cannot be null");
17194         }
17195
17196         if (DEBUG_SERVICE) Slog.v(TAG_SERVICE,
17197                 "startService: " + service + " type=" + resolvedType);
17198         synchronized(this) {
17199             final int callingPid = Binder.getCallingPid();
17200             final int callingUid = Binder.getCallingUid();
17201             final long origId = Binder.clearCallingIdentity();
17202             ComponentName res = mServices.startServiceLocked(caller, service,
17203                     resolvedType, callingPid, callingUid, callingPackage, userId);
17204             Binder.restoreCallingIdentity(origId);
17205             return res;
17206         }
17207     }
17208
17209     ComponentName startServiceInPackage(int uid, Intent service, String resolvedType,
17210             String callingPackage, int userId)
17211             throws TransactionTooLargeException {
17212         synchronized(this) {
17213             if (DEBUG_SERVICE) Slog.v(TAG_SERVICE,
17214                     "startServiceInPackage: " + service + " type=" + resolvedType);
17215             final long origId = Binder.clearCallingIdentity();
17216             ComponentName res = mServices.startServiceLocked(null, service,
17217                     resolvedType, -1, uid, callingPackage, userId);
17218             Binder.restoreCallingIdentity(origId);
17219             return res;
17220         }
17221     }
17222
17223     @Override
17224     public int stopService(IApplicationThread caller, Intent service,
17225             String resolvedType, int userId) {
17226         enforceNotIsolatedCaller("stopService");
17227         // Refuse possible leaked file descriptors
17228         if (service != null && service.hasFileDescriptors() == true) {
17229             throw new IllegalArgumentException("File descriptors passed in Intent");
17230         }
17231
17232         synchronized(this) {
17233             return mServices.stopServiceLocked(caller, service, resolvedType, userId);
17234         }
17235     }
17236
17237     @Override
17238     public IBinder peekService(Intent service, String resolvedType, String callingPackage) {
17239         enforceNotIsolatedCaller("peekService");
17240         // Refuse possible leaked file descriptors
17241         if (service != null && service.hasFileDescriptors() == true) {
17242             throw new IllegalArgumentException("File descriptors passed in Intent");
17243         }
17244
17245         if (callingPackage == null) {
17246             throw new IllegalArgumentException("callingPackage cannot be null");
17247         }
17248
17249         synchronized(this) {
17250             return mServices.peekServiceLocked(service, resolvedType, callingPackage);
17251         }
17252     }
17253
17254     @Override
17255     public boolean stopServiceToken(ComponentName className, IBinder token,
17256             int startId) {
17257         synchronized(this) {
17258             return mServices.stopServiceTokenLocked(className, token, startId);
17259         }
17260     }
17261
17262     @Override
17263     public void setServiceForeground(ComponentName className, IBinder token,
17264             int id, Notification notification, int flags) {
17265         synchronized(this) {
17266             mServices.setServiceForegroundLocked(className, token, id, notification, flags);
17267         }
17268     }
17269
17270     @Override
17271     public int handleIncomingUser(int callingPid, int callingUid, int userId, boolean allowAll,
17272             boolean requireFull, String name, String callerPackage) {
17273         return mUserController.handleIncomingUser(callingPid, callingUid, userId, allowAll,
17274                 requireFull ? ALLOW_FULL_ONLY : ALLOW_NON_FULL, name, callerPackage);
17275     }
17276
17277     boolean isSingleton(String componentProcessName, ApplicationInfo aInfo,
17278             String className, int flags) {
17279         boolean result = false;
17280         // For apps that don't have pre-defined UIDs, check for permission
17281         if (UserHandle.getAppId(aInfo.uid) >= Process.FIRST_APPLICATION_UID) {
17282             if ((flags & ServiceInfo.FLAG_SINGLE_USER) != 0) {
17283                 if (ActivityManager.checkUidPermission(
17284                         INTERACT_ACROSS_USERS,
17285                         aInfo.uid) != PackageManager.PERMISSION_GRANTED) {
17286                     ComponentName comp = new ComponentName(aInfo.packageName, className);
17287                     String msg = "Permission Denial: Component " + comp.flattenToShortString()
17288                             + " requests FLAG_SINGLE_USER, but app does not hold "
17289                             + INTERACT_ACROSS_USERS;
17290                     Slog.w(TAG, msg);
17291                     throw new SecurityException(msg);
17292                 }
17293                 // Permission passed
17294                 result = true;
17295             }
17296         } else if ("system".equals(componentProcessName)) {
17297             result = true;
17298         } else if ((flags & ServiceInfo.FLAG_SINGLE_USER) != 0) {
17299             // Phone app and persistent apps are allowed to export singleuser providers.
17300             result = UserHandle.isSameApp(aInfo.uid, Process.PHONE_UID)
17301                     || (aInfo.flags & ApplicationInfo.FLAG_PERSISTENT) != 0;
17302         }
17303         if (DEBUG_MU) Slog.v(TAG_MU,
17304                 "isSingleton(" + componentProcessName + ", " + aInfo + ", " + className + ", 0x"
17305                 + Integer.toHexString(flags) + ") = " + result);
17306         return result;
17307     }
17308
17309     /**
17310      * Checks to see if the caller is in the same app as the singleton
17311      * component, or the component is in a special app. It allows special apps
17312      * to export singleton components but prevents exporting singleton
17313      * components for regular apps.
17314      */
17315     boolean isValidSingletonCall(int callingUid, int componentUid) {
17316         int componentAppId = UserHandle.getAppId(componentUid);
17317         return UserHandle.isSameApp(callingUid, componentUid)
17318                 || componentAppId == Process.SYSTEM_UID
17319                 || componentAppId == Process.PHONE_UID
17320                 || ActivityManager.checkUidPermission(INTERACT_ACROSS_USERS_FULL, componentUid)
17321                         == PackageManager.PERMISSION_GRANTED;
17322     }
17323
17324     public int bindService(IApplicationThread caller, IBinder token, Intent service,
17325             String resolvedType, IServiceConnection connection, int flags, String callingPackage,
17326             int userId) throws TransactionTooLargeException {
17327         enforceNotIsolatedCaller("bindService");
17328
17329         // Refuse possible leaked file descriptors
17330         if (service != null && service.hasFileDescriptors() == true) {
17331             throw new IllegalArgumentException("File descriptors passed in Intent");
17332         }
17333
17334         if (callingPackage == null) {
17335             throw new IllegalArgumentException("callingPackage cannot be null");
17336         }
17337
17338         synchronized(this) {
17339             return mServices.bindServiceLocked(caller, token, service,
17340                     resolvedType, connection, flags, callingPackage, userId);
17341         }
17342     }
17343
17344     public boolean unbindService(IServiceConnection connection) {
17345         synchronized (this) {
17346             return mServices.unbindServiceLocked(connection);
17347         }
17348     }
17349
17350     public void publishService(IBinder token, Intent intent, IBinder service) {
17351         // Refuse possible leaked file descriptors
17352         if (intent != null && intent.hasFileDescriptors() == true) {
17353             throw new IllegalArgumentException("File descriptors passed in Intent");
17354         }
17355
17356         synchronized(this) {
17357             if (!(token instanceof ServiceRecord)) {
17358                 throw new IllegalArgumentException("Invalid service token");
17359             }
17360             mServices.publishServiceLocked((ServiceRecord)token, intent, service);
17361         }
17362     }
17363
17364     public void unbindFinished(IBinder token, Intent intent, boolean doRebind) {
17365         // Refuse possible leaked file descriptors
17366         if (intent != null && intent.hasFileDescriptors() == true) {
17367             throw new IllegalArgumentException("File descriptors passed in Intent");
17368         }
17369
17370         synchronized(this) {
17371             mServices.unbindFinishedLocked((ServiceRecord)token, intent, doRebind);
17372         }
17373     }
17374
17375     public void serviceDoneExecuting(IBinder token, int type, int startId, int res) {
17376         synchronized(this) {
17377             if (!(token instanceof ServiceRecord)) {
17378                 Slog.e(TAG, "serviceDoneExecuting: Invalid service token=" + token);
17379                 throw new IllegalArgumentException("Invalid service token");
17380             }
17381             mServices.serviceDoneExecutingLocked((ServiceRecord)token, type, startId, res);
17382         }
17383     }
17384
17385     // =========================================================
17386     // BACKUP AND RESTORE
17387     // =========================================================
17388
17389     // Cause the target app to be launched if necessary and its backup agent
17390     // instantiated.  The backup agent will invoke backupAgentCreated() on the
17391     // activity manager to announce its creation.
17392     public boolean bindBackupAgent(String packageName, int backupMode, int userId) {
17393         if (DEBUG_BACKUP) Slog.v(TAG, "bindBackupAgent: app=" + packageName + " mode=" + backupMode);
17394         enforceCallingPermission("android.permission.CONFIRM_FULL_BACKUP", "bindBackupAgent");
17395
17396         IPackageManager pm = AppGlobals.getPackageManager();
17397         ApplicationInfo app = null;
17398         try {
17399             app = pm.getApplicationInfo(packageName, 0, userId);
17400         } catch (RemoteException e) {
17401             // can't happen; package manager is process-local
17402         }
17403         if (app == null) {
17404             Slog.w(TAG, "Unable to bind backup agent for " + packageName);
17405             return false;
17406         }
17407
17408         synchronized(this) {
17409             // !!! TODO: currently no check here that we're already bound
17410             BatteryStatsImpl.Uid.Pkg.Serv ss = null;
17411             BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
17412             synchronized (stats) {
17413                 ss = stats.getServiceStatsLocked(app.uid, app.packageName, app.name);
17414             }
17415
17416             // Backup agent is now in use, its package can't be stopped.
17417             try {
17418                 AppGlobals.getPackageManager().setPackageStoppedState(
17419                         app.packageName, false, UserHandle.getUserId(app.uid));
17420             } catch (RemoteException e) {
17421             } catch (IllegalArgumentException e) {
17422                 Slog.w(TAG, "Failed trying to unstop package "
17423                         + app.packageName + ": " + e);
17424             }
17425
17426             BackupRecord r = new BackupRecord(ss, app, backupMode);
17427             ComponentName hostingName = (backupMode == IApplicationThread.BACKUP_MODE_INCREMENTAL)
17428                     ? new ComponentName(app.packageName, app.backupAgentName)
17429                     : new ComponentName("android", "FullBackupAgent");
17430             // startProcessLocked() returns existing proc's record if it's already running
17431             ProcessRecord proc = startProcessLocked(app.processName, app,
17432                     false, 0, "backup", hostingName, false, false, false);
17433             if (proc == null) {
17434                 Slog.e(TAG, "Unable to start backup agent process " + r);
17435                 return false;
17436             }
17437
17438             // If the app is a regular app (uid >= 10000) and not the system server or phone
17439             // process, etc, then mark it as being in full backup so that certain calls to the
17440             // process can be blocked. This is not reset to false anywhere because we kill the
17441             // process after the full backup is done and the ProcessRecord will vaporize anyway.
17442             if (UserHandle.isApp(app.uid) && backupMode == IApplicationThread.BACKUP_MODE_FULL) {
17443                 proc.inFullBackup = true;
17444             }
17445             r.app = proc;
17446             mBackupTarget = r;
17447             mBackupAppName = app.packageName;
17448
17449             // Try not to kill the process during backup
17450             updateOomAdjLocked(proc);
17451
17452             // If the process is already attached, schedule the creation of the backup agent now.
17453             // If it is not yet live, this will be done when it attaches to the framework.
17454             if (proc.thread != null) {
17455                 if (DEBUG_BACKUP) Slog.v(TAG_BACKUP, "Agent proc already running: " + proc);
17456                 try {
17457                     proc.thread.scheduleCreateBackupAgent(app,
17458                             compatibilityInfoForPackageLocked(app), backupMode);
17459                 } catch (RemoteException e) {
17460                     // Will time out on the backup manager side
17461                 }
17462             } else {
17463                 if (DEBUG_BACKUP) Slog.v(TAG_BACKUP, "Agent proc not running, waiting for attach");
17464             }
17465             // Invariants: at this point, the target app process exists and the application
17466             // is either already running or in the process of coming up.  mBackupTarget and
17467             // mBackupAppName describe the app, so that when it binds back to the AM we
17468             // know that it's scheduled for a backup-agent operation.
17469         }
17470
17471         return true;
17472     }
17473
17474     @Override
17475     public void clearPendingBackup() {
17476         if (DEBUG_BACKUP) Slog.v(TAG_BACKUP, "clearPendingBackup");
17477         enforceCallingPermission("android.permission.BACKUP", "clearPendingBackup");
17478
17479         synchronized (this) {
17480             mBackupTarget = null;
17481             mBackupAppName = null;
17482         }
17483     }
17484
17485     // A backup agent has just come up
17486     public void backupAgentCreated(String agentPackageName, IBinder agent) {
17487         if (DEBUG_BACKUP) Slog.v(TAG_BACKUP, "backupAgentCreated: " + agentPackageName
17488                 + " = " + agent);
17489
17490         synchronized(this) {
17491             if (!agentPackageName.equals(mBackupAppName)) {
17492                 Slog.e(TAG, "Backup agent created for " + agentPackageName + " but not requested!");
17493                 return;
17494             }
17495         }
17496
17497         long oldIdent = Binder.clearCallingIdentity();
17498         try {
17499             IBackupManager bm = IBackupManager.Stub.asInterface(
17500                     ServiceManager.getService(Context.BACKUP_SERVICE));
17501             bm.agentConnected(agentPackageName, agent);
17502         } catch (RemoteException e) {
17503             // can't happen; the backup manager service is local
17504         } catch (Exception e) {
17505             Slog.w(TAG, "Exception trying to deliver BackupAgent binding: ");
17506             e.printStackTrace();
17507         } finally {
17508             Binder.restoreCallingIdentity(oldIdent);
17509         }
17510     }
17511
17512     // done with this agent
17513     public void unbindBackupAgent(ApplicationInfo appInfo) {
17514         if (DEBUG_BACKUP) Slog.v(TAG_BACKUP, "unbindBackupAgent: " + appInfo);
17515         if (appInfo == null) {
17516             Slog.w(TAG, "unbind backup agent for null app");
17517             return;
17518         }
17519
17520         synchronized(this) {
17521             try {
17522                 if (mBackupAppName == null) {
17523                     Slog.w(TAG, "Unbinding backup agent with no active backup");
17524                     return;
17525                 }
17526
17527                 if (!mBackupAppName.equals(appInfo.packageName)) {
17528                     Slog.e(TAG, "Unbind of " + appInfo + " but is not the current backup target");
17529                     return;
17530                 }
17531
17532                 // Not backing this app up any more; reset its OOM adjustment
17533                 final ProcessRecord proc = mBackupTarget.app;
17534                 updateOomAdjLocked(proc);
17535
17536                 // If the app crashed during backup, 'thread' will be null here
17537                 if (proc.thread != null) {
17538                     try {
17539                         proc.thread.scheduleDestroyBackupAgent(appInfo,
17540                                 compatibilityInfoForPackageLocked(appInfo));
17541                     } catch (Exception e) {
17542                         Slog.e(TAG, "Exception when unbinding backup agent:");
17543                         e.printStackTrace();
17544                     }
17545                 }
17546             } finally {
17547                 mBackupTarget = null;
17548                 mBackupAppName = null;
17549             }
17550         }
17551     }
17552     // =========================================================
17553     // BROADCASTS
17554     // =========================================================
17555
17556     boolean isPendingBroadcastProcessLocked(int pid) {
17557         return mFgBroadcastQueue.isPendingBroadcastProcessLocked(pid)
17558                 || mBgBroadcastQueue.isPendingBroadcastProcessLocked(pid);
17559     }
17560
17561     void skipPendingBroadcastLocked(int pid) {
17562             Slog.w(TAG, "Unattached app died before broadcast acknowledged, skipping");
17563             for (BroadcastQueue queue : mBroadcastQueues) {
17564                 queue.skipPendingBroadcastLocked(pid);
17565             }
17566     }
17567
17568     // The app just attached; send any pending broadcasts that it should receive
17569     boolean sendPendingBroadcastsLocked(ProcessRecord app) {
17570         boolean didSomething = false;
17571         for (BroadcastQueue queue : mBroadcastQueues) {
17572             didSomething |= queue.sendPendingBroadcastsLocked(app);
17573         }
17574         return didSomething;
17575     }
17576
17577     public Intent registerReceiver(IApplicationThread caller, String callerPackage,
17578             IIntentReceiver receiver, IntentFilter filter, String permission, int userId) {
17579         enforceNotIsolatedCaller("registerReceiver");
17580         ArrayList<Intent> stickyIntents = null;
17581         ProcessRecord callerApp = null;
17582         int callingUid;
17583         int callingPid;
17584         synchronized(this) {
17585             if (caller != null) {
17586                 callerApp = getRecordForAppLocked(caller);
17587                 if (callerApp == null) {
17588                     throw new SecurityException(
17589                             "Unable to find app for caller " + caller
17590                             + " (pid=" + Binder.getCallingPid()
17591                             + ") when registering receiver " + receiver);
17592                 }
17593                 if (callerApp.info.uid != Process.SYSTEM_UID &&
17594                         !callerApp.pkgList.containsKey(callerPackage) &&
17595                         !"android".equals(callerPackage)) {
17596                     throw new SecurityException("Given caller package " + callerPackage
17597                             + " is not running in process " + callerApp);
17598                 }
17599                 callingUid = callerApp.info.uid;
17600                 callingPid = callerApp.pid;
17601             } else {
17602                 callerPackage = null;
17603                 callingUid = Binder.getCallingUid();
17604                 callingPid = Binder.getCallingPid();
17605             }
17606
17607             userId = mUserController.handleIncomingUser(callingPid, callingUid, userId, true,
17608                     ALLOW_FULL_ONLY, "registerReceiver", callerPackage);
17609
17610             Iterator<String> actions = filter.actionsIterator();
17611             if (actions == null) {
17612                 ArrayList<String> noAction = new ArrayList<String>(1);
17613                 noAction.add(null);
17614                 actions = noAction.iterator();
17615             }
17616
17617             // Collect stickies of users
17618             int[] userIds = { UserHandle.USER_ALL, UserHandle.getUserId(callingUid) };
17619             while (actions.hasNext()) {
17620                 String action = actions.next();
17621                 for (int id : userIds) {
17622                     ArrayMap<String, ArrayList<Intent>> stickies = mStickyBroadcasts.get(id);
17623                     if (stickies != null) {
17624                         ArrayList<Intent> intents = stickies.get(action);
17625                         if (intents != null) {
17626                             if (stickyIntents == null) {
17627                                 stickyIntents = new ArrayList<Intent>();
17628                             }
17629                             stickyIntents.addAll(intents);
17630                         }
17631                     }
17632                 }
17633             }
17634         }
17635
17636         ArrayList<Intent> allSticky = null;
17637         if (stickyIntents != null) {
17638             final ContentResolver resolver = mContext.getContentResolver();
17639             // Look for any matching sticky broadcasts...
17640             for (int i = 0, N = stickyIntents.size(); i < N; i++) {
17641                 Intent intent = stickyIntents.get(i);
17642                 // If intent has scheme "content", it will need to acccess
17643                 // provider that needs to lock mProviderMap in ActivityThread
17644                 // and also it may need to wait application response, so we
17645                 // cannot lock ActivityManagerService here.
17646                 if (filter.match(resolver, intent, true, TAG) >= 0) {
17647                     if (allSticky == null) {
17648                         allSticky = new ArrayList<Intent>();
17649                     }
17650                     allSticky.add(intent);
17651                 }
17652             }
17653         }
17654
17655         // The first sticky in the list is returned directly back to the client.
17656         Intent sticky = allSticky != null ? allSticky.get(0) : null;
17657         if (DEBUG_BROADCAST) Slog.v(TAG_BROADCAST, "Register receiver " + filter + ": " + sticky);
17658         if (receiver == null) {
17659             return sticky;
17660         }
17661
17662         synchronized (this) {
17663             if (callerApp != null && (callerApp.thread == null
17664                     || callerApp.thread.asBinder() != caller.asBinder())) {
17665                 // Original caller already died
17666                 return null;
17667             }
17668             ReceiverList rl = mRegisteredReceivers.get(receiver.asBinder());
17669             if (rl == null) {
17670                 rl = new ReceiverList(this, callerApp, callingPid, callingUid,
17671                         userId, receiver);
17672                 if (rl.app != null) {
17673                     rl.app.receivers.add(rl);
17674                 } else {
17675                     try {
17676                         receiver.asBinder().linkToDeath(rl, 0);
17677                     } catch (RemoteException e) {
17678                         return sticky;
17679                     }
17680                     rl.linkedToDeath = true;
17681                 }
17682                 mRegisteredReceivers.put(receiver.asBinder(), rl);
17683             } else if (rl.uid != callingUid) {
17684                 throw new IllegalArgumentException(
17685                         "Receiver requested to register for uid " + callingUid
17686                         + " was previously registered for uid " + rl.uid);
17687             } else if (rl.pid != callingPid) {
17688                 throw new IllegalArgumentException(
17689                         "Receiver requested to register for pid " + callingPid
17690                         + " was previously registered for pid " + rl.pid);
17691             } else if (rl.userId != userId) {
17692                 throw new IllegalArgumentException(
17693                         "Receiver requested to register for user " + userId
17694                         + " was previously registered for user " + rl.userId);
17695             }
17696             BroadcastFilter bf = new BroadcastFilter(filter, rl, callerPackage,
17697                     permission, callingUid, userId);
17698             rl.add(bf);
17699             if (!bf.debugCheck()) {
17700                 Slog.w(TAG, "==> For Dynamic broadcast");
17701             }
17702             mReceiverResolver.addFilter(bf);
17703
17704             // Enqueue broadcasts for all existing stickies that match
17705             // this filter.
17706             if (allSticky != null) {
17707                 ArrayList receivers = new ArrayList();
17708                 receivers.add(bf);
17709
17710                 final int stickyCount = allSticky.size();
17711                 for (int i = 0; i < stickyCount; i++) {
17712                     Intent intent = allSticky.get(i);
17713                     BroadcastQueue queue = broadcastQueueForIntent(intent);
17714                     BroadcastRecord r = new BroadcastRecord(queue, intent, null,
17715                             null, -1, -1, null, null, AppOpsManager.OP_NONE, null, receivers,
17716                             null, 0, null, null, false, true, true, -1);
17717                     queue.enqueueParallelBroadcastLocked(r);
17718                     queue.scheduleBroadcastsLocked();
17719                 }
17720             }
17721
17722             return sticky;
17723         }
17724     }
17725
17726     public void unregisterReceiver(IIntentReceiver receiver) {
17727         if (DEBUG_BROADCAST) Slog.v(TAG_BROADCAST, "Unregister receiver: " + receiver);
17728
17729         final long origId = Binder.clearCallingIdentity();
17730         try {
17731             boolean doTrim = false;
17732
17733             synchronized(this) {
17734                 ReceiverList rl = mRegisteredReceivers.get(receiver.asBinder());
17735                 if (rl != null) {
17736                     final BroadcastRecord r = rl.curBroadcast;
17737                     if (r != null && r == r.queue.getMatchingOrderedReceiver(r)) {
17738                         final boolean doNext = r.queue.finishReceiverLocked(
17739                                 r, r.resultCode, r.resultData, r.resultExtras,
17740                                 r.resultAbort, false);
17741                         if (doNext) {
17742                             doTrim = true;
17743                             r.queue.processNextBroadcast(false);
17744                         }
17745                     }
17746
17747                     if (rl.app != null) {
17748                         rl.app.receivers.remove(rl);
17749                     }
17750                     removeReceiverLocked(rl);
17751                     if (rl.linkedToDeath) {
17752                         rl.linkedToDeath = false;
17753                         rl.receiver.asBinder().unlinkToDeath(rl, 0);
17754                     }
17755                 }
17756             }
17757
17758             // If we actually concluded any broadcasts, we might now be able
17759             // to trim the recipients' apps from our working set
17760             if (doTrim) {
17761                 trimApplications();
17762                 return;
17763             }
17764
17765         } finally {
17766             Binder.restoreCallingIdentity(origId);
17767         }
17768     }
17769
17770     void removeReceiverLocked(ReceiverList rl) {
17771         mRegisteredReceivers.remove(rl.receiver.asBinder());
17772         for (int i = rl.size() - 1; i >= 0; i--) {
17773             mReceiverResolver.removeFilter(rl.get(i));
17774         }
17775     }
17776
17777     private final void sendPackageBroadcastLocked(int cmd, String[] packages, int userId) {
17778         for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) {
17779             ProcessRecord r = mLruProcesses.get(i);
17780             if (r.thread != null && (userId == UserHandle.USER_ALL || r.userId == userId)) {
17781                 try {
17782                     r.thread.dispatchPackageBroadcast(cmd, packages);
17783                 } catch (RemoteException ex) {
17784                 }
17785             }
17786         }
17787     }
17788
17789     private List<ResolveInfo> collectReceiverComponents(Intent intent, String resolvedType,
17790             int callingUid, int[] users) {
17791         // TODO: come back and remove this assumption to triage all broadcasts
17792         int pmFlags = STOCK_PM_FLAGS | MATCH_DEBUG_TRIAGED_MISSING;
17793
17794         List<ResolveInfo> receivers = null;
17795         try {
17796             HashSet<ComponentName> singleUserReceivers = null;
17797             boolean scannedFirstReceivers = false;
17798             for (int user : users) {
17799                 // Skip users that have Shell restrictions, with exception of always permitted
17800                 // Shell broadcasts
17801                 if (callingUid == Process.SHELL_UID
17802                         && mUserController.hasUserRestriction(
17803                                 UserManager.DISALLOW_DEBUGGING_FEATURES, user)
17804                         && !isPermittedShellBroadcast(intent)) {
17805                     continue;
17806                 }
17807                 List<ResolveInfo> newReceivers = AppGlobals.getPackageManager()
17808                         .queryIntentReceivers(intent, resolvedType, pmFlags, user).getList();
17809                 if (user != UserHandle.USER_SYSTEM && newReceivers != null) {
17810                     // If this is not the system user, we need to check for
17811                     // any receivers that should be filtered out.
17812                     for (int i=0; i<newReceivers.size(); i++) {
17813                         ResolveInfo ri = newReceivers.get(i);
17814                         if ((ri.activityInfo.flags&ActivityInfo.FLAG_SYSTEM_USER_ONLY) != 0) {
17815                             newReceivers.remove(i);
17816                             i--;
17817                         }
17818                     }
17819                 }
17820                 if (newReceivers != null && newReceivers.size() == 0) {
17821                     newReceivers = null;
17822                 }
17823                 if (receivers == null) {
17824                     receivers = newReceivers;
17825                 } else if (newReceivers != null) {
17826                     // We need to concatenate the additional receivers
17827                     // found with what we have do far.  This would be easy,
17828                     // but we also need to de-dup any receivers that are
17829                     // singleUser.
17830                     if (!scannedFirstReceivers) {
17831                         // Collect any single user receivers we had already retrieved.
17832                         scannedFirstReceivers = true;
17833                         for (int i=0; i<receivers.size(); i++) {
17834                             ResolveInfo ri = receivers.get(i);
17835                             if ((ri.activityInfo.flags&ActivityInfo.FLAG_SINGLE_USER) != 0) {
17836                                 ComponentName cn = new ComponentName(
17837                                         ri.activityInfo.packageName, ri.activityInfo.name);
17838                                 if (singleUserReceivers == null) {
17839                                     singleUserReceivers = new HashSet<ComponentName>();
17840                                 }
17841                                 singleUserReceivers.add(cn);
17842                             }
17843                         }
17844                     }
17845                     // Add the new results to the existing results, tracking
17846                     // and de-dupping single user receivers.
17847                     for (int i=0; i<newReceivers.size(); i++) {
17848                         ResolveInfo ri = newReceivers.get(i);
17849                         if ((ri.activityInfo.flags&ActivityInfo.FLAG_SINGLE_USER) != 0) {
17850                             ComponentName cn = new ComponentName(
17851                                     ri.activityInfo.packageName, ri.activityInfo.name);
17852                             if (singleUserReceivers == null) {
17853                                 singleUserReceivers = new HashSet<ComponentName>();
17854                             }
17855                             if (!singleUserReceivers.contains(cn)) {
17856                                 singleUserReceivers.add(cn);
17857                                 receivers.add(ri);
17858                             }
17859                         } else {
17860                             receivers.add(ri);
17861                         }
17862                     }
17863                 }
17864             }
17865         } catch (RemoteException ex) {
17866             // pm is in same process, this will never happen.
17867         }
17868         return receivers;
17869     }
17870
17871     private boolean isPermittedShellBroadcast(Intent intent) {
17872         // remote bugreport should always be allowed to be taken
17873         return INTENT_REMOTE_BUGREPORT_FINISHED.equals(intent.getAction());
17874     }
17875
17876     private void checkBroadcastFromSystem(Intent intent, ProcessRecord callerApp,
17877             String callerPackage, int callingUid, boolean isProtectedBroadcast, List receivers) {
17878         final String action = intent.getAction();
17879         if (isProtectedBroadcast
17880                 || Intent.ACTION_CLOSE_SYSTEM_DIALOGS.equals(action)
17881                 || Intent.ACTION_DISMISS_KEYBOARD_SHORTCUTS.equals(action)
17882                 || Intent.ACTION_MEDIA_BUTTON.equals(action)
17883                 || Intent.ACTION_MEDIA_SCANNER_SCAN_FILE.equals(action)
17884                 || Intent.ACTION_SHOW_KEYBOARD_SHORTCUTS.equals(action)
17885                 || Intent.ACTION_MASTER_CLEAR.equals(action)
17886                 || AppWidgetManager.ACTION_APPWIDGET_CONFIGURE.equals(action)
17887                 || AppWidgetManager.ACTION_APPWIDGET_UPDATE.equals(action)
17888                 || LocationManager.HIGH_POWER_REQUEST_CHANGE_ACTION.equals(action)
17889                 || TelephonyIntents.ACTION_REQUEST_OMADM_CONFIGURATION_UPDATE.equals(action)
17890                 || SuggestionSpan.ACTION_SUGGESTION_PICKED.equals(action)) {
17891             // Broadcast is either protected, or it's a public action that
17892             // we've relaxed, so it's fine for system internals to send.
17893             return;
17894         }
17895
17896         // This broadcast may be a problem...  but there are often system components that
17897         // want to send an internal broadcast to themselves, which is annoying to have to
17898         // explicitly list each action as a protected broadcast, so we will check for that
17899         // one safe case and allow it: an explicit broadcast, only being received by something
17900         // that has protected itself.
17901         if (receivers != null && receivers.size() > 0
17902                 && (intent.getPackage() != null || intent.getComponent() != null)) {
17903             boolean allProtected = true;
17904             for (int i = receivers.size()-1; i >= 0; i--) {
17905                 Object target = receivers.get(i);
17906                 if (target instanceof ResolveInfo) {
17907                     ResolveInfo ri = (ResolveInfo)target;
17908                     if (ri.activityInfo.exported && ri.activityInfo.permission == null) {
17909                         allProtected = false;
17910                         break;
17911                     }
17912                 } else {
17913                     BroadcastFilter bf = (BroadcastFilter)target;
17914                     if (bf.requiredPermission == null) {
17915                         allProtected = false;
17916                         break;
17917                     }
17918                 }
17919             }
17920             if (allProtected) {
17921                 // All safe!
17922                 return;
17923             }
17924         }
17925
17926         // The vast majority of broadcasts sent from system internals
17927         // should be protected to avoid security holes, so yell loudly
17928         // to ensure we examine these cases.
17929         if (callerApp != null) {
17930             Log.wtf(TAG, "Sending non-protected broadcast " + action
17931                             + " from system " + callerApp.toShortString() + " pkg " + callerPackage,
17932                     new Throwable());
17933         } else {
17934             Log.wtf(TAG, "Sending non-protected broadcast " + action
17935                             + " from system uid " + UserHandle.formatUid(callingUid)
17936                             + " pkg " + callerPackage,
17937                     new Throwable());
17938         }
17939     }
17940
17941     final int broadcastIntentLocked(ProcessRecord callerApp,
17942             String callerPackage, Intent intent, String resolvedType,
17943             IIntentReceiver resultTo, int resultCode, String resultData,
17944             Bundle resultExtras, String[] requiredPermissions, int appOp, Bundle bOptions,
17945             boolean ordered, boolean sticky, int callingPid, int callingUid, int userId) {
17946         intent = new Intent(intent);
17947
17948         // By default broadcasts do not go to stopped apps.
17949         intent.addFlags(Intent.FLAG_EXCLUDE_STOPPED_PACKAGES);
17950
17951         // If we have not finished booting, don't allow this to launch new processes.
17952         if (!mProcessesReady && (intent.getFlags()&Intent.FLAG_RECEIVER_BOOT_UPGRADE) == 0) {
17953             intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY);
17954         }
17955
17956         if (DEBUG_BROADCAST_LIGHT) Slog.v(TAG_BROADCAST,
17957                 (sticky ? "Broadcast sticky: ": "Broadcast: ") + intent
17958                 + " ordered=" + ordered + " userid=" + userId);
17959         if ((resultTo != null) && !ordered) {
17960             Slog.w(TAG, "Broadcast " + intent + " not ordered but result callback requested!");
17961         }
17962
17963         userId = mUserController.handleIncomingUser(callingPid, callingUid, userId, true,
17964                 ALLOW_NON_FULL, "broadcast", callerPackage);
17965
17966         // Make sure that the user who is receiving this broadcast is running.
17967         // If not, we will just skip it. Make an exception for shutdown broadcasts
17968         // and upgrade steps.
17969
17970         if (userId != UserHandle.USER_ALL && !mUserController.isUserRunningLocked(userId, 0)) {
17971             if ((callingUid != Process.SYSTEM_UID
17972                     || (intent.getFlags() & Intent.FLAG_RECEIVER_BOOT_UPGRADE) == 0)
17973                     && !Intent.ACTION_SHUTDOWN.equals(intent.getAction())) {
17974                 Slog.w(TAG, "Skipping broadcast of " + intent
17975                         + ": user " + userId + " is stopped");
17976                 return ActivityManager.BROADCAST_FAILED_USER_STOPPED;
17977             }
17978         }
17979
17980         BroadcastOptions brOptions = null;
17981         if (bOptions != null) {
17982             brOptions = new BroadcastOptions(bOptions);
17983             if (brOptions.getTemporaryAppWhitelistDuration() > 0) {
17984                 // See if the caller is allowed to do this.  Note we are checking against
17985                 // the actual real caller (not whoever provided the operation as say a
17986                 // PendingIntent), because that who is actually supplied the arguments.
17987                 if (checkComponentPermission(
17988                         android.Manifest.permission.CHANGE_DEVICE_IDLE_TEMP_WHITELIST,
17989                         Binder.getCallingPid(), Binder.getCallingUid(), -1, true)
17990                         != PackageManager.PERMISSION_GRANTED) {
17991                     String msg = "Permission Denial: " + intent.getAction()
17992                             + " broadcast from " + callerPackage + " (pid=" + callingPid
17993                             + ", uid=" + callingUid + ")"
17994                             + " requires "
17995                             + android.Manifest.permission.CHANGE_DEVICE_IDLE_TEMP_WHITELIST;
17996                     Slog.w(TAG, msg);
17997                     throw new SecurityException(msg);
17998                 }
17999             }
18000         }
18001
18002         // Verify that protected broadcasts are only being sent by system code,
18003         // and that system code is only sending protected broadcasts.
18004         final String action = intent.getAction();
18005         final boolean isProtectedBroadcast;
18006         try {
18007             isProtectedBroadcast = AppGlobals.getPackageManager().isProtectedBroadcast(action);
18008         } catch (RemoteException e) {
18009             Slog.w(TAG, "Remote exception", e);
18010             return ActivityManager.BROADCAST_SUCCESS;
18011         }
18012
18013         final boolean isCallerSystem;
18014         switch (UserHandle.getAppId(callingUid)) {
18015             case Process.ROOT_UID:
18016             case Process.SYSTEM_UID:
18017             case Process.PHONE_UID:
18018             case Process.BLUETOOTH_UID:
18019             case Process.NFC_UID:
18020                 isCallerSystem = true;
18021                 break;
18022             default:
18023                 isCallerSystem = (callerApp != null) && callerApp.persistent;
18024                 break;
18025         }
18026
18027         // First line security check before anything else: stop non-system apps from
18028         // sending protected broadcasts.
18029         if (!isCallerSystem) {
18030             if (isProtectedBroadcast) {
18031                 String msg = "Permission Denial: not allowed to send broadcast "
18032                         + action + " from pid="
18033                         + callingPid + ", uid=" + callingUid;
18034                 Slog.w(TAG, msg);
18035                 throw new SecurityException(msg);
18036
18037             } else if (AppWidgetManager.ACTION_APPWIDGET_CONFIGURE.equals(action)
18038                     || AppWidgetManager.ACTION_APPWIDGET_UPDATE.equals(action)) {
18039                 // Special case for compatibility: we don't want apps to send this,
18040                 // but historically it has not been protected and apps may be using it
18041                 // to poke their own app widget.  So, instead of making it protected,
18042                 // just limit it to the caller.
18043                 if (callerPackage == null) {
18044                     String msg = "Permission Denial: not allowed to send broadcast "
18045                             + action + " from unknown caller.";
18046                     Slog.w(TAG, msg);
18047                     throw new SecurityException(msg);
18048                 } else if (intent.getComponent() != null) {
18049                     // They are good enough to send to an explicit component...  verify
18050                     // it is being sent to the calling app.
18051                     if (!intent.getComponent().getPackageName().equals(
18052                             callerPackage)) {
18053                         String msg = "Permission Denial: not allowed to send broadcast "
18054                                 + action + " to "
18055                                 + intent.getComponent().getPackageName() + " from "
18056                                 + callerPackage;
18057                         Slog.w(TAG, msg);
18058                         throw new SecurityException(msg);
18059                     }
18060                 } else {
18061                     // Limit broadcast to their own package.
18062                     intent.setPackage(callerPackage);
18063                 }
18064             }
18065         }
18066
18067         if (action != null) {
18068             switch (action) {
18069                 case Intent.ACTION_UID_REMOVED:
18070                 case Intent.ACTION_PACKAGE_REMOVED:
18071                 case Intent.ACTION_PACKAGE_CHANGED:
18072                 case Intent.ACTION_EXTERNAL_APPLICATIONS_UNAVAILABLE:
18073                 case Intent.ACTION_EXTERNAL_APPLICATIONS_AVAILABLE:
18074                 case Intent.ACTION_PACKAGES_SUSPENDED:
18075                 case Intent.ACTION_PACKAGES_UNSUSPENDED:
18076                     // Handle special intents: if this broadcast is from the package
18077                     // manager about a package being removed, we need to remove all of
18078                     // its activities from the history stack.
18079                     if (checkComponentPermission(
18080                             android.Manifest.permission.BROADCAST_PACKAGE_REMOVED,
18081                             callingPid, callingUid, -1, true)
18082                             != PackageManager.PERMISSION_GRANTED) {
18083                         String msg = "Permission Denial: " + intent.getAction()
18084                                 + " broadcast from " + callerPackage + " (pid=" + callingPid
18085                                 + ", uid=" + callingUid + ")"
18086                                 + " requires "
18087                                 + android.Manifest.permission.BROADCAST_PACKAGE_REMOVED;
18088                         Slog.w(TAG, msg);
18089                         throw new SecurityException(msg);
18090                     }
18091                     switch (action) {
18092                         case Intent.ACTION_UID_REMOVED:
18093                             final Bundle intentExtras = intent.getExtras();
18094                             final int uid = intentExtras != null
18095                                     ? intentExtras.getInt(Intent.EXTRA_UID) : -1;
18096                             if (uid >= 0) {
18097                                 mBatteryStatsService.removeUid(uid);
18098                                 mAppOpsService.uidRemoved(uid);
18099                             }
18100                             break;
18101                         case Intent.ACTION_EXTERNAL_APPLICATIONS_UNAVAILABLE:
18102                             // If resources are unavailable just force stop all those packages
18103                             // and flush the attribute cache as well.
18104                             String list[] =
18105                                     intent.getStringArrayExtra(Intent.EXTRA_CHANGED_PACKAGE_LIST);
18106                             if (list != null && list.length > 0) {
18107                                 for (int i = 0; i < list.length; i++) {
18108                                     forceStopPackageLocked(list[i], -1, false, true, true,
18109                                             false, false, userId, "storage unmount");
18110                                 }
18111                                 mRecentTasks.cleanupLocked(UserHandle.USER_ALL);
18112                                 sendPackageBroadcastLocked(
18113                                         IApplicationThread.EXTERNAL_STORAGE_UNAVAILABLE, list,
18114                                         userId);
18115                             }
18116                             break;
18117                         case Intent.ACTION_EXTERNAL_APPLICATIONS_AVAILABLE:
18118                             mRecentTasks.cleanupLocked(UserHandle.USER_ALL);
18119                             break;
18120                         case Intent.ACTION_PACKAGE_REMOVED:
18121                         case Intent.ACTION_PACKAGE_CHANGED:
18122                             Uri data = intent.getData();
18123                             String ssp;
18124                             if (data != null && (ssp=data.getSchemeSpecificPart()) != null) {
18125                                 boolean removed = Intent.ACTION_PACKAGE_REMOVED.equals(action);
18126                                 final boolean replacing =
18127                                         intent.getBooleanExtra(Intent.EXTRA_REPLACING, false);
18128                                 final boolean killProcess =
18129                                         !intent.getBooleanExtra(Intent.EXTRA_DONT_KILL_APP, false);
18130                                 final boolean fullUninstall = removed && !replacing;
18131                                 if (removed) {
18132                                     if (killProcess) {
18133                                         forceStopPackageLocked(ssp, UserHandle.getAppId(
18134                                                 intent.getIntExtra(Intent.EXTRA_UID, -1)),
18135                                                 false, true, true, false, fullUninstall, userId,
18136                                                 removed ? "pkg removed" : "pkg changed");
18137                                     }
18138                                     final int cmd = killProcess
18139                                             ? IApplicationThread.PACKAGE_REMOVED
18140                                             : IApplicationThread.PACKAGE_REMOVED_DONT_KILL;
18141                                     sendPackageBroadcastLocked(cmd,
18142                                             new String[] {ssp}, userId);
18143                                     if (fullUninstall) {
18144                                         mAppOpsService.packageRemoved(
18145                                                 intent.getIntExtra(Intent.EXTRA_UID, -1), ssp);
18146
18147                                         // Remove all permissions granted from/to this package
18148                                         removeUriPermissionsForPackageLocked(ssp, userId, true);
18149
18150                                         removeTasksByPackageNameLocked(ssp, userId);
18151
18152                                         // Hide the "unsupported display" dialog if necessary.
18153                                         if (mUnsupportedDisplaySizeDialog != null && ssp.equals(
18154                                                 mUnsupportedDisplaySizeDialog.getPackageName())) {
18155                                             mUnsupportedDisplaySizeDialog.dismiss();
18156                                             mUnsupportedDisplaySizeDialog = null;
18157                                         }
18158                                         mCompatModePackages.handlePackageUninstalledLocked(ssp);
18159                                         mBatteryStatsService.notePackageUninstalled(ssp);
18160                                     }
18161                                 } else {
18162                                     if (killProcess) {
18163                                         killPackageProcessesLocked(ssp, UserHandle.getAppId(
18164                                                 intent.getIntExtra(Intent.EXTRA_UID, -1)),
18165                                                 userId, ProcessList.INVALID_ADJ,
18166                                                 false, true, true, false, "change " + ssp);
18167                                     }
18168                                     cleanupDisabledPackageComponentsLocked(ssp, userId, killProcess,
18169                                             intent.getStringArrayExtra(
18170                                                     Intent.EXTRA_CHANGED_COMPONENT_NAME_LIST));
18171                                 }
18172                             }
18173                             break;
18174                         case Intent.ACTION_PACKAGES_SUSPENDED:
18175                         case Intent.ACTION_PACKAGES_UNSUSPENDED:
18176                             final boolean suspended = Intent.ACTION_PACKAGES_SUSPENDED.equals(
18177                                     intent.getAction());
18178                             final String[] packageNames = intent.getStringArrayExtra(
18179                                     Intent.EXTRA_CHANGED_PACKAGE_LIST);
18180                             final int userHandle = intent.getIntExtra(
18181                                     Intent.EXTRA_USER_HANDLE, UserHandle.USER_NULL);
18182
18183                             synchronized(ActivityManagerService.this) {
18184                                 mRecentTasks.onPackagesSuspendedChanged(
18185                                         packageNames, suspended, userHandle);
18186                             }
18187                             break;
18188                     }
18189                     break;
18190                 case Intent.ACTION_PACKAGE_REPLACED:
18191                 {
18192                     final Uri data = intent.getData();
18193                     final String ssp;
18194                     if (data != null && (ssp = data.getSchemeSpecificPart()) != null) {
18195                         final ApplicationInfo aInfo =
18196                                 getPackageManagerInternalLocked().getApplicationInfo(
18197                                         ssp,
18198                                         userId);
18199                         if (aInfo == null) {
18200                             Slog.w(TAG, "Dropping ACTION_PACKAGE_REPLACED for non-existent pkg:"
18201                                     + " ssp=" + ssp + " data=" + data);
18202                             return ActivityManager.BROADCAST_SUCCESS;
18203                         }
18204                         mStackSupervisor.updateActivityApplicationInfoLocked(aInfo);
18205                         sendPackageBroadcastLocked(IApplicationThread.PACKAGE_REPLACED,
18206                                 new String[] {ssp}, userId);
18207                     }
18208                     break;
18209                 }
18210                 case Intent.ACTION_PACKAGE_ADDED:
18211                 {
18212                     // Special case for adding a package: by default turn on compatibility mode.
18213                     Uri data = intent.getData();
18214                     String ssp;
18215                     if (data != null && (ssp = data.getSchemeSpecificPart()) != null) {
18216                         final boolean replacing =
18217                                 intent.getBooleanExtra(Intent.EXTRA_REPLACING, false);
18218                         mCompatModePackages.handlePackageAddedLocked(ssp, replacing);
18219
18220                         try {
18221                             ApplicationInfo ai = AppGlobals.getPackageManager().
18222                                     getApplicationInfo(ssp, 0, 0);
18223                             mBatteryStatsService.notePackageInstalled(ssp,
18224                                     ai != null ? ai.versionCode : 0);
18225                         } catch (RemoteException e) {
18226                         }
18227                     }
18228                     break;
18229                 }
18230                 case Intent.ACTION_PACKAGE_DATA_CLEARED:
18231                 {
18232                     Uri data = intent.getData();
18233                     String ssp;
18234                     if (data != null && (ssp = data.getSchemeSpecificPart()) != null) {
18235                         // Hide the "unsupported display" dialog if necessary.
18236                         if (mUnsupportedDisplaySizeDialog != null && ssp.equals(
18237                                 mUnsupportedDisplaySizeDialog.getPackageName())) {
18238                             mUnsupportedDisplaySizeDialog.dismiss();
18239                             mUnsupportedDisplaySizeDialog = null;
18240                         }
18241                         mCompatModePackages.handlePackageDataClearedLocked(ssp);
18242                     }
18243                     break;
18244                 }
18245                 case Intent.ACTION_TIMEZONE_CHANGED:
18246                     // If this is the time zone changed action, queue up a message that will reset
18247                     // the timezone of all currently running processes. This message will get
18248                     // queued up before the broadcast happens.
18249                     mHandler.sendEmptyMessage(UPDATE_TIME_ZONE);
18250                     break;
18251                 case Intent.ACTION_TIME_CHANGED:
18252                     // If the user set the time, let all running processes know.
18253                     final int is24Hour =
18254                             intent.getBooleanExtra(Intent.EXTRA_TIME_PREF_24_HOUR_FORMAT, false) ? 1
18255                                     : 0;
18256                     mHandler.sendMessage(mHandler.obtainMessage(UPDATE_TIME, is24Hour, 0));
18257                     BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
18258                     synchronized (stats) {
18259                         stats.noteCurrentTimeChangedLocked();
18260                     }
18261                     break;
18262                 case Intent.ACTION_CLEAR_DNS_CACHE:
18263                     mHandler.sendEmptyMessage(CLEAR_DNS_CACHE_MSG);
18264                     break;
18265                 case Proxy.PROXY_CHANGE_ACTION:
18266                     ProxyInfo proxy = intent.getParcelableExtra(Proxy.EXTRA_PROXY_INFO);
18267                     mHandler.sendMessage(mHandler.obtainMessage(UPDATE_HTTP_PROXY_MSG, proxy));
18268                     break;
18269                 case android.hardware.Camera.ACTION_NEW_PICTURE:
18270                 case android.hardware.Camera.ACTION_NEW_VIDEO:
18271                     // These broadcasts are no longer allowed by the system, since they can
18272                     // cause significant thrashing at a crictical point (using the camera).
18273                     // Apps should use JobScehduler to monitor for media provider changes.
18274                     Slog.w(TAG, action + " no longer allowed; dropping from "
18275                             + UserHandle.formatUid(callingUid));
18276                     if (resultTo != null) {
18277                         final BroadcastQueue queue = broadcastQueueForIntent(intent);
18278                         try {
18279                             queue.performReceiveLocked(callerApp, resultTo, intent,
18280                                     Activity.RESULT_CANCELED, null, null,
18281                                     false, false, userId);
18282                         } catch (RemoteException e) {
18283                             Slog.w(TAG, "Failure ["
18284                                     + queue.mQueueName + "] sending broadcast result of "
18285                                     + intent, e);
18286
18287                         }
18288                     }
18289                     // Lie; we don't want to crash the app.
18290                     return ActivityManager.BROADCAST_SUCCESS;
18291             }
18292         }
18293
18294         // Add to the sticky list if requested.
18295         if (sticky) {
18296             if (checkPermission(android.Manifest.permission.BROADCAST_STICKY,
18297                     callingPid, callingUid)
18298                     != PackageManager.PERMISSION_GRANTED) {
18299                 String msg = "Permission Denial: broadcastIntent() requesting a sticky broadcast from pid="
18300                         + callingPid + ", uid=" + callingUid
18301                         + " requires " + android.Manifest.permission.BROADCAST_STICKY;
18302                 Slog.w(TAG, msg);
18303                 throw new SecurityException(msg);
18304             }
18305             if (requiredPermissions != null && requiredPermissions.length > 0) {
18306                 Slog.w(TAG, "Can't broadcast sticky intent " + intent
18307                         + " and enforce permissions " + Arrays.toString(requiredPermissions));
18308                 return ActivityManager.BROADCAST_STICKY_CANT_HAVE_PERMISSION;
18309             }
18310             if (intent.getComponent() != null) {
18311                 throw new SecurityException(
18312                         "Sticky broadcasts can't target a specific component");
18313             }
18314             // We use userId directly here, since the "all" target is maintained
18315             // as a separate set of sticky broadcasts.
18316             if (userId != UserHandle.USER_ALL) {
18317                 // But first, if this is not a broadcast to all users, then
18318                 // make sure it doesn't conflict with an existing broadcast to
18319                 // all users.
18320                 ArrayMap<String, ArrayList<Intent>> stickies = mStickyBroadcasts.get(
18321                         UserHandle.USER_ALL);
18322                 if (stickies != null) {
18323                     ArrayList<Intent> list = stickies.get(intent.getAction());
18324                     if (list != null) {
18325                         int N = list.size();
18326                         int i;
18327                         for (i=0; i<N; i++) {
18328                             if (intent.filterEquals(list.get(i))) {
18329                                 throw new IllegalArgumentException(
18330                                         "Sticky broadcast " + intent + " for user "
18331                                         + userId + " conflicts with existing global broadcast");
18332                             }
18333                         }
18334                     }
18335                 }
18336             }
18337             ArrayMap<String, ArrayList<Intent>> stickies = mStickyBroadcasts.get(userId);
18338             if (stickies == null) {
18339                 stickies = new ArrayMap<>();
18340                 mStickyBroadcasts.put(userId, stickies);
18341             }
18342             ArrayList<Intent> list = stickies.get(intent.getAction());
18343             if (list == null) {
18344                 list = new ArrayList<>();
18345                 stickies.put(intent.getAction(), list);
18346             }
18347             final int stickiesCount = list.size();
18348             int i;
18349             for (i = 0; i < stickiesCount; i++) {
18350                 if (intent.filterEquals(list.get(i))) {
18351                     // This sticky already exists, replace it.
18352                     list.set(i, new Intent(intent));
18353                     break;
18354                 }
18355             }
18356             if (i >= stickiesCount) {
18357                 list.add(new Intent(intent));
18358             }
18359         }
18360
18361         int[] users;
18362         if (userId == UserHandle.USER_ALL) {
18363             // Caller wants broadcast to go to all started users.
18364             users = mUserController.getStartedUserArrayLocked();
18365         } else {
18366             // Caller wants broadcast to go to one specific user.
18367             users = new int[] {userId};
18368         }
18369
18370         // Figure out who all will receive this broadcast.
18371         List receivers = null;
18372         List<BroadcastFilter> registeredReceivers = null;
18373         // Need to resolve the intent to interested receivers...
18374         if ((intent.getFlags()&Intent.FLAG_RECEIVER_REGISTERED_ONLY)
18375                  == 0) {
18376             receivers = collectReceiverComponents(intent, resolvedType, callingUid, users);
18377         }
18378         if (intent.getComponent() == null) {
18379             if (userId == UserHandle.USER_ALL && callingUid == Process.SHELL_UID) {
18380                 // Query one target user at a time, excluding shell-restricted users
18381                 for (int i = 0; i < users.length; i++) {
18382                     if (mUserController.hasUserRestriction(
18383                             UserManager.DISALLOW_DEBUGGING_FEATURES, users[i])) {
18384                         continue;
18385                     }
18386                     List<BroadcastFilter> registeredReceiversForUser =
18387                             mReceiverResolver.queryIntent(intent,
18388                                     resolvedType, false, users[i]);
18389                     if (registeredReceivers == null) {
18390                         registeredReceivers = registeredReceiversForUser;
18391                     } else if (registeredReceiversForUser != null) {
18392                         registeredReceivers.addAll(registeredReceiversForUser);
18393                     }
18394                 }
18395             } else {
18396                 registeredReceivers = mReceiverResolver.queryIntent(intent,
18397                         resolvedType, false, userId);
18398             }
18399         }
18400
18401         final boolean replacePending =
18402                 (intent.getFlags()&Intent.FLAG_RECEIVER_REPLACE_PENDING) != 0;
18403
18404         if (DEBUG_BROADCAST) Slog.v(TAG_BROADCAST, "Enqueing broadcast: " + intent.getAction()
18405                 + " replacePending=" + replacePending);
18406
18407         int NR = registeredReceivers != null ? registeredReceivers.size() : 0;
18408         if (!ordered && NR > 0) {
18409             // If we are not serializing this broadcast, then send the
18410             // registered receivers separately so they don't wait for the
18411             // components to be launched.
18412             if (isCallerSystem) {
18413                 checkBroadcastFromSystem(intent, callerApp, callerPackage, callingUid,
18414                         isProtectedBroadcast, registeredReceivers);
18415             }
18416             final BroadcastQueue queue = broadcastQueueForIntent(intent);
18417             BroadcastRecord r = new BroadcastRecord(queue, intent, callerApp,
18418                     callerPackage, callingPid, callingUid, resolvedType, requiredPermissions,
18419                     appOp, brOptions, registeredReceivers, resultTo, resultCode, resultData,
18420                     resultExtras, ordered, sticky, false, userId);
18421             if (DEBUG_BROADCAST) Slog.v(TAG_BROADCAST, "Enqueueing parallel broadcast " + r);
18422             final boolean replaced = replacePending && queue.replaceParallelBroadcastLocked(r);
18423             if (!replaced) {
18424                 queue.enqueueParallelBroadcastLocked(r);
18425                 queue.scheduleBroadcastsLocked();
18426             }
18427             registeredReceivers = null;
18428             NR = 0;
18429         }
18430
18431         // Merge into one list.
18432         int ir = 0;
18433         if (receivers != null) {
18434             // A special case for PACKAGE_ADDED: do not allow the package
18435             // being added to see this broadcast.  This prevents them from
18436             // using this as a back door to get run as soon as they are
18437             // installed.  Maybe in the future we want to have a special install
18438             // broadcast or such for apps, but we'd like to deliberately make
18439             // this decision.
18440             String skipPackages[] = null;
18441             if (Intent.ACTION_PACKAGE_ADDED.equals(intent.getAction())
18442                     || Intent.ACTION_PACKAGE_RESTARTED.equals(intent.getAction())
18443                     || Intent.ACTION_PACKAGE_DATA_CLEARED.equals(intent.getAction())) {
18444                 Uri data = intent.getData();
18445                 if (data != null) {
18446                     String pkgName = data.getSchemeSpecificPart();
18447                     if (pkgName != null) {
18448                         skipPackages = new String[] { pkgName };
18449                     }
18450                 }
18451             } else if (Intent.ACTION_EXTERNAL_APPLICATIONS_AVAILABLE.equals(intent.getAction())) {
18452                 skipPackages = intent.getStringArrayExtra(Intent.EXTRA_CHANGED_PACKAGE_LIST);
18453             }
18454             if (skipPackages != null && (skipPackages.length > 0)) {
18455                 for (String skipPackage : skipPackages) {
18456                     if (skipPackage != null) {
18457                         int NT = receivers.size();
18458                         for (int it=0; it<NT; it++) {
18459                             ResolveInfo curt = (ResolveInfo)receivers.get(it);
18460                             if (curt.activityInfo.packageName.equals(skipPackage)) {
18461                                 receivers.remove(it);
18462                                 it--;
18463                                 NT--;
18464                             }
18465                         }
18466                     }
18467                 }
18468             }
18469
18470             int NT = receivers != null ? receivers.size() : 0;
18471             int it = 0;
18472             ResolveInfo curt = null;
18473             BroadcastFilter curr = null;
18474             while (it < NT && ir < NR) {
18475                 if (curt == null) {
18476                     curt = (ResolveInfo)receivers.get(it);
18477                 }
18478                 if (curr == null) {
18479                     curr = registeredReceivers.get(ir);
18480                 }
18481                 if (curr.getPriority() >= curt.priority) {
18482                     // Insert this broadcast record into the final list.
18483                     receivers.add(it, curr);
18484                     ir++;
18485                     curr = null;
18486                     it++;
18487                     NT++;
18488                 } else {
18489                     // Skip to the next ResolveInfo in the final list.
18490                     it++;
18491                     curt = null;
18492                 }
18493             }
18494         }
18495         while (ir < NR) {
18496             if (receivers == null) {
18497                 receivers = new ArrayList();
18498             }
18499             receivers.add(registeredReceivers.get(ir));
18500             ir++;
18501         }
18502
18503         if (isCallerSystem) {
18504             checkBroadcastFromSystem(intent, callerApp, callerPackage, callingUid,
18505                     isProtectedBroadcast, receivers);
18506         }
18507
18508         if ((receivers != null && receivers.size() > 0)
18509                 || resultTo != null) {
18510             BroadcastQueue queue = broadcastQueueForIntent(intent);
18511             BroadcastRecord r = new BroadcastRecord(queue, intent, callerApp,
18512                     callerPackage, callingPid, callingUid, resolvedType,
18513                     requiredPermissions, appOp, brOptions, receivers, resultTo, resultCode,
18514                     resultData, resultExtras, ordered, sticky, false, userId);
18515
18516             if (DEBUG_BROADCAST) Slog.v(TAG_BROADCAST, "Enqueueing ordered broadcast " + r
18517                     + ": prev had " + queue.mOrderedBroadcasts.size());
18518             if (DEBUG_BROADCAST) Slog.i(TAG_BROADCAST,
18519                     "Enqueueing broadcast " + r.intent.getAction());
18520
18521             boolean replaced = replacePending && queue.replaceOrderedBroadcastLocked(r);
18522             if (!replaced) {
18523                 queue.enqueueOrderedBroadcastLocked(r);
18524                 queue.scheduleBroadcastsLocked();
18525             }
18526         } else {
18527             // There was nobody interested in the broadcast, but we still want to record
18528             // that it happened.
18529             if (intent.getComponent() == null && intent.getPackage() == null
18530                     && (intent.getFlags()&Intent.FLAG_RECEIVER_REGISTERED_ONLY) == 0) {
18531                 // This was an implicit broadcast... let's record it for posterity.
18532                 addBroadcastStatLocked(intent.getAction(), callerPackage, 0, 0, 0);
18533             }
18534         }
18535
18536         return ActivityManager.BROADCAST_SUCCESS;
18537     }
18538
18539     final void addBroadcastStatLocked(String action, String srcPackage, int receiveCount,
18540             int skipCount, long dispatchTime) {
18541         final long now = SystemClock.elapsedRealtime();
18542         if (mCurBroadcastStats == null ||
18543                 (mCurBroadcastStats.mStartRealtime +(24*60*60*1000) < now)) {
18544             mLastBroadcastStats = mCurBroadcastStats;
18545             if (mLastBroadcastStats != null) {
18546                 mLastBroadcastStats.mEndRealtime = SystemClock.elapsedRealtime();
18547                 mLastBroadcastStats.mEndUptime = SystemClock.uptimeMillis();
18548             }
18549             mCurBroadcastStats = new BroadcastStats();
18550         }
18551         mCurBroadcastStats.addBroadcast(action, srcPackage, receiveCount, skipCount, dispatchTime);
18552     }
18553
18554     final Intent verifyBroadcastLocked(Intent intent) {
18555         // Refuse possible leaked file descriptors
18556         if (intent != null && intent.hasFileDescriptors() == true) {
18557             throw new IllegalArgumentException("File descriptors passed in Intent");
18558         }
18559
18560         int flags = intent.getFlags();
18561
18562         if (!mProcessesReady) {
18563             // if the caller really truly claims to know what they're doing, go
18564             // ahead and allow the broadcast without launching any receivers
18565             if ((flags&Intent.FLAG_RECEIVER_REGISTERED_ONLY_BEFORE_BOOT) != 0) {
18566                 // This will be turned into a FLAG_RECEIVER_REGISTERED_ONLY later on if needed.
18567             } else if ((flags&Intent.FLAG_RECEIVER_REGISTERED_ONLY) == 0) {
18568                 Slog.e(TAG, "Attempt to launch receivers of broadcast intent " + intent
18569                         + " before boot completion");
18570                 throw new IllegalStateException("Cannot broadcast before boot completed");
18571             }
18572         }
18573
18574         if ((flags&Intent.FLAG_RECEIVER_BOOT_UPGRADE) != 0) {
18575             throw new IllegalArgumentException(
18576                     "Can't use FLAG_RECEIVER_BOOT_UPGRADE here");
18577         }
18578
18579         return intent;
18580     }
18581
18582     public final int broadcastIntent(IApplicationThread caller,
18583             Intent intent, String resolvedType, IIntentReceiver resultTo,
18584             int resultCode, String resultData, Bundle resultExtras,
18585             String[] requiredPermissions, int appOp, Bundle bOptions,
18586             boolean serialized, boolean sticky, int userId) {
18587         enforceNotIsolatedCaller("broadcastIntent");
18588         synchronized(this) {
18589             intent = verifyBroadcastLocked(intent);
18590
18591             final ProcessRecord callerApp = getRecordForAppLocked(caller);
18592             final int callingPid = Binder.getCallingPid();
18593             final int callingUid = Binder.getCallingUid();
18594             final long origId = Binder.clearCallingIdentity();
18595             int res = broadcastIntentLocked(callerApp,
18596                     callerApp != null ? callerApp.info.packageName : null,
18597                     intent, resolvedType, resultTo, resultCode, resultData, resultExtras,
18598                     requiredPermissions, appOp, bOptions, serialized, sticky,
18599                     callingPid, callingUid, userId);
18600             Binder.restoreCallingIdentity(origId);
18601             return res;
18602         }
18603     }
18604
18605
18606     int broadcastIntentInPackage(String packageName, int uid,
18607             Intent intent, String resolvedType, IIntentReceiver resultTo,
18608             int resultCode, String resultData, Bundle resultExtras,
18609             String requiredPermission, Bundle bOptions, boolean serialized, boolean sticky,
18610             int userId) {
18611         synchronized(this) {
18612             intent = verifyBroadcastLocked(intent);
18613
18614             final long origId = Binder.clearCallingIdentity();
18615             String[] requiredPermissions = requiredPermission == null ? null
18616                     : new String[] {requiredPermission};
18617             int res = broadcastIntentLocked(null, packageName, intent, resolvedType,
18618                     resultTo, resultCode, resultData, resultExtras,
18619                     requiredPermissions, AppOpsManager.OP_NONE, bOptions, serialized,
18620                     sticky, -1, uid, userId);
18621             Binder.restoreCallingIdentity(origId);
18622             return res;
18623         }
18624     }
18625
18626     public final void unbroadcastIntent(IApplicationThread caller, Intent intent, int userId) {
18627         // Refuse possible leaked file descriptors
18628         if (intent != null && intent.hasFileDescriptors() == true) {
18629             throw new IllegalArgumentException("File descriptors passed in Intent");
18630         }
18631
18632         userId = mUserController.handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(),
18633                 userId, true, ALLOW_NON_FULL, "removeStickyBroadcast", null);
18634
18635         synchronized(this) {
18636             if (checkCallingPermission(android.Manifest.permission.BROADCAST_STICKY)
18637                     != PackageManager.PERMISSION_GRANTED) {
18638                 String msg = "Permission Denial: unbroadcastIntent() from pid="
18639                         + Binder.getCallingPid()
18640                         + ", uid=" + Binder.getCallingUid()
18641                         + " requires " + android.Manifest.permission.BROADCAST_STICKY;
18642                 Slog.w(TAG, msg);
18643                 throw new SecurityException(msg);
18644             }
18645             ArrayMap<String, ArrayList<Intent>> stickies = mStickyBroadcasts.get(userId);
18646             if (stickies != null) {
18647                 ArrayList<Intent> list = stickies.get(intent.getAction());
18648                 if (list != null) {
18649                     int N = list.size();
18650                     int i;
18651                     for (i=0; i<N; i++) {
18652                         if (intent.filterEquals(list.get(i))) {
18653                             list.remove(i);
18654                             break;
18655                         }
18656                     }
18657                     if (list.size() <= 0) {
18658                         stickies.remove(intent.getAction());
18659                     }
18660                 }
18661                 if (stickies.size() <= 0) {
18662                     mStickyBroadcasts.remove(userId);
18663                 }
18664             }
18665         }
18666     }
18667
18668     void backgroundServicesFinishedLocked(int userId) {
18669         for (BroadcastQueue queue : mBroadcastQueues) {
18670             queue.backgroundServicesFinishedLocked(userId);
18671         }
18672     }
18673
18674     public void finishReceiver(IBinder who, int resultCode, String resultData,
18675             Bundle resultExtras, boolean resultAbort, int flags) {
18676         if (DEBUG_BROADCAST) Slog.v(TAG_BROADCAST, "Finish receiver: " + who);
18677
18678         // Refuse possible leaked file descriptors
18679         if (resultExtras != null && resultExtras.hasFileDescriptors()) {
18680             throw new IllegalArgumentException("File descriptors passed in Bundle");
18681         }
18682
18683         final long origId = Binder.clearCallingIdentity();
18684         try {
18685             boolean doNext = false;
18686             BroadcastRecord r;
18687
18688             synchronized(this) {
18689                 BroadcastQueue queue = (flags & Intent.FLAG_RECEIVER_FOREGROUND) != 0
18690                         ? mFgBroadcastQueue : mBgBroadcastQueue;
18691                 r = queue.getMatchingOrderedReceiver(who);
18692                 if (r != null) {
18693                     doNext = r.queue.finishReceiverLocked(r, resultCode,
18694                         resultData, resultExtras, resultAbort, true);
18695                 }
18696             }
18697
18698             if (doNext) {
18699                 r.queue.processNextBroadcast(false);
18700             }
18701             trimApplications();
18702         } finally {
18703             Binder.restoreCallingIdentity(origId);
18704         }
18705     }
18706
18707     // =========================================================
18708     // INSTRUMENTATION
18709     // =========================================================
18710
18711     public boolean startInstrumentation(ComponentName className,
18712             String profileFile, int flags, Bundle arguments,
18713             IInstrumentationWatcher watcher, IUiAutomationConnection uiAutomationConnection,
18714             int userId, String abiOverride) {
18715         enforceNotIsolatedCaller("startInstrumentation");
18716         userId = mUserController.handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(),
18717                 userId, false, ALLOW_FULL_ONLY, "startInstrumentation", null);
18718         // Refuse possible leaked file descriptors
18719         if (arguments != null && arguments.hasFileDescriptors()) {
18720             throw new IllegalArgumentException("File descriptors passed in Bundle");
18721         }
18722
18723         synchronized(this) {
18724             InstrumentationInfo ii = null;
18725             ApplicationInfo ai = null;
18726             try {
18727                 ii = mContext.getPackageManager().getInstrumentationInfo(
18728                     className, STOCK_PM_FLAGS);
18729                 ai = AppGlobals.getPackageManager().getApplicationInfo(
18730                         ii.targetPackage, STOCK_PM_FLAGS, userId);
18731             } catch (PackageManager.NameNotFoundException e) {
18732             } catch (RemoteException e) {
18733             }
18734             if (ii == null) {
18735                 reportStartInstrumentationFailureLocked(watcher, className,
18736                         "Unable to find instrumentation info for: " + className);
18737                 return false;
18738             }
18739             if (ai == null) {
18740                 reportStartInstrumentationFailureLocked(watcher, className,
18741                         "Unable to find instrumentation target package: " + ii.targetPackage);
18742                 return false;
18743             }
18744             if (!ai.hasCode()) {
18745                 reportStartInstrumentationFailureLocked(watcher, className,
18746                         "Instrumentation target has no code: " + ii.targetPackage);
18747                 return false;
18748             }
18749
18750             int match = mContext.getPackageManager().checkSignatures(
18751                     ii.targetPackage, ii.packageName);
18752             if (match < 0 && match != PackageManager.SIGNATURE_FIRST_NOT_SIGNED) {
18753                 String msg = "Permission Denial: starting instrumentation "
18754                         + className + " from pid="
18755                         + Binder.getCallingPid()
18756                         + ", uid=" + Binder.getCallingPid()
18757                         + " not allowed because package " + ii.packageName
18758                         + " does not have a signature matching the target "
18759                         + ii.targetPackage;
18760                 reportStartInstrumentationFailureLocked(watcher, className, msg);
18761                 throw new SecurityException(msg);
18762             }
18763
18764             final long origId = Binder.clearCallingIdentity();
18765             // Instrumentation can kill and relaunch even persistent processes
18766             forceStopPackageLocked(ii.targetPackage, -1, true, false, true, true, false, userId,
18767                     "start instr");
18768             ProcessRecord app = addAppLocked(ai, false, abiOverride);
18769             app.instrumentationClass = className;
18770             app.instrumentationInfo = ai;
18771             app.instrumentationProfileFile = profileFile;
18772             app.instrumentationArguments = arguments;
18773             app.instrumentationWatcher = watcher;
18774             app.instrumentationUiAutomationConnection = uiAutomationConnection;
18775             app.instrumentationResultClass = className;
18776             Binder.restoreCallingIdentity(origId);
18777         }
18778
18779         return true;
18780     }
18781
18782     /**
18783      * Report errors that occur while attempting to start Instrumentation.  Always writes the
18784      * error to the logs, but if somebody is watching, send the report there too.  This enables
18785      * the "am" command to report errors with more information.
18786      *
18787      * @param watcher The IInstrumentationWatcher.  Null if there isn't one.
18788      * @param cn The component name of the instrumentation.
18789      * @param report The error report.
18790      */
18791     private void reportStartInstrumentationFailureLocked(IInstrumentationWatcher watcher,
18792             ComponentName cn, String report) {
18793         Slog.w(TAG, report);
18794         if (watcher != null) {
18795             Bundle results = new Bundle();
18796             results.putString(Instrumentation.REPORT_KEY_IDENTIFIER, "ActivityManagerService");
18797             results.putString("Error", report);
18798             mInstrumentationReporter.reportStatus(watcher, cn, -1, results);
18799         }
18800     }
18801
18802     void finishInstrumentationLocked(ProcessRecord app, int resultCode, Bundle results) {
18803         if (app.instrumentationWatcher != null) {
18804             mInstrumentationReporter.reportFinished(app.instrumentationWatcher,
18805                     app.instrumentationClass, resultCode, results);
18806         }
18807
18808         // Can't call out of the system process with a lock held, so post a message.
18809         if (app.instrumentationUiAutomationConnection != null) {
18810             mHandler.obtainMessage(SHUTDOWN_UI_AUTOMATION_CONNECTION_MSG,
18811                     app.instrumentationUiAutomationConnection).sendToTarget();
18812         }
18813
18814         app.instrumentationWatcher = null;
18815         app.instrumentationUiAutomationConnection = null;
18816         app.instrumentationClass = null;
18817         app.instrumentationInfo = null;
18818         app.instrumentationProfileFile = null;
18819         app.instrumentationArguments = null;
18820
18821         forceStopPackageLocked(app.info.packageName, -1, false, false, true, true, false, app.userId,
18822                 "finished inst");
18823     }
18824
18825     public void finishInstrumentation(IApplicationThread target,
18826             int resultCode, Bundle results) {
18827         int userId = UserHandle.getCallingUserId();
18828         // Refuse possible leaked file descriptors
18829         if (results != null && results.hasFileDescriptors()) {
18830             throw new IllegalArgumentException("File descriptors passed in Intent");
18831         }
18832
18833         synchronized(this) {
18834             ProcessRecord app = getRecordForAppLocked(target);
18835             if (app == null) {
18836                 Slog.w(TAG, "finishInstrumentation: no app for " + target);
18837                 return;
18838             }
18839             final long origId = Binder.clearCallingIdentity();
18840             finishInstrumentationLocked(app, resultCode, results);
18841             Binder.restoreCallingIdentity(origId);
18842         }
18843     }
18844
18845     // =========================================================
18846     // CONFIGURATION
18847     // =========================================================
18848
18849     public ConfigurationInfo getDeviceConfigurationInfo() {
18850         ConfigurationInfo config = new ConfigurationInfo();
18851         synchronized (this) {
18852             config.reqTouchScreen = mConfiguration.touchscreen;
18853             config.reqKeyboardType = mConfiguration.keyboard;
18854             config.reqNavigation = mConfiguration.navigation;
18855             if (mConfiguration.navigation == Configuration.NAVIGATION_DPAD
18856                     || mConfiguration.navigation == Configuration.NAVIGATION_TRACKBALL) {
18857                 config.reqInputFeatures |= ConfigurationInfo.INPUT_FEATURE_FIVE_WAY_NAV;
18858             }
18859             if (mConfiguration.keyboard != Configuration.KEYBOARD_UNDEFINED
18860                     && mConfiguration.keyboard != Configuration.KEYBOARD_NOKEYS) {
18861                 config.reqInputFeatures |= ConfigurationInfo.INPUT_FEATURE_HARD_KEYBOARD;
18862             }
18863             config.reqGlEsVersion = GL_ES_VERSION;
18864         }
18865         return config;
18866     }
18867
18868     ActivityStack getFocusedStack() {
18869         return mStackSupervisor.getFocusedStack();
18870     }
18871
18872     @Override
18873     public int getFocusedStackId() throws RemoteException {
18874         ActivityStack focusedStack = getFocusedStack();
18875         if (focusedStack != null) {
18876             return focusedStack.getStackId();
18877         }
18878         return -1;
18879     }
18880
18881     public Configuration getConfiguration() {
18882         Configuration ci;
18883         synchronized(this) {
18884             ci = new Configuration(mConfiguration);
18885             ci.userSetLocale = false;
18886         }
18887         return ci;
18888     }
18889
18890     @Override
18891     public void suppressResizeConfigChanges(boolean suppress) throws RemoteException {
18892         enforceCallingPermission(MANAGE_ACTIVITY_STACKS, "suppressResizeConfigChanges()");
18893         synchronized (this) {
18894             mSuppressResizeConfigChanges = suppress;
18895         }
18896     }
18897
18898     @Override
18899     public void moveTasksToFullscreenStack(int fromStackId, boolean onTop) {
18900         enforceCallingPermission(MANAGE_ACTIVITY_STACKS, "moveTasksToFullscreenStack()");
18901         if (fromStackId == HOME_STACK_ID) {
18902             throw new IllegalArgumentException("You can't move tasks from the home stack.");
18903         }
18904         synchronized (this) {
18905             final long origId = Binder.clearCallingIdentity();
18906             try {
18907                 mStackSupervisor.moveTasksToFullscreenStackLocked(fromStackId, onTop);
18908             } finally {
18909                 Binder.restoreCallingIdentity(origId);
18910             }
18911         }
18912     }
18913
18914     @Override
18915     public void updatePersistentConfiguration(Configuration values) {
18916         enforceCallingPermission(android.Manifest.permission.CHANGE_CONFIGURATION,
18917                 "updateConfiguration()");
18918         enforceWriteSettingsPermission("updateConfiguration()");
18919         if (values == null) {
18920             throw new NullPointerException("Configuration must not be null");
18921         }
18922
18923         int userId = UserHandle.getCallingUserId();
18924
18925         synchronized(this) {
18926             updatePersistentConfigurationLocked(values, userId);
18927         }
18928     }
18929
18930     private void updatePersistentConfigurationLocked(Configuration values, @UserIdInt int userId) {
18931         final long origId = Binder.clearCallingIdentity();
18932         try {
18933             updateConfigurationLocked(values, null, false, true, userId, false /* deferResume */);
18934         } finally {
18935             Binder.restoreCallingIdentity(origId);
18936         }
18937     }
18938
18939     private void updateFontScaleIfNeeded(@UserIdInt int userId) {
18940         final float scaleFactor = Settings.System.getFloatForUser(mContext.getContentResolver(),
18941                 FONT_SCALE, 1.0f, userId);
18942         if (mConfiguration.fontScale != scaleFactor) {
18943             final Configuration configuration = mWindowManager.computeNewConfiguration();
18944             configuration.fontScale = scaleFactor;
18945             synchronized (this) {
18946                 updatePersistentConfigurationLocked(configuration, userId);
18947             }
18948         }
18949     }
18950
18951     private void enforceWriteSettingsPermission(String func) {
18952         int uid = Binder.getCallingUid();
18953         if (uid == Process.ROOT_UID) {
18954             return;
18955         }
18956
18957         if (Settings.checkAndNoteWriteSettingsOperation(mContext, uid,
18958                 Settings.getPackageNameForUid(mContext, uid), false)) {
18959             return;
18960         }
18961
18962         String msg = "Permission Denial: " + func + " from pid="
18963                 + Binder.getCallingPid()
18964                 + ", uid=" + uid
18965                 + " requires " + android.Manifest.permission.WRITE_SETTINGS;
18966         Slog.w(TAG, msg);
18967         throw new SecurityException(msg);
18968     }
18969
18970     public void updateConfiguration(Configuration values) {
18971         enforceCallingPermission(android.Manifest.permission.CHANGE_CONFIGURATION,
18972                 "updateConfiguration()");
18973
18974         synchronized(this) {
18975             if (values == null && mWindowManager != null) {
18976                 // sentinel: fetch the current configuration from the window manager
18977                 values = mWindowManager.computeNewConfiguration();
18978             }
18979
18980             if (mWindowManager != null) {
18981                 mProcessList.applyDisplaySize(mWindowManager);
18982             }
18983
18984             final long origId = Binder.clearCallingIdentity();
18985             if (values != null) {
18986                 Settings.System.clearConfiguration(values);
18987             }
18988             updateConfigurationLocked(values, null, false);
18989             Binder.restoreCallingIdentity(origId);
18990         }
18991     }
18992
18993     void updateUserConfigurationLocked() {
18994         Configuration configuration = new Configuration(mConfiguration);
18995         Settings.System.adjustConfigurationForUser(mContext.getContentResolver(), configuration,
18996                 mUserController.getCurrentUserIdLocked(), Settings.System.canWrite(mContext));
18997         updateConfigurationLocked(configuration, null, false);
18998     }
18999
19000     boolean updateConfigurationLocked(Configuration values, ActivityRecord starting,
19001             boolean initLocale) {
19002         return updateConfigurationLocked(values, starting, initLocale, false /* deferResume */);
19003     }
19004
19005     boolean updateConfigurationLocked(Configuration values, ActivityRecord starting,
19006             boolean initLocale, boolean deferResume) {
19007         // pass UserHandle.USER_NULL as userId because we don't persist configuration for any user
19008         return updateConfigurationLocked(values, starting, initLocale, false /* persistent */,
19009                 UserHandle.USER_NULL, deferResume);
19010     }
19011
19012     // To cache the list of supported system locales
19013     private String[] mSupportedSystemLocales = null;
19014
19015     /**
19016      * Do either or both things: (1) change the current configuration, and (2)
19017      * make sure the given activity is running with the (now) current
19018      * configuration.  Returns true if the activity has been left running, or
19019      * false if <var>starting</var> is being destroyed to match the new
19020      * configuration.
19021      *
19022      * @param userId is only used when persistent parameter is set to true to persist configuration
19023      *               for that particular user
19024      */
19025     private boolean updateConfigurationLocked(Configuration values, ActivityRecord starting,
19026             boolean initLocale, boolean persistent, int userId, boolean deferResume) {
19027         int changes = 0;
19028
19029         if (mWindowManager != null) {
19030             mWindowManager.deferSurfaceLayout();
19031         }
19032         if (values != null) {
19033             Configuration newConfig = new Configuration(mConfiguration);
19034             changes = newConfig.updateFrom(values);
19035             if (changes != 0) {
19036                 if (DEBUG_SWITCH || DEBUG_CONFIGURATION) Slog.i(TAG_CONFIGURATION,
19037                         "Updating configuration to: " + values);
19038
19039                 EventLog.writeEvent(EventLogTags.CONFIGURATION_CHANGED, changes);
19040
19041                 if (!initLocale && !values.getLocales().isEmpty() && values.userSetLocale) {
19042                     final LocaleList locales = values.getLocales();
19043                     int bestLocaleIndex = 0;
19044                     if (locales.size() > 1) {
19045                         if (mSupportedSystemLocales == null) {
19046                             mSupportedSystemLocales =
19047                                     Resources.getSystem().getAssets().getLocales();
19048                         }
19049                         bestLocaleIndex = Math.max(0,
19050                                 locales.getFirstMatchIndex(mSupportedSystemLocales));
19051                     }
19052                     SystemProperties.set("persist.sys.locale",
19053                             locales.get(bestLocaleIndex).toLanguageTag());
19054                     LocaleList.setDefault(locales, bestLocaleIndex);
19055                     mHandler.sendMessage(mHandler.obtainMessage(SEND_LOCALE_TO_MOUNT_DAEMON_MSG,
19056                             locales.get(bestLocaleIndex)));
19057                 }
19058
19059                 mConfigurationSeq++;
19060                 if (mConfigurationSeq <= 0) {
19061                     mConfigurationSeq = 1;
19062                 }
19063                 newConfig.seq = mConfigurationSeq;
19064                 mConfiguration = newConfig;
19065                 Slog.i(TAG, "Config changes=" + Integer.toHexString(changes) + " " + newConfig);
19066                 mUsageStatsService.reportConfigurationChange(newConfig,
19067                         mUserController.getCurrentUserIdLocked());
19068                 //mUsageStatsService.noteStartConfig(newConfig);
19069
19070                 final Configuration configCopy = new Configuration(mConfiguration);
19071
19072                 // TODO: If our config changes, should we auto dismiss any currently
19073                 // showing dialogs?
19074                 mShowDialogs = shouldShowDialogs(newConfig, mInVrMode);
19075
19076                 AttributeCache ac = AttributeCache.instance();
19077                 if (ac != null) {
19078                     ac.updateConfiguration(configCopy);
19079                 }
19080
19081                 // Make sure all resources in our process are updated
19082                 // right now, so that anyone who is going to retrieve
19083                 // resource values after we return will be sure to get
19084                 // the new ones.  This is especially important during
19085                 // boot, where the first config change needs to guarantee
19086                 // all resources have that config before following boot
19087                 // code is executed.
19088                 mSystemThread.applyConfigurationToResources(configCopy);
19089
19090                 if (persistent && Settings.System.hasInterestingConfigurationChanges(changes)) {
19091                     Message msg = mHandler.obtainMessage(UPDATE_CONFIGURATION_MSG);
19092                     msg.obj = new Configuration(configCopy);
19093                     msg.arg1 = userId;
19094                     mHandler.sendMessage(msg);
19095                 }
19096
19097                 final boolean isDensityChange = (changes & ActivityInfo.CONFIG_DENSITY) != 0;
19098                 if (isDensityChange) {
19099                     // Reset the unsupported display size dialog.
19100                     mUiHandler.sendEmptyMessage(SHOW_UNSUPPORTED_DISPLAY_SIZE_DIALOG_MSG);
19101
19102                     killAllBackgroundProcessesExcept(Build.VERSION_CODES.N,
19103                             ActivityManager.PROCESS_STATE_FOREGROUND_SERVICE);
19104                 }
19105
19106                 for (int i=mLruProcesses.size()-1; i>=0; i--) {
19107                     ProcessRecord app = mLruProcesses.get(i);
19108                     try {
19109                         if (app.thread != null) {
19110                             if (DEBUG_CONFIGURATION) Slog.v(TAG_CONFIGURATION, "Sending to proc "
19111                                     + app.processName + " new config " + mConfiguration);
19112                             app.thread.scheduleConfigurationChanged(configCopy);
19113                         }
19114                     } catch (Exception e) {
19115                     }
19116                 }
19117                 Intent intent = new Intent(Intent.ACTION_CONFIGURATION_CHANGED);
19118                 intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY
19119                         | Intent.FLAG_RECEIVER_REPLACE_PENDING
19120                         | Intent.FLAG_RECEIVER_FOREGROUND);
19121                 broadcastIntentLocked(null, null, intent, null, null, 0, null, null,
19122                         null, AppOpsManager.OP_NONE, null, false, false,
19123                         MY_PID, Process.SYSTEM_UID, UserHandle.USER_ALL);
19124                 if ((changes&ActivityInfo.CONFIG_LOCALE) != 0) {
19125                     intent = new Intent(Intent.ACTION_LOCALE_CHANGED);
19126                     intent.addFlags(Intent.FLAG_RECEIVER_FOREGROUND);
19127                     if (initLocale || !mProcessesReady) {
19128                         intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY);
19129                     }
19130                     broadcastIntentLocked(null, null, intent,
19131                             null, null, 0, null, null, null, AppOpsManager.OP_NONE,
19132                             null, false, false, MY_PID, Process.SYSTEM_UID, UserHandle.USER_ALL);
19133                 }
19134             }
19135             // Update the configuration with WM first and check if any of the stacks need to be
19136             // resized due to the configuration change. If so, resize the stacks now and do any
19137             // relaunches if necessary. This way we don't need to relaunch again below in
19138             // ensureActivityConfigurationLocked().
19139             if (mWindowManager != null) {
19140                 final int[] resizedStacks = mWindowManager.setNewConfiguration(mConfiguration);
19141                 if (resizedStacks != null) {
19142                     for (int stackId : resizedStacks) {
19143                         final Rect newBounds = mWindowManager.getBoundsForNewConfiguration(stackId);
19144                         mStackSupervisor.resizeStackLocked(
19145                                 stackId, newBounds, null, null, false, false, deferResume);
19146                     }
19147                 }
19148             }
19149         }
19150
19151         boolean kept = true;
19152         final ActivityStack mainStack = mStackSupervisor.getFocusedStack();
19153         // mainStack is null during startup.
19154         if (mainStack != null) {
19155             if (changes != 0 && starting == null) {
19156                 // If the configuration changed, and the caller is not already
19157                 // in the process of starting an activity, then find the top
19158                 // activity to check if its configuration needs to change.
19159                 starting = mainStack.topRunningActivityLocked();
19160             }
19161
19162             if (starting != null) {
19163                 kept = mainStack.ensureActivityConfigurationLocked(starting, changes, false);
19164                 // And we need to make sure at this point that all other activities
19165                 // are made visible with the correct configuration.
19166                 mStackSupervisor.ensureActivitiesVisibleLocked(starting, changes,
19167                         !PRESERVE_WINDOWS);
19168             }
19169         }
19170         if (mWindowManager != null) {
19171             mWindowManager.continueSurfaceLayout();
19172         }
19173         return kept;
19174     }
19175
19176     /**
19177      * Decide based on the configuration whether we should shouw the ANR,
19178      * crash, etc dialogs.  The idea is that if there is no affordence to
19179      * press the on-screen buttons, or the user experience would be more
19180      * greatly impacted than the crash itself, we shouldn't show the dialog.
19181      *
19182      * A thought: SystemUI might also want to get told about this, the Power
19183      * dialog / global actions also might want different behaviors.
19184      */
19185     private static final boolean shouldShowDialogs(Configuration config, boolean inVrMode) {
19186         final boolean inputMethodExists = !(config.keyboard == Configuration.KEYBOARD_NOKEYS
19187                                    && config.touchscreen == Configuration.TOUCHSCREEN_NOTOUCH
19188                                    && config.navigation == Configuration.NAVIGATION_NONAV);
19189         int modeType = config.uiMode & Configuration.UI_MODE_TYPE_MASK;
19190         final boolean uiModeSupportsDialogs = (modeType != Configuration.UI_MODE_TYPE_CAR
19191                 && !(modeType == Configuration.UI_MODE_TYPE_WATCH && "user".equals(Build.TYPE)));
19192         return inputMethodExists && uiModeSupportsDialogs && !inVrMode;
19193     }
19194
19195     @Override
19196     public boolean shouldUpRecreateTask(IBinder token, String destAffinity) {
19197         synchronized (this) {
19198             ActivityRecord srec = ActivityRecord.forTokenLocked(token);
19199             if (srec != null) {
19200                 return srec.task.stack.shouldUpRecreateTaskLocked(srec, destAffinity);
19201             }
19202         }
19203         return false;
19204     }
19205
19206     public boolean navigateUpTo(IBinder token, Intent destIntent, int resultCode,
19207             Intent resultData) {
19208
19209         synchronized (this) {
19210             final ActivityRecord r = ActivityRecord.forTokenLocked(token);
19211             if (r != null) {
19212                 return r.task.stack.navigateUpToLocked(r, destIntent, resultCode, resultData);
19213             }
19214             return false;
19215         }
19216     }
19217
19218     public int getLaunchedFromUid(IBinder activityToken) {
19219         ActivityRecord srec;
19220         synchronized (this) {
19221             srec = ActivityRecord.forTokenLocked(activityToken);
19222         }
19223         if (srec == null) {
19224             return -1;
19225         }
19226         return srec.launchedFromUid;
19227     }
19228
19229     public String getLaunchedFromPackage(IBinder activityToken) {
19230         ActivityRecord srec;
19231         synchronized (this) {
19232             srec = ActivityRecord.forTokenLocked(activityToken);
19233         }
19234         if (srec == null) {
19235             return null;
19236         }
19237         return srec.launchedFromPackage;
19238     }
19239
19240     // =========================================================
19241     // LIFETIME MANAGEMENT
19242     // =========================================================
19243
19244     // Returns which broadcast queue the app is the current [or imminent] receiver
19245     // on, or 'null' if the app is not an active broadcast recipient.
19246     private BroadcastQueue isReceivingBroadcast(ProcessRecord app) {
19247         BroadcastRecord r = app.curReceiver;
19248         if (r != null) {
19249             return r.queue;
19250         }
19251
19252         // It's not the current receiver, but it might be starting up to become one
19253         synchronized (this) {
19254             for (BroadcastQueue queue : mBroadcastQueues) {
19255                 r = queue.mPendingBroadcast;
19256                 if (r != null && r.curApp == app) {
19257                     // found it; report which queue it's in
19258                     return queue;
19259                 }
19260             }
19261         }
19262
19263         return null;
19264     }
19265
19266     Association startAssociationLocked(int sourceUid, String sourceProcess, int sourceState,
19267             int targetUid, ComponentName targetComponent, String targetProcess) {
19268         if (!mTrackingAssociations) {
19269             return null;
19270         }
19271         ArrayMap<ComponentName, SparseArray<ArrayMap<String, Association>>> components
19272                 = mAssociations.get(targetUid);
19273         if (components == null) {
19274             components = new ArrayMap<>();
19275             mAssociations.put(targetUid, components);
19276         }
19277         SparseArray<ArrayMap<String, Association>> sourceUids = components.get(targetComponent);
19278         if (sourceUids == null) {
19279             sourceUids = new SparseArray<>();
19280             components.put(targetComponent, sourceUids);
19281         }
19282         ArrayMap<String, Association> sourceProcesses = sourceUids.get(sourceUid);
19283         if (sourceProcesses == null) {
19284             sourceProcesses = new ArrayMap<>();
19285             sourceUids.put(sourceUid, sourceProcesses);
19286         }
19287         Association ass = sourceProcesses.get(sourceProcess);
19288         if (ass == null) {
19289             ass = new Association(sourceUid, sourceProcess, targetUid, targetComponent,
19290                     targetProcess);
19291             sourceProcesses.put(sourceProcess, ass);
19292         }
19293         ass.mCount++;
19294         ass.mNesting++;
19295         if (ass.mNesting == 1) {
19296             ass.mStartTime = ass.mLastStateUptime = SystemClock.uptimeMillis();
19297             ass.mLastState = sourceState;
19298         }
19299         return ass;
19300     }
19301
19302     void stopAssociationLocked(int sourceUid, String sourceProcess, int targetUid,
19303             ComponentName targetComponent) {
19304         if (!mTrackingAssociations) {
19305             return;
19306         }
19307         ArrayMap<ComponentName, SparseArray<ArrayMap<String, Association>>> components
19308                 = mAssociations.get(targetUid);
19309         if (components == null) {
19310             return;
19311         }
19312         SparseArray<ArrayMap<String, Association>> sourceUids = components.get(targetComponent);
19313         if (sourceUids == null) {
19314             return;
19315         }
19316         ArrayMap<String, Association> sourceProcesses = sourceUids.get(sourceUid);
19317         if (sourceProcesses == null) {
19318             return;
19319         }
19320         Association ass = sourceProcesses.get(sourceProcess);
19321         if (ass == null || ass.mNesting <= 0) {
19322             return;
19323         }
19324         ass.mNesting--;
19325         if (ass.mNesting == 0) {
19326             long uptime = SystemClock.uptimeMillis();
19327             ass.mTime += uptime - ass.mStartTime;
19328             ass.mStateTimes[ass.mLastState-ActivityManager.MIN_PROCESS_STATE]
19329                     += uptime - ass.mLastStateUptime;
19330             ass.mLastState = ActivityManager.MAX_PROCESS_STATE + 2;
19331         }
19332     }
19333
19334     private void noteUidProcessState(final int uid, final int state) {
19335         mBatteryStatsService.noteUidProcessState(uid, state);
19336         if (mTrackingAssociations) {
19337             for (int i1=0, N1=mAssociations.size(); i1<N1; i1++) {
19338                 ArrayMap<ComponentName, SparseArray<ArrayMap<String, Association>>> targetComponents
19339                         = mAssociations.valueAt(i1);
19340                 for (int i2=0, N2=targetComponents.size(); i2<N2; i2++) {
19341                     SparseArray<ArrayMap<String, Association>> sourceUids
19342                             = targetComponents.valueAt(i2);
19343                     ArrayMap<String, Association> sourceProcesses = sourceUids.get(uid);
19344                     if (sourceProcesses != null) {
19345                         for (int i4=0, N4=sourceProcesses.size(); i4<N4; i4++) {
19346                             Association ass = sourceProcesses.valueAt(i4);
19347                             if (ass.mNesting >= 1) {
19348                                 // currently associated
19349                                 long uptime = SystemClock.uptimeMillis();
19350                                 ass.mStateTimes[ass.mLastState-ActivityManager.MIN_PROCESS_STATE]
19351                                         += uptime - ass.mLastStateUptime;
19352                                 ass.mLastState = state;
19353                                 ass.mLastStateUptime = uptime;
19354                             }
19355                         }
19356                     }
19357                 }
19358             }
19359         }
19360     }
19361
19362     private final int computeOomAdjLocked(ProcessRecord app, int cachedAdj, ProcessRecord TOP_APP,
19363             boolean doingAll, long now) {
19364         if (mAdjSeq == app.adjSeq) {
19365             // This adjustment has already been computed.
19366             return app.curRawAdj;
19367         }
19368
19369         if (app.thread == null) {
19370             app.adjSeq = mAdjSeq;
19371             app.curSchedGroup = ProcessList.SCHED_GROUP_BACKGROUND;
19372             app.curProcState = ActivityManager.PROCESS_STATE_CACHED_EMPTY;
19373             return (app.curAdj=app.curRawAdj=ProcessList.CACHED_APP_MAX_ADJ);
19374         }
19375
19376         app.adjTypeCode = ActivityManager.RunningAppProcessInfo.REASON_UNKNOWN;
19377         app.adjSource = null;
19378         app.adjTarget = null;
19379         app.empty = false;
19380         app.cached = false;
19381
19382         final int activitiesSize = app.activities.size();
19383
19384         if (app.maxAdj <= ProcessList.FOREGROUND_APP_ADJ) {
19385             // The max adjustment doesn't allow this app to be anything
19386             // below foreground, so it is not worth doing work for it.
19387             app.adjType = "fixed";
19388             app.adjSeq = mAdjSeq;
19389             app.curRawAdj = app.maxAdj;
19390             app.foregroundActivities = false;
19391             app.curSchedGroup = ProcessList.SCHED_GROUP_DEFAULT;
19392             app.curProcState = ActivityManager.PROCESS_STATE_PERSISTENT;
19393             // System processes can do UI, and when they do we want to have
19394             // them trim their memory after the user leaves the UI.  To
19395             // facilitate this, here we need to determine whether or not it
19396             // is currently showing UI.
19397             app.systemNoUi = true;
19398             if (app == TOP_APP) {
19399                 app.systemNoUi = false;
19400                 app.curSchedGroup = ProcessList.SCHED_GROUP_TOP_APP;
19401                 app.adjType = "pers-top-activity";
19402             } else if (app.hasTopUi) {
19403                 app.systemNoUi = false;
19404                 app.curSchedGroup = ProcessList.SCHED_GROUP_TOP_APP;
19405                 app.adjType = "pers-top-ui";
19406             } else if (activitiesSize > 0) {
19407                 for (int j = 0; j < activitiesSize; j++) {
19408                     final ActivityRecord r = app.activities.get(j);
19409                     if (r.visible) {
19410                         app.systemNoUi = false;
19411                     }
19412                 }
19413             }
19414             if (!app.systemNoUi) {
19415                 app.curProcState = ActivityManager.PROCESS_STATE_PERSISTENT_UI;
19416             }
19417             return (app.curAdj=app.maxAdj);
19418         }
19419
19420         app.systemNoUi = false;
19421
19422         final int PROCESS_STATE_CUR_TOP = mTopProcessState;
19423
19424         // Determine the importance of the process, starting with most
19425         // important to least, and assign an appropriate OOM adjustment.
19426         int adj;
19427         int schedGroup;
19428         int procState;
19429         boolean foregroundActivities = false;
19430         BroadcastQueue queue;
19431         if (app == TOP_APP) {
19432             // The last app on the list is the foreground app.
19433             adj = ProcessList.FOREGROUND_APP_ADJ;
19434             schedGroup = ProcessList.SCHED_GROUP_TOP_APP;
19435             app.adjType = "top-activity";
19436             foregroundActivities = true;
19437             procState = PROCESS_STATE_CUR_TOP;
19438         } else if (app.instrumentationClass != null) {
19439             // Don't want to kill running instrumentation.
19440             adj = ProcessList.FOREGROUND_APP_ADJ;
19441             schedGroup = ProcessList.SCHED_GROUP_DEFAULT;
19442             app.adjType = "instrumentation";
19443             procState = ActivityManager.PROCESS_STATE_FOREGROUND_SERVICE;
19444         } else if ((queue = isReceivingBroadcast(app)) != null) {
19445             // An app that is currently receiving a broadcast also
19446             // counts as being in the foreground for OOM killer purposes.
19447             // It's placed in a sched group based on the nature of the
19448             // broadcast as reflected by which queue it's active in.
19449             adj = ProcessList.FOREGROUND_APP_ADJ;
19450             schedGroup = (queue == mFgBroadcastQueue)
19451                     ? ProcessList.SCHED_GROUP_DEFAULT : ProcessList.SCHED_GROUP_BACKGROUND;
19452             app.adjType = "broadcast";
19453             procState = ActivityManager.PROCESS_STATE_RECEIVER;
19454         } else if (app.executingServices.size() > 0) {
19455             // An app that is currently executing a service callback also
19456             // counts as being in the foreground.
19457             adj = ProcessList.FOREGROUND_APP_ADJ;
19458             schedGroup = app.execServicesFg ?
19459                     ProcessList.SCHED_GROUP_DEFAULT : ProcessList.SCHED_GROUP_BACKGROUND;
19460             app.adjType = "exec-service";
19461             procState = ActivityManager.PROCESS_STATE_SERVICE;
19462             //Slog.i(TAG, "EXEC " + (app.execServicesFg ? "FG" : "BG") + ": " + app);
19463         } else {
19464             // As far as we know the process is empty.  We may change our mind later.
19465             schedGroup = ProcessList.SCHED_GROUP_BACKGROUND;
19466             // At this point we don't actually know the adjustment.  Use the cached adj
19467             // value that the caller wants us to.
19468             adj = cachedAdj;
19469             procState = ActivityManager.PROCESS_STATE_CACHED_EMPTY;
19470             app.cached = true;
19471             app.empty = true;
19472             app.adjType = "cch-empty";
19473         }
19474
19475         // Examine all activities if not already foreground.
19476         if (!foregroundActivities && activitiesSize > 0) {
19477             int minLayer = ProcessList.VISIBLE_APP_LAYER_MAX;
19478             for (int j = 0; j < activitiesSize; j++) {
19479                 final ActivityRecord r = app.activities.get(j);
19480                 if (r.app != app) {
19481                     Log.e(TAG, "Found activity " + r + " in proc activity list using " + r.app
19482                             + " instead of expected " + app);
19483                     if (r.app == null || (r.app.uid == app.uid)) {
19484                         // Only fix things up when they look sane
19485                         r.app = app;
19486                     } else {
19487                         continue;
19488                     }
19489                 }
19490                 if (r.visible) {
19491                     // App has a visible activity; only upgrade adjustment.
19492                     if (adj > ProcessList.VISIBLE_APP_ADJ) {
19493                         adj = ProcessList.VISIBLE_APP_ADJ;
19494                         app.adjType = "visible";
19495                     }
19496                     if (procState > PROCESS_STATE_CUR_TOP) {
19497                         procState = PROCESS_STATE_CUR_TOP;
19498                     }
19499                     schedGroup = ProcessList.SCHED_GROUP_DEFAULT;
19500                     app.cached = false;
19501                     app.empty = false;
19502                     foregroundActivities = true;
19503                     if (r.task != null && minLayer > 0) {
19504                         final int layer = r.task.mLayerRank;
19505                         if (layer >= 0 && minLayer > layer) {
19506                             minLayer = layer;
19507                         }
19508                     }
19509                     break;
19510                 } else if (r.state == ActivityState.PAUSING || r.state == ActivityState.PAUSED) {
19511                     if (adj > ProcessList.PERCEPTIBLE_APP_ADJ) {
19512                         adj = ProcessList.PERCEPTIBLE_APP_ADJ;
19513                         app.adjType = "pausing";
19514                     }
19515                     if (procState > PROCESS_STATE_CUR_TOP) {
19516                         procState = PROCESS_STATE_CUR_TOP;
19517                     }
19518                     schedGroup = ProcessList.SCHED_GROUP_DEFAULT;
19519                     app.cached = false;
19520                     app.empty = false;
19521                     foregroundActivities = true;
19522                 } else if (r.state == ActivityState.STOPPING) {
19523                     if (adj > ProcessList.PERCEPTIBLE_APP_ADJ) {
19524                         adj = ProcessList.PERCEPTIBLE_APP_ADJ;
19525                         app.adjType = "stopping";
19526                     }
19527                     // For the process state, we will at this point consider the
19528                     // process to be cached.  It will be cached either as an activity
19529                     // or empty depending on whether the activity is finishing.  We do
19530                     // this so that we can treat the process as cached for purposes of
19531                     // memory trimming (determing current memory level, trim command to
19532                     // send to process) since there can be an arbitrary number of stopping
19533                     // processes and they should soon all go into the cached state.
19534                     if (!r.finishing) {
19535                         if (procState > ActivityManager.PROCESS_STATE_LAST_ACTIVITY) {
19536                             procState = ActivityManager.PROCESS_STATE_LAST_ACTIVITY;
19537                         }
19538                     }
19539                     app.cached = false;
19540                     app.empty = false;
19541                     foregroundActivities = true;
19542                 } else {
19543                     if (procState > ActivityManager.PROCESS_STATE_CACHED_ACTIVITY) {
19544                         procState = ActivityManager.PROCESS_STATE_CACHED_ACTIVITY;
19545                         app.adjType = "cch-act";
19546                     }
19547                 }
19548             }
19549             if (adj == ProcessList.VISIBLE_APP_ADJ) {
19550                 adj += minLayer;
19551             }
19552         }
19553
19554         if (adj > ProcessList.PERCEPTIBLE_APP_ADJ
19555                 || procState > ActivityManager.PROCESS_STATE_FOREGROUND_SERVICE) {
19556             if (app.foregroundServices) {
19557                 // The user is aware of this app, so make it visible.
19558                 adj = ProcessList.PERCEPTIBLE_APP_ADJ;
19559                 procState = ActivityManager.PROCESS_STATE_FOREGROUND_SERVICE;
19560                 app.cached = false;
19561                 app.adjType = "fg-service";
19562                 schedGroup = ProcessList.SCHED_GROUP_DEFAULT;
19563             } else if (app.forcingToForeground != null) {
19564                 // The user is aware of this app, so make it visible.
19565                 adj = ProcessList.PERCEPTIBLE_APP_ADJ;
19566                 procState = ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND;
19567                 app.cached = false;
19568                 app.adjType = "force-fg";
19569                 app.adjSource = app.forcingToForeground;
19570                 schedGroup = ProcessList.SCHED_GROUP_DEFAULT;
19571             }
19572         }
19573
19574         if (app == mHeavyWeightProcess) {
19575             if (adj > ProcessList.HEAVY_WEIGHT_APP_ADJ) {
19576                 // We don't want to kill the current heavy-weight process.
19577                 adj = ProcessList.HEAVY_WEIGHT_APP_ADJ;
19578                 schedGroup = ProcessList.SCHED_GROUP_BACKGROUND;
19579                 app.cached = false;
19580                 app.adjType = "heavy";
19581             }
19582             if (procState > ActivityManager.PROCESS_STATE_HEAVY_WEIGHT) {
19583                 procState = ActivityManager.PROCESS_STATE_HEAVY_WEIGHT;
19584             }
19585         }
19586
19587         if (app == mHomeProcess) {
19588             if (adj > ProcessList.HOME_APP_ADJ) {
19589                 // This process is hosting what we currently consider to be the
19590                 // home app, so we don't want to let it go into the background.
19591                 adj = ProcessList.HOME_APP_ADJ;
19592                 schedGroup = ProcessList.SCHED_GROUP_BACKGROUND;
19593                 app.cached = false;
19594                 app.adjType = "home";
19595             }
19596             if (procState > ActivityManager.PROCESS_STATE_HOME) {
19597                 procState = ActivityManager.PROCESS_STATE_HOME;
19598             }
19599         }
19600
19601         if (app == mPreviousProcess && app.activities.size() > 0) {
19602             if (adj > ProcessList.PREVIOUS_APP_ADJ) {
19603                 // This was the previous process that showed UI to the user.
19604                 // We want to try to keep it around more aggressively, to give
19605                 // a good experience around switching between two apps.
19606                 adj = ProcessList.PREVIOUS_APP_ADJ;
19607                 schedGroup = ProcessList.SCHED_GROUP_BACKGROUND;
19608                 app.cached = false;
19609                 app.adjType = "previous";
19610             }
19611             if (procState > ActivityManager.PROCESS_STATE_LAST_ACTIVITY) {
19612                 procState = ActivityManager.PROCESS_STATE_LAST_ACTIVITY;
19613             }
19614         }
19615
19616         if (false) Slog.i(TAG, "OOM " + app + ": initial adj=" + adj
19617                 + " reason=" + app.adjType);
19618
19619         // By default, we use the computed adjustment.  It may be changed if
19620         // there are applications dependent on our services or providers, but
19621         // this gives us a baseline and makes sure we don't get into an
19622         // infinite recursion.
19623         app.adjSeq = mAdjSeq;
19624         app.curRawAdj = adj;
19625         app.hasStartedServices = false;
19626
19627         if (mBackupTarget != null && app == mBackupTarget.app) {
19628             // If possible we want to avoid killing apps while they're being backed up
19629             if (adj > ProcessList.BACKUP_APP_ADJ) {
19630                 if (DEBUG_BACKUP) Slog.v(TAG_BACKUP, "oom BACKUP_APP_ADJ for " + app);
19631                 adj = ProcessList.BACKUP_APP_ADJ;
19632                 if (procState > ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND) {
19633                     procState = ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND;
19634                 }
19635                 app.adjType = "backup";
19636                 app.cached = false;
19637             }
19638             if (procState > ActivityManager.PROCESS_STATE_BACKUP) {
19639                 procState = ActivityManager.PROCESS_STATE_BACKUP;
19640             }
19641         }
19642
19643         boolean mayBeTop = false;
19644
19645         for (int is = app.services.size()-1;
19646                 is >= 0 && (adj > ProcessList.FOREGROUND_APP_ADJ
19647                         || schedGroup == ProcessList.SCHED_GROUP_BACKGROUND
19648                         || procState > ActivityManager.PROCESS_STATE_TOP);
19649                 is--) {
19650             ServiceRecord s = app.services.valueAt(is);
19651             if (s.startRequested) {
19652                 app.hasStartedServices = true;
19653                 if (procState > ActivityManager.PROCESS_STATE_SERVICE) {
19654                     procState = ActivityManager.PROCESS_STATE_SERVICE;
19655                 }
19656                 if (app.hasShownUi && app != mHomeProcess) {
19657                     // If this process has shown some UI, let it immediately
19658                     // go to the LRU list because it may be pretty heavy with
19659                     // UI stuff.  We'll tag it with a label just to help
19660                     // debug and understand what is going on.
19661                     if (adj > ProcessList.SERVICE_ADJ) {
19662                         app.adjType = "cch-started-ui-services";
19663                     }
19664                 } else {
19665                     if (now < (s.lastActivity + ActiveServices.MAX_SERVICE_INACTIVITY)) {
19666                         // This service has seen some activity within
19667                         // recent memory, so we will keep its process ahead
19668                         // of the background processes.
19669                         if (adj > ProcessList.SERVICE_ADJ) {
19670                             adj = ProcessList.SERVICE_ADJ;
19671                             app.adjType = "started-services";
19672                             app.cached = false;
19673                         }
19674                     }
19675                     // If we have let the service slide into the background
19676                     // state, still have some text describing what it is doing
19677                     // even though the service no longer has an impact.
19678                     if (adj > ProcessList.SERVICE_ADJ) {
19679                         app.adjType = "cch-started-services";
19680                     }
19681                 }
19682             }
19683
19684             for (int conni = s.connections.size()-1;
19685                     conni >= 0 && (adj > ProcessList.FOREGROUND_APP_ADJ
19686                             || schedGroup == ProcessList.SCHED_GROUP_BACKGROUND
19687                             || procState > ActivityManager.PROCESS_STATE_TOP);
19688                     conni--) {
19689                 ArrayList<ConnectionRecord> clist = s.connections.valueAt(conni);
19690                 for (int i = 0;
19691                         i < clist.size() && (adj > ProcessList.FOREGROUND_APP_ADJ
19692                                 || schedGroup == ProcessList.SCHED_GROUP_BACKGROUND
19693                                 || procState > ActivityManager.PROCESS_STATE_TOP);
19694                         i++) {
19695                     // XXX should compute this based on the max of
19696                     // all connected clients.
19697                     ConnectionRecord cr = clist.get(i);
19698                     if (cr.binding.client == app) {
19699                         // Binding to ourself is not interesting.
19700                         continue;
19701                     }
19702
19703                     if ((cr.flags&Context.BIND_WAIVE_PRIORITY) == 0) {
19704                         ProcessRecord client = cr.binding.client;
19705                         int clientAdj = computeOomAdjLocked(client, cachedAdj,
19706                                 TOP_APP, doingAll, now);
19707                         int clientProcState = client.curProcState;
19708                         if (clientProcState >= ActivityManager.PROCESS_STATE_CACHED_ACTIVITY) {
19709                             // If the other app is cached for any reason, for purposes here
19710                             // we are going to consider it empty.  The specific cached state
19711                             // doesn't propagate except under certain conditions.
19712                             clientProcState = ActivityManager.PROCESS_STATE_CACHED_EMPTY;
19713                         }
19714                         String adjType = null;
19715                         if ((cr.flags&Context.BIND_ALLOW_OOM_MANAGEMENT) != 0) {
19716                             // Not doing bind OOM management, so treat
19717                             // this guy more like a started service.
19718                             if (app.hasShownUi && app != mHomeProcess) {
19719                                 // If this process has shown some UI, let it immediately
19720                                 // go to the LRU list because it may be pretty heavy with
19721                                 // UI stuff.  We'll tag it with a label just to help
19722                                 // debug and understand what is going on.
19723                                 if (adj > clientAdj) {
19724                                     adjType = "cch-bound-ui-services";
19725                                 }
19726                                 app.cached = false;
19727                                 clientAdj = adj;
19728                                 clientProcState = procState;
19729                             } else {
19730                                 if (now >= (s.lastActivity
19731                                         + ActiveServices.MAX_SERVICE_INACTIVITY)) {
19732                                     // This service has not seen activity within
19733                                     // recent memory, so allow it to drop to the
19734                                     // LRU list if there is no other reason to keep
19735                                     // it around.  We'll also tag it with a label just
19736                                     // to help debug and undertand what is going on.
19737                                     if (adj > clientAdj) {
19738                                         adjType = "cch-bound-services";
19739                                     }
19740                                     clientAdj = adj;
19741                                 }
19742                             }
19743                         }
19744                         if (adj > clientAdj) {
19745                             // If this process has recently shown UI, and
19746                             // the process that is binding to it is less
19747                             // important than being visible, then we don't
19748                             // care about the binding as much as we care
19749                             // about letting this process get into the LRU
19750                             // list to be killed and restarted if needed for
19751                             // memory.
19752                             if (app.hasShownUi && app != mHomeProcess
19753                                     && clientAdj > ProcessList.PERCEPTIBLE_APP_ADJ) {
19754                                 adjType = "cch-bound-ui-services";
19755                             } else {
19756                                 if ((cr.flags&(Context.BIND_ABOVE_CLIENT
19757                                         |Context.BIND_IMPORTANT)) != 0) {
19758                                     adj = clientAdj >= ProcessList.PERSISTENT_SERVICE_ADJ
19759                                             ? clientAdj : ProcessList.PERSISTENT_SERVICE_ADJ;
19760                                 } else if ((cr.flags&Context.BIND_NOT_VISIBLE) != 0
19761                                         && clientAdj < ProcessList.PERCEPTIBLE_APP_ADJ
19762                                         && adj > ProcessList.PERCEPTIBLE_APP_ADJ) {
19763                                     adj = ProcessList.PERCEPTIBLE_APP_ADJ;
19764                                 } else if (clientAdj >= ProcessList.PERCEPTIBLE_APP_ADJ) {
19765                                     adj = clientAdj;
19766                                 } else {
19767                                     if (adj > ProcessList.VISIBLE_APP_ADJ) {
19768                                         adj = Math.max(clientAdj, ProcessList.VISIBLE_APP_ADJ);
19769                                     }
19770                                 }
19771                                 if (!client.cached) {
19772                                     app.cached = false;
19773                                 }
19774                                 adjType = "service";
19775                             }
19776                         }
19777                         if ((cr.flags&Context.BIND_NOT_FOREGROUND) == 0) {
19778                             // This will treat important bound services identically to
19779                             // the top app, which may behave differently than generic
19780                             // foreground work.
19781                             if (client.curSchedGroup > schedGroup) {
19782                                 if ((cr.flags&Context.BIND_IMPORTANT) != 0) {
19783                                     schedGroup = client.curSchedGroup;
19784                                 } else {
19785                                     schedGroup = ProcessList.SCHED_GROUP_DEFAULT;
19786                                 }
19787                             }
19788                             if (clientProcState <= ActivityManager.PROCESS_STATE_TOP) {
19789                                 if (clientProcState == ActivityManager.PROCESS_STATE_TOP) {
19790                                     // Special handling of clients who are in the top state.
19791                                     // We *may* want to consider this process to be in the
19792                                     // top state as well, but only if there is not another
19793                                     // reason for it to be running.  Being on the top is a
19794                                     // special state, meaning you are specifically running
19795                                     // for the current top app.  If the process is already
19796                                     // running in the background for some other reason, it
19797                                     // is more important to continue considering it to be
19798                                     // in the background state.
19799                                     mayBeTop = true;
19800                                     clientProcState = ActivityManager.PROCESS_STATE_CACHED_EMPTY;
19801                                 } else {
19802                                     // Special handling for above-top states (persistent
19803                                     // processes).  These should not bring the current process
19804                                     // into the top state, since they are not on top.  Instead
19805                                     // give them the best state after that.
19806                                     if ((cr.flags&Context.BIND_FOREGROUND_SERVICE) != 0) {
19807                                         clientProcState =
19808                                                 ActivityManager.PROCESS_STATE_BOUND_FOREGROUND_SERVICE;
19809                                     } else if (mWakefulness
19810                                                     == PowerManagerInternal.WAKEFULNESS_AWAKE &&
19811                                             (cr.flags&Context.BIND_FOREGROUND_SERVICE_WHILE_AWAKE)
19812                                                     != 0) {
19813                                         clientProcState =
19814                                                 ActivityManager.PROCESS_STATE_BOUND_FOREGROUND_SERVICE;
19815                                     } else {
19816                                         clientProcState =
19817                                                 ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND;
19818                                     }
19819                                 }
19820                             }
19821                         } else {
19822                             if (clientProcState <
19823                                     ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND) {
19824                                 clientProcState =
19825                                         ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND;
19826                             }
19827                         }
19828                         if (procState > clientProcState) {
19829                             procState = clientProcState;
19830                         }
19831                         if (procState < ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND
19832                                 && (cr.flags&Context.BIND_SHOWING_UI) != 0) {
19833                             app.pendingUiClean = true;
19834                         }
19835                         if (adjType != null) {
19836                             app.adjType = adjType;
19837                             app.adjTypeCode = ActivityManager.RunningAppProcessInfo
19838                                     .REASON_SERVICE_IN_USE;
19839                             app.adjSource = cr.binding.client;
19840                             app.adjSourceProcState = clientProcState;
19841                             app.adjTarget = s.name;
19842                         }
19843                     }
19844                     if ((cr.flags&Context.BIND_TREAT_LIKE_ACTIVITY) != 0) {
19845                         app.treatLikeActivity = true;
19846                     }
19847                     final ActivityRecord a = cr.activity;
19848                     if ((cr.flags&Context.BIND_ADJUST_WITH_ACTIVITY) != 0) {
19849                         if (a != null && adj > ProcessList.FOREGROUND_APP_ADJ &&
19850                             (a.visible || a.state == ActivityState.RESUMED ||
19851                              a.state == ActivityState.PAUSING)) {
19852                             adj = ProcessList.FOREGROUND_APP_ADJ;
19853                             if ((cr.flags&Context.BIND_NOT_FOREGROUND) == 0) {
19854                                 if ((cr.flags&Context.BIND_IMPORTANT) != 0) {
19855                                     schedGroup = ProcessList.SCHED_GROUP_TOP_APP_BOUND;
19856                                 } else {
19857                                     schedGroup = ProcessList.SCHED_GROUP_DEFAULT;
19858                                 }
19859                             }
19860                             app.cached = false;
19861                             app.adjType = "service";
19862                             app.adjTypeCode = ActivityManager.RunningAppProcessInfo
19863                                     .REASON_SERVICE_IN_USE;
19864                             app.adjSource = a;
19865                             app.adjSourceProcState = procState;
19866                             app.adjTarget = s.name;
19867                         }
19868                     }
19869                 }
19870             }
19871         }
19872
19873         for (int provi = app.pubProviders.size()-1;
19874                 provi >= 0 && (adj > ProcessList.FOREGROUND_APP_ADJ
19875                         || schedGroup == ProcessList.SCHED_GROUP_BACKGROUND
19876                         || procState > ActivityManager.PROCESS_STATE_TOP);
19877                 provi--) {
19878             ContentProviderRecord cpr = app.pubProviders.valueAt(provi);
19879             for (int i = cpr.connections.size()-1;
19880                     i >= 0 && (adj > ProcessList.FOREGROUND_APP_ADJ
19881                             || schedGroup == ProcessList.SCHED_GROUP_BACKGROUND
19882                             || procState > ActivityManager.PROCESS_STATE_TOP);
19883                     i--) {
19884                 ContentProviderConnection conn = cpr.connections.get(i);
19885                 ProcessRecord client = conn.client;
19886                 if (client == app) {
19887                     // Being our own client is not interesting.
19888                     continue;
19889                 }
19890                 int clientAdj = computeOomAdjLocked(client, cachedAdj, TOP_APP, doingAll, now);
19891                 int clientProcState = client.curProcState;
19892                 if (clientProcState >= ActivityManager.PROCESS_STATE_CACHED_ACTIVITY) {
19893                     // If the other app is cached for any reason, for purposes here
19894                     // we are going to consider it empty.
19895                     clientProcState = ActivityManager.PROCESS_STATE_CACHED_EMPTY;
19896                 }
19897                 if (adj > clientAdj) {
19898                     if (app.hasShownUi && app != mHomeProcess
19899                             && clientAdj > ProcessList.PERCEPTIBLE_APP_ADJ) {
19900                         app.adjType = "cch-ui-provider";
19901                     } else {
19902                         adj = clientAdj > ProcessList.FOREGROUND_APP_ADJ
19903                                 ? clientAdj : ProcessList.FOREGROUND_APP_ADJ;
19904                         app.adjType = "provider";
19905                     }
19906                     app.cached &= client.cached;
19907                     app.adjTypeCode = ActivityManager.RunningAppProcessInfo
19908                             .REASON_PROVIDER_IN_USE;
19909                     app.adjSource = client;
19910                     app.adjSourceProcState = clientProcState;
19911                     app.adjTarget = cpr.name;
19912                 }
19913                 if (clientProcState <= ActivityManager.PROCESS_STATE_TOP) {
19914                     if (clientProcState == ActivityManager.PROCESS_STATE_TOP) {
19915                         // Special handling of clients who are in the top state.
19916                         // We *may* want to consider this process to be in the
19917                         // top state as well, but only if there is not another
19918                         // reason for it to be running.  Being on the top is a
19919                         // special state, meaning you are specifically running
19920                         // for the current top app.  If the process is already
19921                         // running in the background for some other reason, it
19922                         // is more important to continue considering it to be
19923                         // in the background state.
19924                         mayBeTop = true;
19925                         clientProcState = ActivityManager.PROCESS_STATE_CACHED_EMPTY;
19926                     } else {
19927                         // Special handling for above-top states (persistent
19928                         // processes).  These should not bring the current process
19929                         // into the top state, since they are not on top.  Instead
19930                         // give them the best state after that.
19931                         clientProcState =
19932                                 ActivityManager.PROCESS_STATE_BOUND_FOREGROUND_SERVICE;
19933                     }
19934                 }
19935                 if (procState > clientProcState) {
19936                     procState = clientProcState;
19937                 }
19938                 if (client.curSchedGroup > schedGroup) {
19939                     schedGroup = ProcessList.SCHED_GROUP_DEFAULT;
19940                 }
19941             }
19942             // If the provider has external (non-framework) process
19943             // dependencies, ensure that its adjustment is at least
19944             // FOREGROUND_APP_ADJ.
19945             if (cpr.hasExternalProcessHandles()) {
19946                 if (adj > ProcessList.FOREGROUND_APP_ADJ) {
19947                     adj = ProcessList.FOREGROUND_APP_ADJ;
19948                     schedGroup = ProcessList.SCHED_GROUP_DEFAULT;
19949                     app.cached = false;
19950                     app.adjType = "provider";
19951                     app.adjTarget = cpr.name;
19952                 }
19953                 if (procState > ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND) {
19954                     procState = ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND;
19955                 }
19956             }
19957         }
19958
19959         if (app.lastProviderTime > 0 && (app.lastProviderTime+CONTENT_PROVIDER_RETAIN_TIME) > now) {
19960             if (adj > ProcessList.PREVIOUS_APP_ADJ) {
19961                 adj = ProcessList.PREVIOUS_APP_ADJ;
19962                 schedGroup = ProcessList.SCHED_GROUP_BACKGROUND;
19963                 app.cached = false;
19964                 app.adjType = "provider";
19965             }
19966             if (procState > ActivityManager.PROCESS_STATE_LAST_ACTIVITY) {
19967                 procState = ActivityManager.PROCESS_STATE_LAST_ACTIVITY;
19968             }
19969         }
19970
19971         if (mayBeTop && procState > ActivityManager.PROCESS_STATE_TOP) {
19972             // A client of one of our services or providers is in the top state.  We
19973             // *may* want to be in the top state, but not if we are already running in
19974             // the background for some other reason.  For the decision here, we are going
19975             // to pick out a few specific states that we want to remain in when a client
19976             // is top (states that tend to be longer-term) and otherwise allow it to go
19977             // to the top state.
19978             switch (procState) {
19979                 case ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND:
19980                 case ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND:
19981                 case ActivityManager.PROCESS_STATE_SERVICE:
19982                     // These all are longer-term states, so pull them up to the top
19983                     // of the background states, but not all the way to the top state.
19984                     procState = ActivityManager.PROCESS_STATE_BOUND_FOREGROUND_SERVICE;
19985                     break;
19986                 default:
19987                     // Otherwise, top is a better choice, so take it.
19988                     procState = ActivityManager.PROCESS_STATE_TOP;
19989                     break;
19990             }
19991         }
19992
19993         if (procState >= ActivityManager.PROCESS_STATE_CACHED_EMPTY) {
19994             if (app.hasClientActivities) {
19995                 // This is a cached process, but with client activities.  Mark it so.
19996                 procState = ActivityManager.PROCESS_STATE_CACHED_ACTIVITY_CLIENT;
19997                 app.adjType = "cch-client-act";
19998             } else if (app.treatLikeActivity) {
19999                 // This is a cached process, but somebody wants us to treat it like it has
20000                 // an activity, okay!
20001                 procState = ActivityManager.PROCESS_STATE_CACHED_ACTIVITY;
20002                 app.adjType = "cch-as-act";
20003             }
20004         }
20005
20006         if (adj == ProcessList.SERVICE_ADJ) {
20007             if (doingAll) {
20008                 app.serviceb = mNewNumAServiceProcs > (mNumServiceProcs/3);
20009                 mNewNumServiceProcs++;
20010                 //Slog.i(TAG, "ADJ " + app + " serviceb=" + app.serviceb);
20011                 if (!app.serviceb) {
20012                     // This service isn't far enough down on the LRU list to
20013                     // normally be a B service, but if we are low on RAM and it
20014                     // is large we want to force it down since we would prefer to
20015                     // keep launcher over it.
20016                     if (mLastMemoryLevel > ProcessStats.ADJ_MEM_FACTOR_NORMAL
20017                             && app.lastPss >= mProcessList.getCachedRestoreThresholdKb()) {
20018                         app.serviceHighRam = true;
20019                         app.serviceb = true;
20020                         //Slog.i(TAG, "ADJ " + app + " high ram!");
20021                     } else {
20022                         mNewNumAServiceProcs++;
20023                         //Slog.i(TAG, "ADJ " + app + " not high ram!");
20024                     }
20025                 } else {
20026                     app.serviceHighRam = false;
20027                 }
20028             }
20029             if (app.serviceb) {
20030                 adj = ProcessList.SERVICE_B_ADJ;
20031             }
20032         }
20033
20034         app.curRawAdj = adj;
20035
20036         //Slog.i(TAG, "OOM ADJ " + app + ": pid=" + app.pid +
20037         //      " adj=" + adj + " curAdj=" + app.curAdj + " maxAdj=" + app.maxAdj);
20038         if (adj > app.maxAdj) {
20039             adj = app.maxAdj;
20040             if (app.maxAdj <= ProcessList.PERCEPTIBLE_APP_ADJ) {
20041                 schedGroup = ProcessList.SCHED_GROUP_DEFAULT;
20042             }
20043         }
20044
20045         // Do final modification to adj.  Everything we do between here and applying
20046         // the final setAdj must be done in this function, because we will also use
20047         // it when computing the final cached adj later.  Note that we don't need to
20048         // worry about this for max adj above, since max adj will always be used to
20049         // keep it out of the cached vaues.
20050         app.curAdj = app.modifyRawOomAdj(adj);
20051         app.curSchedGroup = schedGroup;
20052         app.curProcState = procState;
20053         app.foregroundActivities = foregroundActivities;
20054
20055         return app.curRawAdj;
20056     }
20057
20058     /**
20059      * Record new PSS sample for a process.
20060      */
20061     void recordPssSampleLocked(ProcessRecord proc, int procState, long pss, long uss, long swapPss,
20062             long now) {
20063         EventLogTags.writeAmPss(proc.pid, proc.uid, proc.processName, pss * 1024, uss * 1024,
20064                 swapPss * 1024);
20065         proc.lastPssTime = now;
20066         proc.baseProcessTracker.addPss(pss, uss, true, proc.pkgList);
20067         if (DEBUG_PSS) Slog.d(TAG_PSS,
20068                 "PSS of " + proc.toShortString() + ": " + pss + " lastPss=" + proc.lastPss
20069                 + " state=" + ProcessList.makeProcStateString(procState));
20070         if (proc.initialIdlePss == 0) {
20071             proc.initialIdlePss = pss;
20072         }
20073         proc.lastPss = pss;
20074         proc.lastSwapPss = swapPss;
20075         if (procState >= ActivityManager.PROCESS_STATE_HOME) {
20076             proc.lastCachedPss = pss;
20077             proc.lastCachedSwapPss = swapPss;
20078         }
20079
20080         final SparseArray<Pair<Long, String>> watchUids
20081                 = mMemWatchProcesses.getMap().get(proc.processName);
20082         Long check = null;
20083         if (watchUids != null) {
20084             Pair<Long, String> val = watchUids.get(proc.uid);
20085             if (val == null) {
20086                 val = watchUids.get(0);
20087             }
20088             if (val != null) {
20089                 check = val.first;
20090             }
20091         }
20092         if (check != null) {
20093             if ((pss * 1024) >= check && proc.thread != null && mMemWatchDumpProcName == null) {
20094                 boolean isDebuggable = "1".equals(SystemProperties.get(SYSTEM_DEBUGGABLE, "0"));
20095                 if (!isDebuggable) {
20096                     if ((proc.info.flags&ApplicationInfo.FLAG_DEBUGGABLE) != 0) {
20097                         isDebuggable = true;
20098                     }
20099                 }
20100                 if (isDebuggable) {
20101                     Slog.w(TAG, "Process " + proc + " exceeded pss limit " + check + "; reporting");
20102                     final ProcessRecord myProc = proc;
20103                     final File heapdumpFile = DumpHeapProvider.getJavaFile();
20104                     mMemWatchDumpProcName = proc.processName;
20105                     mMemWatchDumpFile = heapdumpFile.toString();
20106                     mMemWatchDumpPid = proc.pid;
20107                     mMemWatchDumpUid = proc.uid;
20108                     BackgroundThread.getHandler().post(new Runnable() {
20109                         @Override
20110                         public void run() {
20111                             revokeUriPermission(ActivityThread.currentActivityThread()
20112                                             .getApplicationThread(),
20113                                     DumpHeapActivity.JAVA_URI,
20114                                     Intent.FLAG_GRANT_READ_URI_PERMISSION
20115                                             | Intent.FLAG_GRANT_WRITE_URI_PERMISSION,
20116                                     UserHandle.myUserId());
20117                             ParcelFileDescriptor fd = null;
20118                             try {
20119                                 heapdumpFile.delete();
20120                                 fd = ParcelFileDescriptor.open(heapdumpFile,
20121                                         ParcelFileDescriptor.MODE_CREATE |
20122                                                 ParcelFileDescriptor.MODE_TRUNCATE |
20123                                                 ParcelFileDescriptor.MODE_WRITE_ONLY |
20124                                                 ParcelFileDescriptor.MODE_APPEND);
20125                                 IApplicationThread thread = myProc.thread;
20126                                 if (thread != null) {
20127                                     try {
20128                                         if (DEBUG_PSS) Slog.d(TAG_PSS,
20129                                                 "Requesting dump heap from "
20130                                                 + myProc + " to " + heapdumpFile);
20131                                         thread.dumpHeap(true, heapdumpFile.toString(), fd);
20132                                     } catch (RemoteException e) {
20133                                     }
20134                                 }
20135                             } catch (FileNotFoundException e) {
20136                                 e.printStackTrace();
20137                             } finally {
20138                                 if (fd != null) {
20139                                     try {
20140                                         fd.close();
20141                                     } catch (IOException e) {
20142                                     }
20143                                 }
20144                             }
20145                         }
20146                     });
20147                 } else {
20148                     Slog.w(TAG, "Process " + proc + " exceeded pss limit " + check
20149                             + ", but debugging not enabled");
20150                 }
20151             }
20152         }
20153     }
20154
20155     /**
20156      * Schedule PSS collection of a process.
20157      */
20158     void requestPssLocked(ProcessRecord proc, int procState) {
20159         if (mPendingPssProcesses.contains(proc)) {
20160             return;
20161         }
20162         if (mPendingPssProcesses.size() == 0) {
20163             mBgHandler.sendEmptyMessage(COLLECT_PSS_BG_MSG);
20164         }
20165         if (DEBUG_PSS) Slog.d(TAG_PSS, "Requesting PSS of: " + proc);
20166         proc.pssProcState = procState;
20167         mPendingPssProcesses.add(proc);
20168     }
20169
20170     /**
20171      * Schedule PSS collection of all processes.
20172      */
20173     void requestPssAllProcsLocked(long now, boolean always, boolean memLowered) {
20174         if (!always) {
20175             if (now < (mLastFullPssTime +
20176                     (memLowered ? FULL_PSS_LOWERED_INTERVAL : FULL_PSS_MIN_INTERVAL))) {
20177                 return;
20178             }
20179         }
20180         if (DEBUG_PSS) Slog.d(TAG_PSS, "Requesting PSS of all procs!  memLowered=" + memLowered);
20181         mLastFullPssTime = now;
20182         mFullPssPending = true;
20183         mPendingPssProcesses.ensureCapacity(mLruProcesses.size());
20184         mPendingPssProcesses.clear();
20185         for (int i = mLruProcesses.size() - 1; i >= 0; i--) {
20186             ProcessRecord app = mLruProcesses.get(i);
20187             if (app.thread == null
20188                     || app.curProcState == ActivityManager.PROCESS_STATE_NONEXISTENT) {
20189                 continue;
20190             }
20191             if (memLowered || now > (app.lastStateTime+ProcessList.PSS_ALL_INTERVAL)) {
20192                 app.pssProcState = app.setProcState;
20193                 app.nextPssTime = ProcessList.computeNextPssTime(app.curProcState, true,
20194                         mTestPssMode, isSleepingLocked(), now);
20195                 mPendingPssProcesses.add(app);
20196             }
20197         }
20198         mBgHandler.sendEmptyMessage(COLLECT_PSS_BG_MSG);
20199     }
20200
20201     public void setTestPssMode(boolean enabled) {
20202         synchronized (this) {
20203             mTestPssMode = enabled;
20204             if (enabled) {
20205                 // Whenever we enable the mode, we want to take a snapshot all of current
20206                 // process mem use.
20207                 requestPssAllProcsLocked(SystemClock.uptimeMillis(), true, true);
20208             }
20209         }
20210     }
20211
20212     /**
20213      * Ask a given process to GC right now.
20214      */
20215     final void performAppGcLocked(ProcessRecord app) {
20216         try {
20217             app.lastRequestedGc = SystemClock.uptimeMillis();
20218             if (app.thread != null) {
20219                 if (app.reportLowMemory) {
20220                     app.reportLowMemory = false;
20221                     app.thread.scheduleLowMemory();
20222                 } else {
20223                     app.thread.processInBackground();
20224                 }
20225             }
20226         } catch (Exception e) {
20227             // whatever.
20228         }
20229     }
20230
20231     /**
20232      * Returns true if things are idle enough to perform GCs.
20233      */
20234     private final boolean canGcNowLocked() {
20235         boolean processingBroadcasts = false;
20236         for (BroadcastQueue q : mBroadcastQueues) {
20237             if (q.mParallelBroadcasts.size() != 0 || q.mOrderedBroadcasts.size() != 0) {
20238                 processingBroadcasts = true;
20239             }
20240         }
20241         return !processingBroadcasts
20242                 && (isSleepingLocked() || mStackSupervisor.allResumedActivitiesIdle());
20243     }
20244
20245     /**
20246      * Perform GCs on all processes that are waiting for it, but only
20247      * if things are idle.
20248      */
20249     final void performAppGcsLocked() {
20250         final int N = mProcessesToGc.size();
20251         if (N <= 0) {
20252             return;
20253         }
20254         if (canGcNowLocked()) {
20255             while (mProcessesToGc.size() > 0) {
20256                 ProcessRecord proc = mProcessesToGc.remove(0);
20257                 if (proc.curRawAdj > ProcessList.PERCEPTIBLE_APP_ADJ || proc.reportLowMemory) {
20258                     if ((proc.lastRequestedGc+GC_MIN_INTERVAL)
20259                             <= SystemClock.uptimeMillis()) {
20260                         // To avoid spamming the system, we will GC processes one
20261                         // at a time, waiting a few seconds between each.
20262                         performAppGcLocked(proc);
20263                         scheduleAppGcsLocked();
20264                         return;
20265                     } else {
20266                         // It hasn't been long enough since we last GCed this
20267                         // process...  put it in the list to wait for its time.
20268                         addProcessToGcListLocked(proc);
20269                         break;
20270                     }
20271                 }
20272             }
20273
20274             scheduleAppGcsLocked();
20275         }
20276     }
20277
20278     /**
20279      * If all looks good, perform GCs on all processes waiting for them.
20280      */
20281     final void performAppGcsIfAppropriateLocked() {
20282         if (canGcNowLocked()) {
20283             performAppGcsLocked();
20284             return;
20285         }
20286         // Still not idle, wait some more.
20287         scheduleAppGcsLocked();
20288     }
20289
20290     /**
20291      * Schedule the execution of all pending app GCs.
20292      */
20293     final void scheduleAppGcsLocked() {
20294         mHandler.removeMessages(GC_BACKGROUND_PROCESSES_MSG);
20295
20296         if (mProcessesToGc.size() > 0) {
20297             // Schedule a GC for the time to the next process.
20298             ProcessRecord proc = mProcessesToGc.get(0);
20299             Message msg = mHandler.obtainMessage(GC_BACKGROUND_PROCESSES_MSG);
20300
20301             long when = proc.lastRequestedGc + GC_MIN_INTERVAL;
20302             long now = SystemClock.uptimeMillis();
20303             if (when < (now+GC_TIMEOUT)) {
20304                 when = now + GC_TIMEOUT;
20305             }
20306             mHandler.sendMessageAtTime(msg, when);
20307         }
20308     }
20309
20310     /**
20311      * Add a process to the array of processes waiting to be GCed.  Keeps the
20312      * list in sorted order by the last GC time.  The process can't already be
20313      * on the list.
20314      */
20315     final void addProcessToGcListLocked(ProcessRecord proc) {
20316         boolean added = false;
20317         for (int i=mProcessesToGc.size()-1; i>=0; i--) {
20318             if (mProcessesToGc.get(i).lastRequestedGc <
20319                     proc.lastRequestedGc) {
20320                 added = true;
20321                 mProcessesToGc.add(i+1, proc);
20322                 break;
20323             }
20324         }
20325         if (!added) {
20326             mProcessesToGc.add(0, proc);
20327         }
20328     }
20329
20330     /**
20331      * Set up to ask a process to GC itself.  This will either do it
20332      * immediately, or put it on the list of processes to gc the next
20333      * time things are idle.
20334      */
20335     final void scheduleAppGcLocked(ProcessRecord app) {
20336         long now = SystemClock.uptimeMillis();
20337         if ((app.lastRequestedGc+GC_MIN_INTERVAL) > now) {
20338             return;
20339         }
20340         if (!mProcessesToGc.contains(app)) {
20341             addProcessToGcListLocked(app);
20342             scheduleAppGcsLocked();
20343         }
20344     }
20345
20346     final void checkExcessivePowerUsageLocked(boolean doKills) {
20347         updateCpuStatsNow();
20348
20349         BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
20350         boolean doWakeKills = doKills;
20351         boolean doCpuKills = doKills;
20352         if (mLastPowerCheckRealtime == 0) {
20353             doWakeKills = false;
20354         }
20355         if (mLastPowerCheckUptime == 0) {
20356             doCpuKills = false;
20357         }
20358         if (stats.isScreenOn()) {
20359             doWakeKills = false;
20360         }
20361         final long curRealtime = SystemClock.elapsedRealtime();
20362         final long realtimeSince = curRealtime - mLastPowerCheckRealtime;
20363         final long curUptime = SystemClock.uptimeMillis();
20364         final long uptimeSince = curUptime - mLastPowerCheckUptime;
20365         mLastPowerCheckRealtime = curRealtime;
20366         mLastPowerCheckUptime = curUptime;
20367         if (realtimeSince < WAKE_LOCK_MIN_CHECK_DURATION) {
20368             doWakeKills = false;
20369         }
20370         if (uptimeSince < CPU_MIN_CHECK_DURATION) {
20371             doCpuKills = false;
20372         }
20373         int i = mLruProcesses.size();
20374         while (i > 0) {
20375             i--;
20376             ProcessRecord app = mLruProcesses.get(i);
20377             if (app.setProcState >= ActivityManager.PROCESS_STATE_HOME) {
20378                 long wtime;
20379                 synchronized (stats) {
20380                     wtime = stats.getProcessWakeTime(app.info.uid,
20381                             app.pid, curRealtime);
20382                 }
20383                 long wtimeUsed = wtime - app.lastWakeTime;
20384                 long cputimeUsed = app.curCpuTime - app.lastCpuTime;
20385                 if (DEBUG_POWER) {
20386                     StringBuilder sb = new StringBuilder(128);
20387                     sb.append("Wake for ");
20388                     app.toShortString(sb);
20389                     sb.append(": over ");
20390                     TimeUtils.formatDuration(realtimeSince, sb);
20391                     sb.append(" used ");
20392                     TimeUtils.formatDuration(wtimeUsed, sb);
20393                     sb.append(" (");
20394                     sb.append((wtimeUsed*100)/realtimeSince);
20395                     sb.append("%)");
20396                     Slog.i(TAG_POWER, sb.toString());
20397                     sb.setLength(0);
20398                     sb.append("CPU for ");
20399                     app.toShortString(sb);
20400                     sb.append(": over ");
20401                     TimeUtils.formatDuration(uptimeSince, sb);
20402                     sb.append(" used ");
20403                     TimeUtils.formatDuration(cputimeUsed, sb);
20404                     sb.append(" (");
20405                     sb.append((cputimeUsed*100)/uptimeSince);
20406                     sb.append("%)");
20407                     Slog.i(TAG_POWER, sb.toString());
20408                 }
20409                 // If a process has held a wake lock for more
20410                 // than 50% of the time during this period,
20411                 // that sounds bad.  Kill!
20412                 if (doWakeKills && realtimeSince > 0
20413                         && ((wtimeUsed*100)/realtimeSince) >= 50) {
20414                     synchronized (stats) {
20415                         stats.reportExcessiveWakeLocked(app.info.uid, app.processName,
20416                                 realtimeSince, wtimeUsed);
20417                     }
20418                     app.kill("excessive wake held " + wtimeUsed + " during " + realtimeSince, true);
20419                     app.baseProcessTracker.reportExcessiveWake(app.pkgList);
20420                 } else if (doCpuKills && uptimeSince > 0
20421                         && ((cputimeUsed*100)/uptimeSince) >= 25) {
20422                     synchronized (stats) {
20423                         stats.reportExcessiveCpuLocked(app.info.uid, app.processName,
20424                                 uptimeSince, cputimeUsed);
20425                     }
20426                     app.kill("excessive cpu " + cputimeUsed + " during " + uptimeSince, true);
20427                     app.baseProcessTracker.reportExcessiveCpu(app.pkgList);
20428                 } else {
20429                     app.lastWakeTime = wtime;
20430                     app.lastCpuTime = app.curCpuTime;
20431                 }
20432             }
20433         }
20434     }
20435
20436     private final boolean applyOomAdjLocked(ProcessRecord app, boolean doingAll, long now,
20437             long nowElapsed) {
20438         boolean success = true;
20439
20440         if (app.curRawAdj != app.setRawAdj) {
20441             app.setRawAdj = app.curRawAdj;
20442         }
20443
20444         int changes = 0;
20445
20446         if (app.curAdj != app.setAdj) {
20447             ProcessList.setOomAdj(app.pid, app.info.uid, app.curAdj);
20448             if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG_OOM_ADJ,
20449                     "Set " + app.pid + " " + app.processName + " adj " + app.curAdj + ": "
20450                     + app.adjType);
20451             app.setAdj = app.curAdj;
20452             app.verifiedAdj = ProcessList.INVALID_ADJ;
20453         }
20454
20455         if (app.setSchedGroup != app.curSchedGroup) {
20456             int oldSchedGroup = app.setSchedGroup;
20457             app.setSchedGroup = app.curSchedGroup;
20458             if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG_OOM_ADJ,
20459                     "Setting sched group of " + app.processName
20460                     + " to " + app.curSchedGroup);
20461             if (app.waitingToKill != null && app.curReceiver == null
20462                     && app.setSchedGroup == ProcessList.SCHED_GROUP_BACKGROUND) {
20463                 app.kill(app.waitingToKill, true);
20464                 success = false;
20465             } else {
20466                 int processGroup;
20467                 switch (app.curSchedGroup) {
20468                     case ProcessList.SCHED_GROUP_BACKGROUND:
20469                         processGroup = Process.THREAD_GROUP_BG_NONINTERACTIVE;
20470                         break;
20471                     case ProcessList.SCHED_GROUP_TOP_APP:
20472                     case ProcessList.SCHED_GROUP_TOP_APP_BOUND:
20473                         processGroup = Process.THREAD_GROUP_TOP_APP;
20474                         break;
20475                     default:
20476                         processGroup = Process.THREAD_GROUP_DEFAULT;
20477                         break;
20478                 }
20479                 long oldId = Binder.clearCallingIdentity();
20480                 try {
20481                     Process.setProcessGroup(app.pid, processGroup);
20482                     if (app.curSchedGroup == ProcessList.SCHED_GROUP_TOP_APP) {
20483                         // do nothing if we already switched to RT
20484                         if (oldSchedGroup != ProcessList.SCHED_GROUP_TOP_APP) {
20485                             // Switch VR thread for app to SCHED_FIFO
20486                             if (mInVrMode && app.vrThreadTid != 0) {
20487                                 try {
20488                                     Process.setThreadScheduler(app.vrThreadTid,
20489                                         Process.SCHED_FIFO | Process.SCHED_RESET_ON_FORK, 1);
20490                                 } catch (IllegalArgumentException e) {
20491                                     // thread died, ignore
20492                                 }
20493                             }
20494                             if (mUseFifoUiScheduling) {
20495                                 // Switch UI pipeline for app to SCHED_FIFO
20496                                 app.savedPriority = Process.getThreadPriority(app.pid);
20497                                 try {
20498                                     Process.setThreadScheduler(app.pid,
20499                                         Process.SCHED_FIFO | Process.SCHED_RESET_ON_FORK, 1);
20500                                 } catch (IllegalArgumentException e) {
20501                                     // thread died, ignore
20502                                 }
20503                                 if (app.renderThreadTid != 0) {
20504                                     try {
20505                                         Process.setThreadScheduler(app.renderThreadTid,
20506                                             Process.SCHED_FIFO | Process.SCHED_RESET_ON_FORK, 1);
20507                                     } catch (IllegalArgumentException e) {
20508                                         // thread died, ignore
20509                                     }
20510                                     if (DEBUG_OOM_ADJ) {
20511                                         Slog.d("UI_FIFO", "Set RenderThread (TID " +
20512                                             app.renderThreadTid + ") to FIFO");
20513                                     }
20514                                 } else {
20515                                     if (DEBUG_OOM_ADJ) {
20516                                         Slog.d("UI_FIFO", "Not setting RenderThread TID");
20517                                     }
20518                                 }
20519                             } else {
20520                                 // Boost priority for top app UI and render threads
20521                                 Process.setThreadPriority(app.pid, -10);
20522                                 if (app.renderThreadTid != 0) {
20523                                     try {
20524                                         Process.setThreadPriority(app.renderThreadTid, -10);
20525                                     } catch (IllegalArgumentException e) {
20526                                         // thread died, ignore
20527                                     }
20528                                 }
20529                             }
20530                         }
20531                     } else if (oldSchedGroup == ProcessList.SCHED_GROUP_TOP_APP &&
20532                                app.curSchedGroup != ProcessList.SCHED_GROUP_TOP_APP) {
20533                         // Reset VR thread to SCHED_OTHER
20534                         // Safe to do even if we're not in VR mode
20535                         if (app.vrThreadTid != 0) {
20536                             Process.setThreadScheduler(app.vrThreadTid, Process.SCHED_OTHER, 0);
20537                         }
20538                         if (mUseFifoUiScheduling) {
20539                             // Reset UI pipeline to SCHED_OTHER
20540                             Process.setThreadScheduler(app.pid, Process.SCHED_OTHER, 0);
20541                             Process.setThreadPriority(app.pid, app.savedPriority);
20542                             if (app.renderThreadTid != 0) {
20543                                 Process.setThreadScheduler(app.renderThreadTid,
20544                                     Process.SCHED_OTHER, 0);
20545                                 Process.setThreadPriority(app.renderThreadTid, -4);
20546                             }
20547                         } else {
20548                             // Reset priority for top app UI and render threads
20549                             Process.setThreadPriority(app.pid, 0);
20550                             if (app.renderThreadTid != 0) {
20551                                 Process.setThreadPriority(app.renderThreadTid, 0);
20552                             }
20553                         }
20554                     }
20555                 } catch (Exception e) {
20556                     Slog.w(TAG, "Failed setting process group of " + app.pid
20557                             + " to " + app.curSchedGroup);
20558                     e.printStackTrace();
20559                 } finally {
20560                     Binder.restoreCallingIdentity(oldId);
20561                 }
20562             }
20563         }
20564         if (app.repForegroundActivities != app.foregroundActivities) {
20565             app.repForegroundActivities = app.foregroundActivities;
20566             changes |= ProcessChangeItem.CHANGE_ACTIVITIES;
20567         }
20568         if (app.repProcState != app.curProcState) {
20569             app.repProcState = app.curProcState;
20570             changes |= ProcessChangeItem.CHANGE_PROCESS_STATE;
20571             if (app.thread != null) {
20572                 try {
20573                     if (false) {
20574                         //RuntimeException h = new RuntimeException("here");
20575                         Slog.i(TAG, "Sending new process state " + app.repProcState
20576                                 + " to " + app /*, h*/);
20577                     }
20578                     app.thread.setProcessState(app.repProcState);
20579                 } catch (RemoteException e) {
20580                 }
20581             }
20582         }
20583         if (app.setProcState == ActivityManager.PROCESS_STATE_NONEXISTENT
20584                 || ProcessList.procStatesDifferForMem(app.curProcState, app.setProcState)) {
20585             if (false && mTestPssMode && app.setProcState >= 0 && app.lastStateTime <= (now-200)) {
20586                 // Experimental code to more aggressively collect pss while
20587                 // running test...  the problem is that this tends to collect
20588                 // the data right when a process is transitioning between process
20589                 // states, which well tend to give noisy data.
20590                 long start = SystemClock.uptimeMillis();
20591                 long pss = Debug.getPss(app.pid, mTmpLong, null);
20592                 recordPssSampleLocked(app, app.curProcState, pss, mTmpLong[0], mTmpLong[1], now);
20593                 mPendingPssProcesses.remove(app);
20594                 Slog.i(TAG, "Recorded pss for " + app + " state " + app.setProcState
20595                         + " to " + app.curProcState + ": "
20596                         + (SystemClock.uptimeMillis()-start) + "ms");
20597             }
20598             app.lastStateTime = now;
20599             app.nextPssTime = ProcessList.computeNextPssTime(app.curProcState, true,
20600                     mTestPssMode, isSleepingLocked(), now);
20601             if (DEBUG_PSS) Slog.d(TAG_PSS, "Process state change from "
20602                     + ProcessList.makeProcStateString(app.setProcState) + " to "
20603                     + ProcessList.makeProcStateString(app.curProcState) + " next pss in "
20604                     + (app.nextPssTime-now) + ": " + app);
20605         } else {
20606             if (now > app.nextPssTime || (now > (app.lastPssTime+ProcessList.PSS_MAX_INTERVAL)
20607                     && now > (app.lastStateTime+ProcessList.minTimeFromStateChange(
20608                     mTestPssMode)))) {
20609                 requestPssLocked(app, app.setProcState);
20610                 app.nextPssTime = ProcessList.computeNextPssTime(app.curProcState, false,
20611                         mTestPssMode, isSleepingLocked(), now);
20612             } else if (false && DEBUG_PSS) Slog.d(TAG_PSS,
20613                     "Not requesting PSS of " + app + ": next=" + (app.nextPssTime-now));
20614         }
20615         if (app.setProcState != app.curProcState) {
20616             if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG_OOM_ADJ,
20617                     "Proc state change of " + app.processName
20618                             + " to " + app.curProcState);
20619             boolean setImportant = app.setProcState < ActivityManager.PROCESS_STATE_SERVICE;
20620             boolean curImportant = app.curProcState < ActivityManager.PROCESS_STATE_SERVICE;
20621             if (setImportant && !curImportant) {
20622                 // This app is no longer something we consider important enough to allow to
20623                 // use arbitrary amounts of battery power.  Note
20624                 // its current wake lock time to later know to kill it if
20625                 // it is not behaving well.
20626                 BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
20627                 synchronized (stats) {
20628                     app.lastWakeTime = stats.getProcessWakeTime(app.info.uid,
20629                             app.pid, nowElapsed);
20630                 }
20631                 app.lastCpuTime = app.curCpuTime;
20632
20633             }
20634             // Inform UsageStats of important process state change
20635             // Must be called before updating setProcState
20636             maybeUpdateUsageStatsLocked(app, nowElapsed);
20637
20638             app.setProcState = app.curProcState;
20639             if (app.setProcState >= ActivityManager.PROCESS_STATE_HOME) {
20640                 app.notCachedSinceIdle = false;
20641             }
20642             if (!doingAll) {
20643                 setProcessTrackerStateLocked(app, mProcessStats.getMemFactorLocked(), now);
20644             } else {
20645                 app.procStateChanged = true;
20646             }
20647         } else if (app.reportedInteraction && (nowElapsed-app.interactionEventTime)
20648                 > USAGE_STATS_INTERACTION_INTERVAL) {
20649             // For apps that sit around for a long time in the interactive state, we need
20650             // to report this at least once a day so they don't go idle.
20651             maybeUpdateUsageStatsLocked(app, nowElapsed);
20652         }
20653
20654         if (changes != 0) {
20655             if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG_PROCESS_OBSERVERS,
20656                     "Changes in " + app + ": " + changes);
20657             int i = mPendingProcessChanges.size()-1;
20658             ProcessChangeItem item = null;
20659             while (i >= 0) {
20660                 item = mPendingProcessChanges.get(i);
20661                 if (item.pid == app.pid) {
20662                     if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG_PROCESS_OBSERVERS,
20663                             "Re-using existing item: " + item);
20664                     break;
20665                 }
20666                 i--;
20667             }
20668             if (i < 0) {
20669                 // No existing item in pending changes; need a new one.
20670                 final int NA = mAvailProcessChanges.size();
20671                 if (NA > 0) {
20672                     item = mAvailProcessChanges.remove(NA-1);
20673                     if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG_PROCESS_OBSERVERS,
20674                             "Retrieving available item: " + item);
20675                 } else {
20676                     item = new ProcessChangeItem();
20677                     if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG_PROCESS_OBSERVERS,
20678                             "Allocating new item: " + item);
20679                 }
20680                 item.changes = 0;
20681                 item.pid = app.pid;
20682                 item.uid = app.info.uid;
20683                 if (mPendingProcessChanges.size() == 0) {
20684                     if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG_PROCESS_OBSERVERS,
20685                             "*** Enqueueing dispatch processes changed!");
20686                     mUiHandler.obtainMessage(DISPATCH_PROCESSES_CHANGED_UI_MSG).sendToTarget();
20687                 }
20688                 mPendingProcessChanges.add(item);
20689             }
20690             item.changes |= changes;
20691             item.processState = app.repProcState;
20692             item.foregroundActivities = app.repForegroundActivities;
20693             if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG_PROCESS_OBSERVERS,
20694                     "Item " + Integer.toHexString(System.identityHashCode(item))
20695                     + " " + app.toShortString() + ": changes=" + item.changes
20696                     + " procState=" + item.processState
20697                     + " foreground=" + item.foregroundActivities
20698                     + " type=" + app.adjType + " source=" + app.adjSource
20699                     + " target=" + app.adjTarget);
20700         }
20701
20702         return success;
20703     }
20704
20705     private final void enqueueUidChangeLocked(UidRecord uidRec, int uid, int change) {
20706         final UidRecord.ChangeItem pendingChange;
20707         if (uidRec == null || uidRec.pendingChange == null) {
20708             if (mPendingUidChanges.size() == 0) {
20709                 if (DEBUG_UID_OBSERVERS) Slog.i(TAG_UID_OBSERVERS,
20710                         "*** Enqueueing dispatch uid changed!");
20711                 mUiHandler.obtainMessage(DISPATCH_UIDS_CHANGED_UI_MSG).sendToTarget();
20712             }
20713             final int NA = mAvailUidChanges.size();
20714             if (NA > 0) {
20715                 pendingChange = mAvailUidChanges.remove(NA-1);
20716                 if (DEBUG_UID_OBSERVERS) Slog.i(TAG_UID_OBSERVERS,
20717                         "Retrieving available item: " + pendingChange);
20718             } else {
20719                 pendingChange = new UidRecord.ChangeItem();
20720                 if (DEBUG_UID_OBSERVERS) Slog.i(TAG_UID_OBSERVERS,
20721                         "Allocating new item: " + pendingChange);
20722             }
20723             if (uidRec != null) {
20724                 uidRec.pendingChange = pendingChange;
20725                 if (change == UidRecord.CHANGE_GONE && !uidRec.idle) {
20726                     // If this uid is going away, and we haven't yet reported it is gone,
20727                     // then do so now.
20728                     change = UidRecord.CHANGE_GONE_IDLE;
20729                 }
20730             } else if (uid < 0) {
20731                 throw new IllegalArgumentException("No UidRecord or uid");
20732             }
20733             pendingChange.uidRecord = uidRec;
20734             pendingChange.uid = uidRec != null ? uidRec.uid : uid;
20735             mPendingUidChanges.add(pendingChange);
20736         } else {
20737             pendingChange = uidRec.pendingChange;
20738             if (change == UidRecord.CHANGE_GONE && pendingChange.change == UidRecord.CHANGE_IDLE) {
20739                 change = UidRecord.CHANGE_GONE_IDLE;
20740             }
20741         }
20742         pendingChange.change = change;
20743         pendingChange.processState = uidRec != null
20744                 ? uidRec.setProcState : ActivityManager.PROCESS_STATE_NONEXISTENT;
20745     }
20746
20747     private void maybeUpdateProviderUsageStatsLocked(ProcessRecord app, String providerPkgName,
20748             String authority) {
20749         if (app == null) return;
20750         if (app.curProcState <= ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND) {
20751             UserState userState = mUserController.getStartedUserStateLocked(app.userId);
20752             if (userState == null) return;
20753             final long now = SystemClock.elapsedRealtime();
20754             Long lastReported = userState.mProviderLastReportedFg.get(authority);
20755             if (lastReported == null || lastReported < now - 60 * 1000L) {
20756                 if (mSystemReady) {
20757                     // Cannot touch the user stats if not system ready
20758                     mUsageStatsService.reportContentProviderUsage(
20759                             authority, providerPkgName, app.userId);
20760                 }
20761                 userState.mProviderLastReportedFg.put(authority, now);
20762             }
20763         }
20764     }
20765
20766     private void maybeUpdateUsageStatsLocked(ProcessRecord app, long nowElapsed) {
20767         if (DEBUG_USAGE_STATS) {
20768             Slog.d(TAG, "Checking proc [" + Arrays.toString(app.getPackageList())
20769                     + "] state changes: old = " + app.setProcState + ", new = "
20770                     + app.curProcState);
20771         }
20772         if (mUsageStatsService == null) {
20773             return;
20774         }
20775         boolean isInteraction;
20776         // To avoid some abuse patterns, we are going to be careful about what we consider
20777         // to be an app interaction.  Being the top activity doesn't count while the display
20778         // is sleeping, nor do short foreground services.
20779         if (app.curProcState <= ActivityManager.PROCESS_STATE_BOUND_FOREGROUND_SERVICE) {
20780             isInteraction = true;
20781             app.fgInteractionTime = 0;
20782         } else if (app.curProcState <= ActivityManager.PROCESS_STATE_TOP_SLEEPING) {
20783             if (app.fgInteractionTime == 0) {
20784                 app.fgInteractionTime = nowElapsed;
20785                 isInteraction = false;
20786             } else {
20787                 isInteraction = nowElapsed > app.fgInteractionTime + SERVICE_USAGE_INTERACTION_TIME;
20788             }
20789         } else {
20790             // If the app was being forced to the foreground, by say a Toast, then
20791             // no need to treat it as an interaction
20792             isInteraction = app.forcingToForeground == null
20793                     && app.curProcState <= ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND;
20794             app.fgInteractionTime = 0;
20795         }
20796         if (isInteraction && (!app.reportedInteraction
20797                 || (nowElapsed-app.interactionEventTime) > USAGE_STATS_INTERACTION_INTERVAL)) {
20798             app.interactionEventTime = nowElapsed;
20799             String[] packages = app.getPackageList();
20800             if (packages != null) {
20801                 for (int i = 0; i < packages.length; i++) {
20802                     mUsageStatsService.reportEvent(packages[i], app.userId,
20803                             UsageEvents.Event.SYSTEM_INTERACTION);
20804                 }
20805             }
20806         }
20807         app.reportedInteraction = isInteraction;
20808         if (!isInteraction) {
20809             app.interactionEventTime = 0;
20810         }
20811     }
20812
20813     private final void setProcessTrackerStateLocked(ProcessRecord proc, int memFactor, long now) {
20814         if (proc.thread != null) {
20815             if (proc.baseProcessTracker != null) {
20816                 proc.baseProcessTracker.setState(proc.repProcState, memFactor, now, proc.pkgList);
20817             }
20818         }
20819     }
20820
20821     private final boolean updateOomAdjLocked(ProcessRecord app, int cachedAdj,
20822             ProcessRecord TOP_APP, boolean doingAll, long now) {
20823         if (app.thread == null) {
20824             return false;
20825         }
20826
20827         computeOomAdjLocked(app, cachedAdj, TOP_APP, doingAll, now);
20828
20829         return applyOomAdjLocked(app, doingAll, now, SystemClock.elapsedRealtime());
20830     }
20831
20832     final void updateProcessForegroundLocked(ProcessRecord proc, boolean isForeground,
20833             boolean oomAdj) {
20834         if (isForeground != proc.foregroundServices) {
20835             proc.foregroundServices = isForeground;
20836             ArrayList<ProcessRecord> curProcs = mForegroundPackages.get(proc.info.packageName,
20837                     proc.info.uid);
20838             if (isForeground) {
20839                 if (curProcs == null) {
20840                     curProcs = new ArrayList<ProcessRecord>();
20841                     mForegroundPackages.put(proc.info.packageName, proc.info.uid, curProcs);
20842                 }
20843                 if (!curProcs.contains(proc)) {
20844                     curProcs.add(proc);
20845                     mBatteryStatsService.noteEvent(BatteryStats.HistoryItem.EVENT_FOREGROUND_START,
20846                             proc.info.packageName, proc.info.uid);
20847                 }
20848             } else {
20849                 if (curProcs != null) {
20850                     if (curProcs.remove(proc)) {
20851                         mBatteryStatsService.noteEvent(
20852                                 BatteryStats.HistoryItem.EVENT_FOREGROUND_FINISH,
20853                                 proc.info.packageName, proc.info.uid);
20854                         if (curProcs.size() <= 0) {
20855                             mForegroundPackages.remove(proc.info.packageName, proc.info.uid);
20856                         }
20857                     }
20858                 }
20859             }
20860             if (oomAdj) {
20861                 updateOomAdjLocked();
20862             }
20863         }
20864     }
20865
20866     private final ActivityRecord resumedAppLocked() {
20867         ActivityRecord act = mStackSupervisor.resumedAppLocked();
20868         String pkg;
20869         int uid;
20870         if (act != null) {
20871             pkg = act.packageName;
20872             uid = act.info.applicationInfo.uid;
20873         } else {
20874             pkg = null;
20875             uid = -1;
20876         }
20877         // Has the UID or resumed package name changed?
20878         if (uid != mCurResumedUid || (pkg != mCurResumedPackage
20879                 && (pkg == null || !pkg.equals(mCurResumedPackage)))) {
20880             if (mCurResumedPackage != null) {
20881                 mBatteryStatsService.noteEvent(BatteryStats.HistoryItem.EVENT_TOP_FINISH,
20882                         mCurResumedPackage, mCurResumedUid);
20883             }
20884             mCurResumedPackage = pkg;
20885             mCurResumedUid = uid;
20886             if (mCurResumedPackage != null) {
20887                 mBatteryStatsService.noteEvent(BatteryStats.HistoryItem.EVENT_TOP_START,
20888                         mCurResumedPackage, mCurResumedUid);
20889             }
20890         }
20891         return act;
20892     }
20893
20894     final boolean updateOomAdjLocked(ProcessRecord app) {
20895         final ActivityRecord TOP_ACT = resumedAppLocked();
20896         final ProcessRecord TOP_APP = TOP_ACT != null ? TOP_ACT.app : null;
20897         final boolean wasCached = app.cached;
20898
20899         mAdjSeq++;
20900
20901         // This is the desired cached adjusment we want to tell it to use.
20902         // If our app is currently cached, we know it, and that is it.  Otherwise,
20903         // we don't know it yet, and it needs to now be cached we will then
20904         // need to do a complete oom adj.
20905         final int cachedAdj = app.curRawAdj >= ProcessList.CACHED_APP_MIN_ADJ
20906                 ? app.curRawAdj : ProcessList.UNKNOWN_ADJ;
20907         boolean success = updateOomAdjLocked(app, cachedAdj, TOP_APP, false,
20908                 SystemClock.uptimeMillis());
20909         if (wasCached != app.cached || app.curRawAdj == ProcessList.UNKNOWN_ADJ) {
20910             // Changed to/from cached state, so apps after it in the LRU
20911             // list may also be changed.
20912             updateOomAdjLocked();
20913         }
20914         return success;
20915     }
20916
20917     final void updateOomAdjLocked() {
20918         final ActivityRecord TOP_ACT = resumedAppLocked();
20919         final ProcessRecord TOP_APP = TOP_ACT != null ? TOP_ACT.app : null;
20920         final long now = SystemClock.uptimeMillis();
20921         final long nowElapsed = SystemClock.elapsedRealtime();
20922         final long oldTime = now - ProcessList.MAX_EMPTY_TIME;
20923         final int N = mLruProcesses.size();
20924
20925         if (false) {
20926             RuntimeException e = new RuntimeException();
20927             e.fillInStackTrace();
20928             Slog.i(TAG, "updateOomAdj: top=" + TOP_ACT, e);
20929         }
20930
20931         // Reset state in all uid records.
20932         for (int i=mActiveUids.size()-1; i>=0; i--) {
20933             final UidRecord uidRec = mActiveUids.valueAt(i);
20934             if (false && DEBUG_UID_OBSERVERS) Slog.i(TAG_UID_OBSERVERS,
20935                     "Starting update of " + uidRec);
20936             uidRec.reset();
20937         }
20938
20939         mStackSupervisor.rankTaskLayersIfNeeded();
20940
20941         mAdjSeq++;
20942         mNewNumServiceProcs = 0;
20943         mNewNumAServiceProcs = 0;
20944
20945         final int emptyProcessLimit;
20946         final int cachedProcessLimit;
20947         if (mProcessLimit <= 0) {
20948             emptyProcessLimit = cachedProcessLimit = 0;
20949         } else if (mProcessLimit == 1) {
20950             emptyProcessLimit = 1;
20951             cachedProcessLimit = 0;
20952         } else {
20953             emptyProcessLimit = ProcessList.computeEmptyProcessLimit(mProcessLimit);
20954             cachedProcessLimit = mProcessLimit - emptyProcessLimit;
20955         }
20956
20957         // Let's determine how many processes we have running vs.
20958         // how many slots we have for background processes; we may want
20959         // to put multiple processes in a slot of there are enough of
20960         // them.
20961         int numSlots = (ProcessList.CACHED_APP_MAX_ADJ
20962                 - ProcessList.CACHED_APP_MIN_ADJ + 1) / 2;
20963         int numEmptyProcs = N - mNumNonCachedProcs - mNumCachedHiddenProcs;
20964         if (numEmptyProcs > cachedProcessLimit) {
20965             // If there are more empty processes than our limit on cached
20966             // processes, then use the cached process limit for the factor.
20967             // This ensures that the really old empty processes get pushed
20968             // down to the bottom, so if we are running low on memory we will
20969             // have a better chance at keeping around more cached processes
20970             // instead of a gazillion empty processes.
20971             numEmptyProcs = cachedProcessLimit;
20972         }
20973         int emptyFactor = numEmptyProcs/numSlots;
20974         if (emptyFactor < 1) emptyFactor = 1;
20975         int cachedFactor = (mNumCachedHiddenProcs > 0 ? mNumCachedHiddenProcs : 1)/numSlots;
20976         if (cachedFactor < 1) cachedFactor = 1;
20977         int stepCached = 0;
20978         int stepEmpty = 0;
20979         int numCached = 0;
20980         int numEmpty = 0;
20981         int numTrimming = 0;
20982
20983         mNumNonCachedProcs = 0;
20984         mNumCachedHiddenProcs = 0;
20985
20986         // First update the OOM adjustment for each of the
20987         // application processes based on their current state.
20988         int curCachedAdj = ProcessList.CACHED_APP_MIN_ADJ;
20989         int nextCachedAdj = curCachedAdj+1;
20990         int curEmptyAdj = ProcessList.CACHED_APP_MIN_ADJ;
20991         int nextEmptyAdj = curEmptyAdj+2;
20992         for (int i=N-1; i>=0; i--) {
20993             ProcessRecord app = mLruProcesses.get(i);
20994             if (!app.killedByAm && app.thread != null) {
20995                 app.procStateChanged = false;
20996                 computeOomAdjLocked(app, ProcessList.UNKNOWN_ADJ, TOP_APP, true, now);
20997
20998                 // If we haven't yet assigned the final cached adj
20999                 // to the process, do that now.
21000                 if (app.curAdj >= ProcessList.UNKNOWN_ADJ) {
21001                     switch (app.curProcState) {
21002                         case ActivityManager.PROCESS_STATE_CACHED_ACTIVITY:
21003                         case ActivityManager.PROCESS_STATE_CACHED_ACTIVITY_CLIENT:
21004                             // This process is a cached process holding activities...
21005                             // assign it the next cached value for that type, and then
21006                             // step that cached level.
21007                             app.curRawAdj = curCachedAdj;
21008                             app.curAdj = app.modifyRawOomAdj(curCachedAdj);
21009                             if (DEBUG_LRU && false) Slog.d(TAG_LRU, "Assigning activity LRU #" + i
21010                                     + " adj: " + app.curAdj + " (curCachedAdj=" + curCachedAdj
21011                                     + ")");
21012                             if (curCachedAdj != nextCachedAdj) {
21013                                 stepCached++;
21014                                 if (stepCached >= cachedFactor) {
21015                                     stepCached = 0;
21016                                     curCachedAdj = nextCachedAdj;
21017                                     nextCachedAdj += 2;
21018                                     if (nextCachedAdj > ProcessList.CACHED_APP_MAX_ADJ) {
21019                                         nextCachedAdj = ProcessList.CACHED_APP_MAX_ADJ;
21020                                     }
21021                                 }
21022                             }
21023                             break;
21024                         default:
21025                             // For everything else, assign next empty cached process
21026                             // level and bump that up.  Note that this means that
21027                             // long-running services that have dropped down to the
21028                             // cached level will be treated as empty (since their process
21029                             // state is still as a service), which is what we want.
21030                             app.curRawAdj = curEmptyAdj;
21031                             app.curAdj = app.modifyRawOomAdj(curEmptyAdj);
21032                             if (DEBUG_LRU && false) Slog.d(TAG_LRU, "Assigning empty LRU #" + i
21033                                     + " adj: " + app.curAdj + " (curEmptyAdj=" + curEmptyAdj
21034                                     + ")");
21035                             if (curEmptyAdj != nextEmptyAdj) {
21036                                 stepEmpty++;
21037                                 if (stepEmpty >= emptyFactor) {
21038                                     stepEmpty = 0;
21039                                     curEmptyAdj = nextEmptyAdj;
21040                                     nextEmptyAdj += 2;
21041                                     if (nextEmptyAdj > ProcessList.CACHED_APP_MAX_ADJ) {
21042                                         nextEmptyAdj = ProcessList.CACHED_APP_MAX_ADJ;
21043                                     }
21044                                 }
21045                             }
21046                             break;
21047                     }
21048                 }
21049
21050                 applyOomAdjLocked(app, true, now, nowElapsed);
21051
21052                 // Count the number of process types.
21053                 switch (app.curProcState) {
21054                     case ActivityManager.PROCESS_STATE_CACHED_ACTIVITY:
21055                     case ActivityManager.PROCESS_STATE_CACHED_ACTIVITY_CLIENT:
21056                         mNumCachedHiddenProcs++;
21057                         numCached++;
21058                         if (numCached > cachedProcessLimit) {
21059                             app.kill("cached #" + numCached, true);
21060                         }
21061                         break;
21062                     case ActivityManager.PROCESS_STATE_CACHED_EMPTY:
21063                         if (numEmpty > ProcessList.TRIM_EMPTY_APPS
21064                                 && app.lastActivityTime < oldTime) {
21065                             app.kill("empty for "
21066                                     + ((oldTime + ProcessList.MAX_EMPTY_TIME - app.lastActivityTime)
21067                                     / 1000) + "s", true);
21068                         } else {
21069                             numEmpty++;
21070                             if (numEmpty > emptyProcessLimit) {
21071                                 app.kill("empty #" + numEmpty, true);
21072                             }
21073                         }
21074                         break;
21075                     default:
21076                         mNumNonCachedProcs++;
21077                         break;
21078                 }
21079
21080                 if (app.isolated && app.services.size() <= 0) {
21081                     // If this is an isolated process, and there are no
21082                     // services running in it, then the process is no longer
21083                     // needed.  We agressively kill these because we can by
21084                     // definition not re-use the same process again, and it is
21085                     // good to avoid having whatever code was running in them
21086                     // left sitting around after no longer needed.
21087                     app.kill("isolated not needed", true);
21088                 } else {
21089                     // Keeping this process, update its uid.
21090                     final UidRecord uidRec = app.uidRecord;
21091                     if (uidRec != null && uidRec.curProcState > app.curProcState) {
21092                         uidRec.curProcState = app.curProcState;
21093                     }
21094                 }
21095
21096                 if (app.curProcState >= ActivityManager.PROCESS_STATE_HOME
21097                         && !app.killedByAm) {
21098                     numTrimming++;
21099                 }
21100             }
21101         }
21102
21103         mNumServiceProcs = mNewNumServiceProcs;
21104
21105         // Now determine the memory trimming level of background processes.
21106         // Unfortunately we need to start at the back of the list to do this
21107         // properly.  We only do this if the number of background apps we
21108         // are managing to keep around is less than half the maximum we desire;
21109         // if we are keeping a good number around, we'll let them use whatever
21110         // memory they want.
21111         final int numCachedAndEmpty = numCached + numEmpty;
21112         int memFactor;
21113         if (numCached <= ProcessList.TRIM_CACHED_APPS
21114                 && numEmpty <= ProcessList.TRIM_EMPTY_APPS) {
21115             if (numCachedAndEmpty <= ProcessList.TRIM_CRITICAL_THRESHOLD) {
21116                 memFactor = ProcessStats.ADJ_MEM_FACTOR_CRITICAL;
21117             } else if (numCachedAndEmpty <= ProcessList.TRIM_LOW_THRESHOLD) {
21118                 memFactor = ProcessStats.ADJ_MEM_FACTOR_LOW;
21119             } else {
21120                 memFactor = ProcessStats.ADJ_MEM_FACTOR_MODERATE;
21121             }
21122         } else {
21123             memFactor = ProcessStats.ADJ_MEM_FACTOR_NORMAL;
21124         }
21125         // We always allow the memory level to go up (better).  We only allow it to go
21126         // down if we are in a state where that is allowed, *and* the total number of processes
21127         // has gone down since last time.
21128         if (DEBUG_OOM_ADJ) Slog.d(TAG_OOM_ADJ, "oom: memFactor=" + memFactor
21129                 + " last=" + mLastMemoryLevel + " allowLow=" + mAllowLowerMemLevel
21130                 + " numProcs=" + mLruProcesses.size() + " last=" + mLastNumProcesses);
21131         if (memFactor > mLastMemoryLevel) {
21132             if (!mAllowLowerMemLevel || mLruProcesses.size() >= mLastNumProcesses) {
21133                 memFactor = mLastMemoryLevel;
21134                 if (DEBUG_OOM_ADJ) Slog.d(TAG_OOM_ADJ, "Keeping last mem factor!");
21135             }
21136         }
21137         if (memFactor != mLastMemoryLevel) {
21138             EventLogTags.writeAmMemFactor(memFactor, mLastMemoryLevel);
21139         }
21140         mLastMemoryLevel = memFactor;
21141         mLastNumProcesses = mLruProcesses.size();
21142         boolean allChanged = mProcessStats.setMemFactorLocked(memFactor, !isSleepingLocked(), now);
21143         final int trackerMemFactor = mProcessStats.getMemFactorLocked();
21144         if (memFactor != ProcessStats.ADJ_MEM_FACTOR_NORMAL) {
21145             if (mLowRamStartTime == 0) {
21146                 mLowRamStartTime = now;
21147             }
21148             int step = 0;
21149             int fgTrimLevel;
21150             switch (memFactor) {
21151                 case ProcessStats.ADJ_MEM_FACTOR_CRITICAL:
21152                     fgTrimLevel = ComponentCallbacks2.TRIM_MEMORY_RUNNING_CRITICAL;
21153                     break;
21154                 case ProcessStats.ADJ_MEM_FACTOR_LOW:
21155                     fgTrimLevel = ComponentCallbacks2.TRIM_MEMORY_RUNNING_LOW;
21156                     break;
21157                 default:
21158                     fgTrimLevel = ComponentCallbacks2.TRIM_MEMORY_RUNNING_MODERATE;
21159                     break;
21160             }
21161             int factor = numTrimming/3;
21162             int minFactor = 2;
21163             if (mHomeProcess != null) minFactor++;
21164             if (mPreviousProcess != null) minFactor++;
21165             if (factor < minFactor) factor = minFactor;
21166             int curLevel = ComponentCallbacks2.TRIM_MEMORY_COMPLETE;
21167             for (int i=N-1; i>=0; i--) {
21168                 ProcessRecord app = mLruProcesses.get(i);
21169                 if (allChanged || app.procStateChanged) {
21170                     setProcessTrackerStateLocked(app, trackerMemFactor, now);
21171                     app.procStateChanged = false;
21172                 }
21173                 if (app.curProcState >= ActivityManager.PROCESS_STATE_HOME
21174                         && !app.killedByAm) {
21175                     if (app.trimMemoryLevel < curLevel && app.thread != null) {
21176                         try {
21177                             if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG_OOM_ADJ,
21178                                     "Trimming memory of " + app.processName + " to " + curLevel);
21179                             app.thread.scheduleTrimMemory(curLevel);
21180                         } catch (RemoteException e) {
21181                         }
21182                         if (false) {
21183                             // For now we won't do this; our memory trimming seems
21184                             // to be good enough at this point that destroying
21185                             // activities causes more harm than good.
21186                             if (curLevel >= ComponentCallbacks2.TRIM_MEMORY_COMPLETE
21187                                     && app != mHomeProcess && app != mPreviousProcess) {
21188                                 // Need to do this on its own message because the stack may not
21189                                 // be in a consistent state at this point.
21190                                 // For these apps we will also finish their activities
21191                                 // to help them free memory.
21192                                 mStackSupervisor.scheduleDestroyAllActivities(app, "trim");
21193                             }
21194                         }
21195                     }
21196                     app.trimMemoryLevel = curLevel;
21197                     step++;
21198                     if (step >= factor) {
21199                         step = 0;
21200                         switch (curLevel) {
21201                             case ComponentCallbacks2.TRIM_MEMORY_COMPLETE:
21202                                 curLevel = ComponentCallbacks2.TRIM_MEMORY_MODERATE;
21203                                 break;
21204                             case ComponentCallbacks2.TRIM_MEMORY_MODERATE:
21205                                 curLevel = ComponentCallbacks2.TRIM_MEMORY_BACKGROUND;
21206                                 break;
21207                         }
21208                     }
21209                 } else if (app.curProcState == ActivityManager.PROCESS_STATE_HEAVY_WEIGHT) {
21210                     if (app.trimMemoryLevel < ComponentCallbacks2.TRIM_MEMORY_BACKGROUND
21211                             && app.thread != null) {
21212                         try {
21213                             if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG_OOM_ADJ,
21214                                     "Trimming memory of heavy-weight " + app.processName
21215                                     + " to " + ComponentCallbacks2.TRIM_MEMORY_BACKGROUND);
21216                             app.thread.scheduleTrimMemory(
21217                                     ComponentCallbacks2.TRIM_MEMORY_BACKGROUND);
21218                         } catch (RemoteException e) {
21219                         }
21220                     }
21221                     app.trimMemoryLevel = ComponentCallbacks2.TRIM_MEMORY_BACKGROUND;
21222                 } else {
21223                     if ((app.curProcState >= ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND
21224                             || app.systemNoUi) && app.pendingUiClean) {
21225                         // If this application is now in the background and it
21226                         // had done UI, then give it the special trim level to
21227                         // have it free UI resources.
21228                         final int level = ComponentCallbacks2.TRIM_MEMORY_UI_HIDDEN;
21229                         if (app.trimMemoryLevel < level && app.thread != null) {
21230                             try {
21231                                 if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG_OOM_ADJ,
21232                                         "Trimming memory of bg-ui " + app.processName
21233                                         + " to " + level);
21234                                 app.thread.scheduleTrimMemory(level);
21235                             } catch (RemoteException e) {
21236                             }
21237                         }
21238                         app.pendingUiClean = false;
21239                     }
21240                     if (app.trimMemoryLevel < fgTrimLevel && app.thread != null) {
21241                         try {
21242                             if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG_OOM_ADJ,
21243                                     "Trimming memory of fg " + app.processName
21244                                     + " to " + fgTrimLevel);
21245                             app.thread.scheduleTrimMemory(fgTrimLevel);
21246                         } catch (RemoteException e) {
21247                         }
21248                     }
21249                     app.trimMemoryLevel = fgTrimLevel;
21250                 }
21251             }
21252         } else {
21253             if (mLowRamStartTime != 0) {
21254                 mLowRamTimeSinceLastIdle += now - mLowRamStartTime;
21255                 mLowRamStartTime = 0;
21256             }
21257             for (int i=N-1; i>=0; i--) {
21258                 ProcessRecord app = mLruProcesses.get(i);
21259                 if (allChanged || app.procStateChanged) {
21260                     setProcessTrackerStateLocked(app, trackerMemFactor, now);
21261                     app.procStateChanged = false;
21262                 }
21263                 if ((app.curProcState >= ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND
21264                         || app.systemNoUi) && app.pendingUiClean) {
21265                     if (app.trimMemoryLevel < ComponentCallbacks2.TRIM_MEMORY_UI_HIDDEN
21266                             && app.thread != null) {
21267                         try {
21268                             if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG_OOM_ADJ,
21269                                     "Trimming memory of ui hidden " + app.processName
21270                                     + " to " + ComponentCallbacks2.TRIM_MEMORY_UI_HIDDEN);
21271                             app.thread.scheduleTrimMemory(
21272                                     ComponentCallbacks2.TRIM_MEMORY_UI_HIDDEN);
21273                         } catch (RemoteException e) {
21274                         }
21275                     }
21276                     app.pendingUiClean = false;
21277                 }
21278                 app.trimMemoryLevel = 0;
21279             }
21280         }
21281
21282         if (mAlwaysFinishActivities) {
21283             // Need to do this on its own message because the stack may not
21284             // be in a consistent state at this point.
21285             mStackSupervisor.scheduleDestroyAllActivities(null, "always-finish");
21286         }
21287
21288         if (allChanged) {
21289             requestPssAllProcsLocked(now, false, mProcessStats.isMemFactorLowered());
21290         }
21291
21292         // Update from any uid changes.
21293         for (int i=mActiveUids.size()-1; i>=0; i--) {
21294             final UidRecord uidRec = mActiveUids.valueAt(i);
21295             int uidChange = UidRecord.CHANGE_PROCSTATE;
21296             if (uidRec.setProcState != uidRec.curProcState) {
21297                 if (DEBUG_UID_OBSERVERS) Slog.i(TAG_UID_OBSERVERS,
21298                         "Changes in " + uidRec + ": proc state from " + uidRec.setProcState
21299                         + " to " + uidRec.curProcState);
21300                 if (ActivityManager.isProcStateBackground(uidRec.curProcState)) {
21301                     if (!ActivityManager.isProcStateBackground(uidRec.setProcState)) {
21302                         uidRec.lastBackgroundTime = nowElapsed;
21303                         if (!mHandler.hasMessages(IDLE_UIDS_MSG)) {
21304                             // Note: the background settle time is in elapsed realtime, while
21305                             // the handler time base is uptime.  All this means is that we may
21306                             // stop background uids later than we had intended, but that only
21307                             // happens because the device was sleeping so we are okay anyway.
21308                             mHandler.sendEmptyMessageDelayed(IDLE_UIDS_MSG, BACKGROUND_SETTLE_TIME);
21309                         }
21310                     }
21311                 } else {
21312                     if (uidRec.idle) {
21313                         uidChange = UidRecord.CHANGE_ACTIVE;
21314                         uidRec.idle = false;
21315                     }
21316                     uidRec.lastBackgroundTime = 0;
21317                 }
21318                 uidRec.setProcState = uidRec.curProcState;
21319                 enqueueUidChangeLocked(uidRec, -1, uidChange);
21320                 noteUidProcessState(uidRec.uid, uidRec.curProcState);
21321             }
21322         }
21323
21324         if (mProcessStats.shouldWriteNowLocked(now)) {
21325             mHandler.post(new Runnable() {
21326                 @Override public void run() {
21327                     synchronized (ActivityManagerService.this) {
21328                         mProcessStats.writeStateAsyncLocked();
21329                     }
21330                 }
21331             });
21332         }
21333
21334         if (DEBUG_OOM_ADJ) {
21335             final long duration = SystemClock.uptimeMillis() - now;
21336             if (false) {
21337                 Slog.d(TAG_OOM_ADJ, "Did OOM ADJ in " + duration + "ms",
21338                         new RuntimeException("here").fillInStackTrace());
21339             } else {
21340                 Slog.d(TAG_OOM_ADJ, "Did OOM ADJ in " + duration + "ms");
21341             }
21342         }
21343     }
21344
21345     final void idleUids() {
21346         synchronized (this) {
21347             final long nowElapsed = SystemClock.elapsedRealtime();
21348             final long maxBgTime = nowElapsed - BACKGROUND_SETTLE_TIME;
21349             long nextTime = 0;
21350             for (int i=mActiveUids.size()-1; i>=0; i--) {
21351                 final UidRecord uidRec = mActiveUids.valueAt(i);
21352                 final long bgTime = uidRec.lastBackgroundTime;
21353                 if (bgTime > 0 && !uidRec.idle) {
21354                     if (bgTime <= maxBgTime) {
21355                         uidRec.idle = true;
21356                         doStopUidLocked(uidRec.uid, uidRec);
21357                     } else {
21358                         if (nextTime == 0 || nextTime > bgTime) {
21359                             nextTime = bgTime;
21360                         }
21361                     }
21362                 }
21363             }
21364             if (nextTime > 0) {
21365                 mHandler.removeMessages(IDLE_UIDS_MSG);
21366                 mHandler.sendEmptyMessageDelayed(IDLE_UIDS_MSG,
21367                         nextTime + BACKGROUND_SETTLE_TIME - nowElapsed);
21368             }
21369         }
21370     }
21371
21372     final void runInBackgroundDisabled(int uid) {
21373         synchronized (this) {
21374             UidRecord uidRec = mActiveUids.get(uid);
21375             if (uidRec != null) {
21376                 // This uid is actually running...  should it be considered background now?
21377                 if (uidRec.idle) {
21378                     doStopUidLocked(uidRec.uid, uidRec);
21379                 }
21380             } else {
21381                 // This uid isn't actually running...  still send a report about it being "stopped".
21382                 doStopUidLocked(uid, null);
21383             }
21384         }
21385     }
21386
21387     final void doStopUidLocked(int uid, final UidRecord uidRec) {
21388         mServices.stopInBackgroundLocked(uid);
21389         enqueueUidChangeLocked(uidRec, uid, UidRecord.CHANGE_IDLE);
21390     }
21391
21392     final void trimApplications() {
21393         synchronized (this) {
21394             int i;
21395
21396             // First remove any unused application processes whose package
21397             // has been removed.
21398             for (i=mRemovedProcesses.size()-1; i>=0; i--) {
21399                 final ProcessRecord app = mRemovedProcesses.get(i);
21400                 if (app.activities.size() == 0
21401                         && app.curReceiver == null && app.services.size() == 0) {
21402                     Slog.i(
21403                         TAG, "Exiting empty application process "
21404                         + app.toShortString() + " ("
21405                         + (app.thread != null ? app.thread.asBinder() : null)
21406                         + ")\n");
21407                     if (app.pid > 0 && app.pid != MY_PID) {
21408                         app.kill("empty", false);
21409                     } else {
21410                         try {
21411                             app.thread.scheduleExit();
21412                         } catch (Exception e) {
21413                             // Ignore exceptions.
21414                         }
21415                     }
21416                     cleanUpApplicationRecordLocked(app, false, true, -1, false /*replacingPid*/);
21417                     mRemovedProcesses.remove(i);
21418
21419                     if (app.persistent) {
21420                         addAppLocked(app.info, false, null /* ABI override */);
21421                     }
21422                 }
21423             }
21424
21425             // Now update the oom adj for all processes.
21426             updateOomAdjLocked();
21427         }
21428     }
21429
21430     /** This method sends the specified signal to each of the persistent apps */
21431     public void signalPersistentProcesses(int sig) throws RemoteException {
21432         if (sig != Process.SIGNAL_USR1) {
21433             throw new SecurityException("Only SIGNAL_USR1 is allowed");
21434         }
21435
21436         synchronized (this) {
21437             if (checkCallingPermission(android.Manifest.permission.SIGNAL_PERSISTENT_PROCESSES)
21438                     != PackageManager.PERMISSION_GRANTED) {
21439                 throw new SecurityException("Requires permission "
21440                         + android.Manifest.permission.SIGNAL_PERSISTENT_PROCESSES);
21441             }
21442
21443             for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) {
21444                 ProcessRecord r = mLruProcesses.get(i);
21445                 if (r.thread != null && r.persistent) {
21446                     Process.sendSignal(r.pid, sig);
21447                 }
21448             }
21449         }
21450     }
21451
21452     private void stopProfilerLocked(ProcessRecord proc, int profileType) {
21453         if (proc == null || proc == mProfileProc) {
21454             proc = mProfileProc;
21455             profileType = mProfileType;
21456             clearProfilerLocked();
21457         }
21458         if (proc == null) {
21459             return;
21460         }
21461         try {
21462             proc.thread.profilerControl(false, null, profileType);
21463         } catch (RemoteException e) {
21464             throw new IllegalStateException("Process disappeared");
21465         }
21466     }
21467
21468     private void clearProfilerLocked() {
21469         if (mProfileFd != null) {
21470             try {
21471                 mProfileFd.close();
21472             } catch (IOException e) {
21473             }
21474         }
21475         mProfileApp = null;
21476         mProfileProc = null;
21477         mProfileFile = null;
21478         mProfileType = 0;
21479         mAutoStopProfiler = false;
21480         mSamplingInterval = 0;
21481     }
21482
21483     public boolean profileControl(String process, int userId, boolean start,
21484             ProfilerInfo profilerInfo, int profileType) throws RemoteException {
21485
21486         try {
21487             synchronized (this) {
21488                 // note: hijacking SET_ACTIVITY_WATCHER, but should be changed to
21489                 // its own permission.
21490                 if (checkCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER)
21491                         != PackageManager.PERMISSION_GRANTED) {
21492                     throw new SecurityException("Requires permission "
21493                             + android.Manifest.permission.SET_ACTIVITY_WATCHER);
21494                 }
21495
21496                 if (start && (profilerInfo == null || profilerInfo.profileFd == null)) {
21497                     throw new IllegalArgumentException("null profile info or fd");
21498                 }
21499
21500                 ProcessRecord proc = null;
21501                 if (process != null) {
21502                     proc = findProcessLocked(process, userId, "profileControl");
21503                 }
21504
21505                 if (start && (proc == null || proc.thread == null)) {
21506                     throw new IllegalArgumentException("Unknown process: " + process);
21507                 }
21508
21509                 if (start) {
21510                     stopProfilerLocked(null, 0);
21511                     setProfileApp(proc.info, proc.processName, profilerInfo);
21512                     mProfileProc = proc;
21513                     mProfileType = profileType;
21514                     ParcelFileDescriptor fd = profilerInfo.profileFd;
21515                     try {
21516                         fd = fd.dup();
21517                     } catch (IOException e) {
21518                         fd = null;
21519                     }
21520                     profilerInfo.profileFd = fd;
21521                     proc.thread.profilerControl(start, profilerInfo, profileType);
21522                     fd = null;
21523                     mProfileFd = null;
21524                 } else {
21525                     stopProfilerLocked(proc, profileType);
21526                     if (profilerInfo != null && profilerInfo.profileFd != null) {
21527                         try {
21528                             profilerInfo.profileFd.close();
21529                         } catch (IOException e) {
21530                         }
21531                     }
21532                 }
21533
21534                 return true;
21535             }
21536         } catch (RemoteException e) {
21537             throw new IllegalStateException("Process disappeared");
21538         } finally {
21539             if (profilerInfo != null && profilerInfo.profileFd != null) {
21540                 try {
21541                     profilerInfo.profileFd.close();
21542                 } catch (IOException e) {
21543                 }
21544             }
21545         }
21546     }
21547
21548     private ProcessRecord findProcessLocked(String process, int userId, String callName) {
21549         userId = mUserController.handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(),
21550                 userId, true, ALLOW_FULL_ONLY, callName, null);
21551         ProcessRecord proc = null;
21552         try {
21553             int pid = Integer.parseInt(process);
21554             synchronized (mPidsSelfLocked) {
21555                 proc = mPidsSelfLocked.get(pid);
21556             }
21557         } catch (NumberFormatException e) {
21558         }
21559
21560         if (proc == null) {
21561             ArrayMap<String, SparseArray<ProcessRecord>> all
21562                     = mProcessNames.getMap();
21563             SparseArray<ProcessRecord> procs = all.get(process);
21564             if (procs != null && procs.size() > 0) {
21565                 proc = procs.valueAt(0);
21566                 if (userId != UserHandle.USER_ALL && proc.userId != userId) {
21567                     for (int i=1; i<procs.size(); i++) {
21568                         ProcessRecord thisProc = procs.valueAt(i);
21569                         if (thisProc.userId == userId) {
21570                             proc = thisProc;
21571                             break;
21572                         }
21573                     }
21574                 }
21575             }
21576         }
21577
21578         return proc;
21579     }
21580
21581     public boolean dumpHeap(String process, int userId, boolean managed,
21582             String path, ParcelFileDescriptor fd) throws RemoteException {
21583
21584         try {
21585             synchronized (this) {
21586                 // note: hijacking SET_ACTIVITY_WATCHER, but should be changed to
21587                 // its own permission (same as profileControl).
21588                 if (checkCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER)
21589                         != PackageManager.PERMISSION_GRANTED) {
21590                     throw new SecurityException("Requires permission "
21591                             + android.Manifest.permission.SET_ACTIVITY_WATCHER);
21592                 }
21593
21594                 if (fd == null) {
21595                     throw new IllegalArgumentException("null fd");
21596                 }
21597
21598                 ProcessRecord proc = findProcessLocked(process, userId, "dumpHeap");
21599                 if (proc == null || proc.thread == null) {
21600                     throw new IllegalArgumentException("Unknown process: " + process);
21601                 }
21602
21603                 boolean isDebuggable = "1".equals(SystemProperties.get(SYSTEM_DEBUGGABLE, "0"));
21604                 if (!isDebuggable) {
21605                     if ((proc.info.flags&ApplicationInfo.FLAG_DEBUGGABLE) == 0) {
21606                         throw new SecurityException("Process not debuggable: " + proc);
21607                     }
21608                 }
21609
21610                 proc.thread.dumpHeap(managed, path, fd);
21611                 fd = null;
21612                 return true;
21613             }
21614         } catch (RemoteException e) {
21615             throw new IllegalStateException("Process disappeared");
21616         } finally {
21617             if (fd != null) {
21618                 try {
21619                     fd.close();
21620                 } catch (IOException e) {
21621                 }
21622             }
21623         }
21624     }
21625
21626     @Override
21627     public void setDumpHeapDebugLimit(String processName, int uid, long maxMemSize,
21628             String reportPackage) {
21629         if (processName != null) {
21630             enforceCallingPermission(android.Manifest.permission.SET_DEBUG_APP,
21631                     "setDumpHeapDebugLimit()");
21632         } else {
21633             synchronized (mPidsSelfLocked) {
21634                 ProcessRecord proc = mPidsSelfLocked.get(Binder.getCallingPid());
21635                 if (proc == null) {
21636                     throw new SecurityException("No process found for calling pid "
21637                             + Binder.getCallingPid());
21638                 }
21639                 if (!Build.IS_DEBUGGABLE
21640                         && (proc.info.flags&ApplicationInfo.FLAG_DEBUGGABLE) == 0) {
21641                     throw new SecurityException("Not running a debuggable build");
21642                 }
21643                 processName = proc.processName;
21644                 uid = proc.uid;
21645                 if (reportPackage != null && !proc.pkgList.containsKey(reportPackage)) {
21646                     throw new SecurityException("Package " + reportPackage + " is not running in "
21647                             + proc);
21648                 }
21649             }
21650         }
21651         synchronized (this) {
21652             if (maxMemSize > 0) {
21653                 mMemWatchProcesses.put(processName, uid, new Pair(maxMemSize, reportPackage));
21654             } else {
21655                 if (uid != 0) {
21656                     mMemWatchProcesses.remove(processName, uid);
21657                 } else {
21658                     mMemWatchProcesses.getMap().remove(processName);
21659                 }
21660             }
21661         }
21662     }
21663
21664     @Override
21665     public void dumpHeapFinished(String path) {
21666         synchronized (this) {
21667             if (Binder.getCallingPid() != mMemWatchDumpPid) {
21668                 Slog.w(TAG, "dumpHeapFinished: Calling pid " + Binder.getCallingPid()
21669                         + " does not match last pid " + mMemWatchDumpPid);
21670                 return;
21671             }
21672             if (mMemWatchDumpFile == null || !mMemWatchDumpFile.equals(path)) {
21673                 Slog.w(TAG, "dumpHeapFinished: Calling path " + path
21674                         + " does not match last path " + mMemWatchDumpFile);
21675                 return;
21676             }
21677             if (DEBUG_PSS) Slog.d(TAG_PSS, "Dump heap finished for " + path);
21678             mHandler.sendEmptyMessage(POST_DUMP_HEAP_NOTIFICATION_MSG);
21679         }
21680     }
21681
21682     /** In this method we try to acquire our lock to make sure that we have not deadlocked */
21683     public void monitor() {
21684         synchronized (this) { }
21685     }
21686
21687     void onCoreSettingsChange(Bundle settings) {
21688         for (int i = mLruProcesses.size() - 1; i >= 0; i--) {
21689             ProcessRecord processRecord = mLruProcesses.get(i);
21690             try {
21691                 if (processRecord.thread != null) {
21692                     processRecord.thread.setCoreSettings(settings);
21693                 }
21694             } catch (RemoteException re) {
21695                 /* ignore */
21696             }
21697         }
21698     }
21699
21700     // Multi-user methods
21701
21702     /**
21703      * Start user, if its not already running, but don't bring it to foreground.
21704      */
21705     @Override
21706     public boolean startUserInBackground(final int userId) {
21707         return mUserController.startUser(userId, /* foreground */ false);
21708     }
21709
21710     @Override
21711     public boolean unlockUser(int userId, byte[] token, byte[] secret, IProgressListener listener) {
21712         return mUserController.unlockUser(userId, token, secret, listener);
21713     }
21714
21715     @Override
21716     public boolean switchUser(final int targetUserId) {
21717         enforceShellRestriction(UserManager.DISALLOW_DEBUGGING_FEATURES, targetUserId);
21718         UserInfo currentUserInfo;
21719         UserInfo targetUserInfo;
21720         synchronized (this) {
21721             int currentUserId = mUserController.getCurrentUserIdLocked();
21722             currentUserInfo = mUserController.getUserInfo(currentUserId);
21723             targetUserInfo = mUserController.getUserInfo(targetUserId);
21724             if (targetUserInfo == null) {
21725                 Slog.w(TAG, "No user info for user #" + targetUserId);
21726                 return false;
21727             }
21728             if (!targetUserInfo.isDemo() && UserManager.isDeviceInDemoMode(mContext)) {
21729                 Slog.w(TAG, "Cannot switch to non-demo user #" + targetUserId
21730                         + " when device is in demo mode");
21731                 return false;
21732             }
21733             if (!targetUserInfo.supportsSwitchTo()) {
21734                 Slog.w(TAG, "Cannot switch to User #" + targetUserId + ": not supported");
21735                 return false;
21736             }
21737             if (targetUserInfo.isManagedProfile()) {
21738                 Slog.w(TAG, "Cannot switch to User #" + targetUserId + ": not a full user");
21739                 return false;
21740             }
21741             mUserController.setTargetUserIdLocked(targetUserId);
21742         }
21743         Pair<UserInfo, UserInfo> userNames = new Pair<>(currentUserInfo, targetUserInfo);
21744         mUiHandler.removeMessages(START_USER_SWITCH_UI_MSG);
21745         mUiHandler.sendMessage(mUiHandler.obtainMessage(START_USER_SWITCH_UI_MSG, userNames));
21746         return true;
21747     }
21748
21749     void scheduleStartProfilesLocked() {
21750         if (!mHandler.hasMessages(START_PROFILES_MSG)) {
21751             mHandler.sendMessageDelayed(mHandler.obtainMessage(START_PROFILES_MSG),
21752                     DateUtils.SECOND_IN_MILLIS);
21753         }
21754     }
21755
21756     @Override
21757     public int stopUser(final int userId, boolean force, final IStopUserCallback callback) {
21758         return mUserController.stopUser(userId, force, callback);
21759     }
21760
21761     @Override
21762     public UserInfo getCurrentUser() {
21763         return mUserController.getCurrentUser();
21764     }
21765
21766     @Override
21767     public boolean isUserRunning(int userId, int flags) {
21768         if (!mUserController.isSameProfileGroup(userId, UserHandle.getCallingUserId())
21769                 && checkCallingPermission(INTERACT_ACROSS_USERS)
21770                     != PackageManager.PERMISSION_GRANTED) {
21771             String msg = "Permission Denial: isUserRunning() from pid="
21772                     + Binder.getCallingPid()
21773                     + ", uid=" + Binder.getCallingUid()
21774                     + " requires " + INTERACT_ACROSS_USERS;
21775             Slog.w(TAG, msg);
21776             throw new SecurityException(msg);
21777         }
21778         synchronized (this) {
21779             return mUserController.isUserRunningLocked(userId, flags);
21780         }
21781     }
21782
21783     @Override
21784     public int[] getRunningUserIds() {
21785         if (checkCallingPermission(INTERACT_ACROSS_USERS)
21786                 != PackageManager.PERMISSION_GRANTED) {
21787             String msg = "Permission Denial: isUserRunning() from pid="
21788                     + Binder.getCallingPid()
21789                     + ", uid=" + Binder.getCallingUid()
21790                     + " requires " + INTERACT_ACROSS_USERS;
21791             Slog.w(TAG, msg);
21792             throw new SecurityException(msg);
21793         }
21794         synchronized (this) {
21795             return mUserController.getStartedUserArrayLocked();
21796         }
21797     }
21798
21799     @Override
21800     public void registerUserSwitchObserver(IUserSwitchObserver observer, String name) {
21801         mUserController.registerUserSwitchObserver(observer, name);
21802     }
21803
21804     @Override
21805     public void unregisterUserSwitchObserver(IUserSwitchObserver observer) {
21806         mUserController.unregisterUserSwitchObserver(observer);
21807     }
21808
21809     ApplicationInfo getAppInfoForUser(ApplicationInfo info, int userId) {
21810         if (info == null) return null;
21811         ApplicationInfo newInfo = new ApplicationInfo(info);
21812         newInfo.initForUser(userId);
21813         return newInfo;
21814     }
21815
21816     public boolean isUserStopped(int userId) {
21817         synchronized (this) {
21818             return mUserController.getStartedUserStateLocked(userId) == null;
21819         }
21820     }
21821
21822     ActivityInfo getActivityInfoForUser(ActivityInfo aInfo, int userId) {
21823         if (aInfo == null
21824                 || (userId < 1 && aInfo.applicationInfo.uid < UserHandle.PER_USER_RANGE)) {
21825             return aInfo;
21826         }
21827
21828         ActivityInfo info = new ActivityInfo(aInfo);
21829         info.applicationInfo = getAppInfoForUser(info.applicationInfo, userId);
21830         return info;
21831     }
21832
21833     private boolean processSanityChecksLocked(ProcessRecord process) {
21834         if (process == null || process.thread == null) {
21835             return false;
21836         }
21837
21838         boolean isDebuggable = "1".equals(SystemProperties.get(SYSTEM_DEBUGGABLE, "0"));
21839         if (!isDebuggable) {
21840             if ((process.info.flags&ApplicationInfo.FLAG_DEBUGGABLE) == 0) {
21841                 return false;
21842             }
21843         }
21844
21845         return true;
21846     }
21847
21848     public boolean startBinderTracking() throws RemoteException {
21849         synchronized (this) {
21850             mBinderTransactionTrackingEnabled = true;
21851             // TODO: hijacking SET_ACTIVITY_WATCHER, but should be changed to its own
21852             // permission (same as profileControl).
21853             if (checkCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER)
21854                     != PackageManager.PERMISSION_GRANTED) {
21855                 throw new SecurityException("Requires permission "
21856                         + android.Manifest.permission.SET_ACTIVITY_WATCHER);
21857             }
21858
21859             for (int i = 0; i < mLruProcesses.size(); i++) {
21860                 ProcessRecord process = mLruProcesses.get(i);
21861                 if (!processSanityChecksLocked(process)) {
21862                     continue;
21863                 }
21864                 try {
21865                     process.thread.startBinderTracking();
21866                 } catch (RemoteException e) {
21867                     Log.v(TAG, "Process disappared");
21868                 }
21869             }
21870             return true;
21871         }
21872     }
21873
21874     public boolean stopBinderTrackingAndDump(ParcelFileDescriptor fd) throws RemoteException {
21875         try {
21876             synchronized (this) {
21877                 mBinderTransactionTrackingEnabled = false;
21878                 // TODO: hijacking SET_ACTIVITY_WATCHER, but should be changed to its own
21879                 // permission (same as profileControl).
21880                 if (checkCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER)
21881                         != PackageManager.PERMISSION_GRANTED) {
21882                     throw new SecurityException("Requires permission "
21883                             + android.Manifest.permission.SET_ACTIVITY_WATCHER);
21884                 }
21885
21886                 if (fd == null) {
21887                     throw new IllegalArgumentException("null fd");
21888                 }
21889
21890                 PrintWriter pw = new FastPrintWriter(new FileOutputStream(fd.getFileDescriptor()));
21891                 pw.println("Binder transaction traces for all processes.\n");
21892                 for (ProcessRecord process : mLruProcesses) {
21893                     if (!processSanityChecksLocked(process)) {
21894                         continue;
21895                     }
21896
21897                     pw.println("Traces for process: " + process.processName);
21898                     pw.flush();
21899                     try {
21900                         TransferPipe tp = new TransferPipe();
21901                         try {
21902                             process.thread.stopBinderTrackingAndDump(
21903                                     tp.getWriteFd().getFileDescriptor());
21904                             tp.go(fd.getFileDescriptor());
21905                         } finally {
21906                             tp.kill();
21907                         }
21908                     } catch (IOException e) {
21909                         pw.println("Failure while dumping IPC traces from " + process +
21910                                 ".  Exception: " + e);
21911                         pw.flush();
21912                     } catch (RemoteException e) {
21913                         pw.println("Got a RemoteException while dumping IPC traces from " +
21914                                 process + ".  Exception: " + e);
21915                         pw.flush();
21916                     }
21917                 }
21918                 fd = null;
21919                 return true;
21920             }
21921         } finally {
21922             if (fd != null) {
21923                 try {
21924                     fd.close();
21925                 } catch (IOException e) {
21926                 }
21927             }
21928         }
21929     }
21930
21931     private final class LocalService extends ActivityManagerInternal {
21932         @Override
21933         public String checkContentProviderAccess(String authority, int userId) {
21934             return ActivityManagerService.this.checkContentProviderAccess(authority, userId);
21935         }
21936
21937         @Override
21938         public void onWakefulnessChanged(int wakefulness) {
21939             ActivityManagerService.this.onWakefulnessChanged(wakefulness);
21940         }
21941
21942         @Override
21943         public int startIsolatedProcess(String entryPoint, String[] entryPointArgs,
21944                 String processName, String abiOverride, int uid, Runnable crashHandler) {
21945             return ActivityManagerService.this.startIsolatedProcess(entryPoint, entryPointArgs,
21946                     processName, abiOverride, uid, crashHandler);
21947         }
21948
21949         @Override
21950         public SleepToken acquireSleepToken(String tag) {
21951             Preconditions.checkNotNull(tag);
21952
21953             synchronized (ActivityManagerService.this) {
21954                 SleepTokenImpl token = new SleepTokenImpl(tag);
21955                 mSleepTokens.add(token);
21956                 updateSleepIfNeededLocked();
21957                 return token;
21958             }
21959         }
21960
21961         @Override
21962         public ComponentName getHomeActivityForUser(int userId) {
21963             synchronized (ActivityManagerService.this) {
21964                 ActivityRecord homeActivity = mStackSupervisor.getHomeActivityForUser(userId);
21965                 return homeActivity == null ? null : homeActivity.realActivity;
21966             }
21967         }
21968
21969         @Override
21970         public void onUserRemoved(int userId) {
21971             synchronized (ActivityManagerService.this) {
21972                 ActivityManagerService.this.onUserStoppedLocked(userId);
21973             }
21974         }
21975
21976         @Override
21977         public void onLocalVoiceInteractionStarted(IBinder activity,
21978                 IVoiceInteractionSession voiceSession, IVoiceInteractor voiceInteractor) {
21979             synchronized (ActivityManagerService.this) {
21980                 ActivityManagerService.this.onLocalVoiceInteractionStartedLocked(activity,
21981                         voiceSession, voiceInteractor);
21982             }
21983         }
21984
21985         @Override
21986         public void notifyStartingWindowDrawn() {
21987             synchronized (ActivityManagerService.this) {
21988                 mStackSupervisor.mActivityMetricsLogger.notifyStartingWindowDrawn();
21989             }
21990         }
21991
21992         @Override
21993         public void notifyAppTransitionStarting(int reason) {
21994             synchronized (ActivityManagerService.this) {
21995                 mStackSupervisor.mActivityMetricsLogger.notifyTransitionStarting(reason);
21996             }
21997         }
21998
21999         @Override
22000         public void notifyAppTransitionFinished() {
22001             synchronized (ActivityManagerService.this) {
22002                 mStackSupervisor.notifyAppTransitionDone();
22003             }
22004         }
22005
22006         @Override
22007         public void notifyAppTransitionCancelled() {
22008             synchronized (ActivityManagerService.this) {
22009                 mStackSupervisor.notifyAppTransitionDone();
22010             }
22011         }
22012
22013         @Override
22014         public List<IBinder> getTopVisibleActivities() {
22015             synchronized (ActivityManagerService.this) {
22016                 return mStackSupervisor.getTopVisibleActivities();
22017             }
22018         }
22019
22020         @Override
22021         public void notifyDockedStackMinimizedChanged(boolean minimized) {
22022             synchronized (ActivityManagerService.this) {
22023                 mStackSupervisor.setDockedStackMinimized(minimized);
22024             }
22025         }
22026
22027         @Override
22028         public void killForegroundAppsForUser(int userHandle) {
22029             synchronized (ActivityManagerService.this) {
22030                 final ArrayList<ProcessRecord> procs = new ArrayList<>();
22031                 final int NP = mProcessNames.getMap().size();
22032                 for (int ip = 0; ip < NP; ip++) {
22033                     final SparseArray<ProcessRecord> apps = mProcessNames.getMap().valueAt(ip);
22034                     final int NA = apps.size();
22035                     for (int ia = 0; ia < NA; ia++) {
22036                         final ProcessRecord app = apps.valueAt(ia);
22037                         if (app.persistent) {
22038                             // We don't kill persistent processes.
22039                             continue;
22040                         }
22041                         if (app.removed) {
22042                             procs.add(app);
22043                         } else if (app.userId == userHandle && app.foregroundActivities) {
22044                             app.removed = true;
22045                             procs.add(app);
22046                         }
22047                     }
22048                 }
22049
22050                 final int N = procs.size();
22051                 for (int i = 0; i < N; i++) {
22052                     removeProcessLocked(procs.get(i), false, true, "kill all fg");
22053                 }
22054             }
22055         }
22056
22057         @Override
22058         public void setPendingIntentWhitelistDuration(IIntentSender target, long duration) {
22059             if (!(target instanceof PendingIntentRecord)) {
22060                 Slog.w(TAG, "markAsSentFromNotification(): not a PendingIntentRecord: " + target);
22061                 return;
22062             }
22063             ((PendingIntentRecord) target).setWhitelistDuration(duration);
22064         }
22065
22066         @Override
22067         public void updatePersistentConfigurationForUser(@NonNull Configuration values,
22068                 int userId) {
22069             Preconditions.checkNotNull(values, "Configuration must not be null");
22070             Preconditions.checkArgumentNonnegative(userId, "userId " + userId + " not supported");
22071             synchronized (ActivityManagerService.this) {
22072                 updateConfigurationLocked(values, null, false, true, userId,
22073                         false /* deferResume */);
22074             }
22075         }
22076
22077         @Override
22078         public int startActivitiesAsPackage(String packageName, int userId, Intent[] intents,
22079                 Bundle bOptions) {
22080             Preconditions.checkNotNull(intents, "intents");
22081             final String[] resolvedTypes = new String[intents.length];
22082             for (int i = 0; i < intents.length; i++) {
22083                 resolvedTypes[i] = intents[i].resolveTypeIfNeeded(mContext.getContentResolver());
22084             }
22085
22086             // UID of the package on user userId.
22087             // "= 0" is needed because otherwise catch(RemoteException) would make it look like
22088             // packageUid may not be initialized.
22089             int packageUid = 0;
22090             try {
22091                 packageUid = AppGlobals.getPackageManager().getPackageUid(
22092                         packageName, PackageManager.MATCH_DEBUG_TRIAGED_MISSING, userId);
22093             } catch (RemoteException e) {
22094                 // Shouldn't happen.
22095             }
22096
22097             synchronized (ActivityManagerService.this) {
22098                 return startActivitiesInPackage(packageUid, packageName, intents, resolvedTypes,
22099                         /*resultTo*/ null, bOptions, userId);
22100             }
22101         }
22102
22103         @Override
22104         public int getUidProcessState(int uid) {
22105             return getUidState(uid);
22106         }
22107     }
22108
22109     private final class SleepTokenImpl extends SleepToken {
22110         private final String mTag;
22111         private final long mAcquireTime;
22112
22113         public SleepTokenImpl(String tag) {
22114             mTag = tag;
22115             mAcquireTime = SystemClock.uptimeMillis();
22116         }
22117
22118         @Override
22119         public void release() {
22120             synchronized (ActivityManagerService.this) {
22121                 if (mSleepTokens.remove(this)) {
22122                     updateSleepIfNeededLocked();
22123                 }
22124             }
22125         }
22126
22127         @Override
22128         public String toString() {
22129             return "{\"" + mTag + "\", acquire at " + TimeUtils.formatUptime(mAcquireTime) + "}";
22130         }
22131     }
22132
22133     /**
22134      * An implementation of IAppTask, that allows an app to manage its own tasks via
22135      * {@link android.app.ActivityManager.AppTask}.  We keep track of the callingUid to ensure that
22136      * only the process that calls getAppTasks() can call the AppTask methods.
22137      */
22138     class AppTaskImpl extends IAppTask.Stub {
22139         private int mTaskId;
22140         private int mCallingUid;
22141
22142         public AppTaskImpl(int taskId, int callingUid) {
22143             mTaskId = taskId;
22144             mCallingUid = callingUid;
22145         }
22146
22147         private void checkCaller() {
22148             if (mCallingUid != Binder.getCallingUid()) {
22149                 throw new SecurityException("Caller " + mCallingUid
22150                         + " does not match caller of getAppTasks(): " + Binder.getCallingUid());
22151             }
22152         }
22153
22154         @Override
22155         public void finishAndRemoveTask() {
22156             checkCaller();
22157
22158             synchronized (ActivityManagerService.this) {
22159                 long origId = Binder.clearCallingIdentity();
22160                 try {
22161                     // We remove the task from recents to preserve backwards
22162                     if (!removeTaskByIdLocked(mTaskId, false, REMOVE_FROM_RECENTS)) {
22163                         throw new IllegalArgumentException("Unable to find task ID " + mTaskId);
22164                     }
22165                 } finally {
22166                     Binder.restoreCallingIdentity(origId);
22167                 }
22168             }
22169         }
22170
22171         @Override
22172         public ActivityManager.RecentTaskInfo getTaskInfo() {
22173             checkCaller();
22174
22175             synchronized (ActivityManagerService.this) {
22176                 long origId = Binder.clearCallingIdentity();
22177                 try {
22178                     TaskRecord tr = mStackSupervisor.anyTaskForIdLocked(mTaskId);
22179                     if (tr == null) {
22180                         throw new IllegalArgumentException("Unable to find task ID " + mTaskId);
22181                     }
22182                     return createRecentTaskInfoFromTaskRecord(tr);
22183                 } finally {
22184                     Binder.restoreCallingIdentity(origId);
22185                 }
22186             }
22187         }
22188
22189         @Override
22190         public void moveToFront() {
22191             checkCaller();
22192             // Will bring task to front if it already has a root activity.
22193             final long origId = Binder.clearCallingIdentity();
22194             try {
22195                 synchronized (this) {
22196                     mStackSupervisor.startActivityFromRecentsInner(mTaskId, null);
22197                 }
22198             } finally {
22199                 Binder.restoreCallingIdentity(origId);
22200             }
22201         }
22202
22203         @Override
22204         public int startActivity(IBinder whoThread, String callingPackage,
22205                 Intent intent, String resolvedType, Bundle bOptions) {
22206             checkCaller();
22207
22208             int callingUser = UserHandle.getCallingUserId();
22209             TaskRecord tr;
22210             IApplicationThread appThread;
22211             synchronized (ActivityManagerService.this) {
22212                 tr = mStackSupervisor.anyTaskForIdLocked(mTaskId);
22213                 if (tr == null) {
22214                     throw new IllegalArgumentException("Unable to find task ID " + mTaskId);
22215                 }
22216                 appThread = ApplicationThreadNative.asInterface(whoThread);
22217                 if (appThread == null) {
22218                     throw new IllegalArgumentException("Bad app thread " + appThread);
22219                 }
22220             }
22221             return mActivityStarter.startActivityMayWait(appThread, -1, callingPackage, intent,
22222                     resolvedType, null, null, null, null, 0, 0, null, null,
22223                     null, bOptions, false, callingUser, null, tr);
22224         }
22225
22226         @Override
22227         public void setExcludeFromRecents(boolean exclude) {
22228             checkCaller();
22229
22230             synchronized (ActivityManagerService.this) {
22231                 long origId = Binder.clearCallingIdentity();
22232                 try {
22233                     TaskRecord tr = mStackSupervisor.anyTaskForIdLocked(mTaskId);
22234                     if (tr == null) {
22235                         throw new IllegalArgumentException("Unable to find task ID " + mTaskId);
22236                     }
22237                     Intent intent = tr.getBaseIntent();
22238                     if (exclude) {
22239                         intent.addFlags(Intent.FLAG_ACTIVITY_EXCLUDE_FROM_RECENTS);
22240                     } else {
22241                         intent.setFlags(intent.getFlags()
22242                                 & ~Intent.FLAG_ACTIVITY_EXCLUDE_FROM_RECENTS);
22243                     }
22244                 } finally {
22245                     Binder.restoreCallingIdentity(origId);
22246                 }
22247             }
22248         }
22249     }
22250
22251     /**
22252      * Kill processes for the user with id userId and that depend on the package named packageName
22253      */
22254     @Override
22255     public void killPackageDependents(String packageName, int userId) {
22256         enforceCallingPermission(android.Manifest.permission.KILL_UID, "killPackageDependents()");
22257         if (packageName == null) {
22258             throw new NullPointerException(
22259                     "Cannot kill the dependents of a package without its name.");
22260         }
22261
22262         long callingId = Binder.clearCallingIdentity();
22263         IPackageManager pm = AppGlobals.getPackageManager();
22264         int pkgUid = -1;
22265         try {
22266             pkgUid = pm.getPackageUid(packageName, MATCH_DEBUG_TRIAGED_MISSING, userId);
22267         } catch (RemoteException e) {
22268         }
22269         if (userId != UserHandle.USER_ALL && pkgUid == -1) {
22270             throw new IllegalArgumentException(
22271                     "Cannot kill dependents of non-existing package " + packageName);
22272         }
22273         try {
22274             synchronized(this) {
22275                 killPackageProcessesLocked(packageName, UserHandle.getAppId(pkgUid), userId,
22276                         ProcessList.FOREGROUND_APP_ADJ, false, true, true, false,
22277                         "dep: " + packageName);
22278             }
22279         } finally {
22280             Binder.restoreCallingIdentity(callingId);
22281         }
22282     }
22283
22284     @Override
22285     public boolean canBypassWorkChallenge(PendingIntent intent) throws RemoteException {
22286         final int userId = intent.getCreatorUserHandle().getIdentifier();
22287         if (!mUserController.isUserRunningLocked(userId, ActivityManager.FLAG_AND_LOCKED)) {
22288             return false;
22289         }
22290         IIntentSender target = intent.getTarget();
22291         if (!(target instanceof PendingIntentRecord)) {
22292             return false;
22293         }
22294         final PendingIntentRecord record = (PendingIntentRecord) target;
22295         final ResolveInfo rInfo = mStackSupervisor.resolveIntent(record.key.requestIntent,
22296                 record.key.requestResolvedType, userId, PackageManager.MATCH_DIRECT_BOOT_AWARE);
22297         // For direct boot aware activities, they can be shown without triggering a work challenge
22298         // before the profile user is unlocked.
22299         return rInfo != null && rInfo.activityInfo != null;
22300     }
22301 }