OSDN Git Service

Merge "Fix uri permission grant on remote bug report uri" into nyc-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.annotation.UserIdInt;
67 import android.app.Activity;
68 import android.app.ActivityManager;
69 import android.app.ActivityManager.RunningTaskInfo;
70 import android.app.ActivityManager.StackId;
71 import android.app.ActivityManager.StackInfo;
72 import android.app.ActivityManager.TaskThumbnailInfo;
73 import android.app.ActivityManagerInternal;
74 import android.app.ActivityManagerInternal.SleepToken;
75 import android.app.ActivityManagerNative;
76 import android.app.ActivityOptions;
77 import android.app.ActivityThread;
78 import android.app.AlertDialog;
79 import android.app.AppGlobals;
80 import android.app.AppOpsManager;
81 import android.app.ApplicationErrorReport;
82 import android.app.ApplicationThreadNative;
83 import android.app.BroadcastOptions;
84 import android.app.Dialog;
85 import android.app.IActivityContainer;
86 import android.app.IActivityContainerCallback;
87 import android.app.IActivityController;
88 import android.app.IAppTask;
89 import android.app.IApplicationThread;
90 import android.app.IInstrumentationWatcher;
91 import android.app.INotificationManager;
92 import android.app.IProcessObserver;
93 import android.app.IServiceConnection;
94 import android.app.IStopUserCallback;
95 import android.app.ITaskStackListener;
96 import android.app.IUiAutomationConnection;
97 import android.app.IUidObserver;
98 import android.app.IUserSwitchObserver;
99 import android.app.Instrumentation;
100 import android.app.Notification;
101 import android.app.NotificationManager;
102 import android.app.PendingIntent;
103 import android.app.ProfilerInfo;
104 import android.app.admin.DevicePolicyManager;
105 import android.app.assist.AssistContent;
106 import android.app.assist.AssistStructure;
107 import android.app.backup.IBackupManager;
108 import android.app.usage.UsageEvents;
109 import android.app.usage.UsageStatsManagerInternal;
110 import android.appwidget.AppWidgetManager;
111 import android.content.ActivityNotFoundException;
112 import android.content.BroadcastReceiver;
113 import android.content.ClipData;
114 import android.content.ComponentCallbacks2;
115 import android.content.ComponentName;
116 import android.content.ContentProvider;
117 import android.content.ContentResolver;
118 import android.content.Context;
119 import android.content.DialogInterface;
120 import android.content.IContentProvider;
121 import android.content.IIntentReceiver;
122 import android.content.IIntentSender;
123 import android.content.Intent;
124 import android.content.IntentFilter;
125 import android.content.IntentSender;
126 import android.content.pm.ActivityInfo;
127 import android.content.pm.ApplicationInfo;
128 import android.content.pm.ConfigurationInfo;
129 import android.content.pm.IPackageDataObserver;
130 import android.content.pm.IPackageManager;
131 import android.content.pm.InstrumentationInfo;
132 import android.content.pm.PackageInfo;
133 import android.content.pm.PackageManager;
134 import android.content.pm.PackageManager.NameNotFoundException;
135 import android.content.pm.PackageManagerInternal;
136 import android.content.pm.ParceledListSlice;
137 import android.content.pm.PathPermission;
138 import android.content.pm.PermissionInfo;
139 import android.content.pm.ProviderInfo;
140 import android.content.pm.ResolveInfo;
141 import android.content.pm.ServiceInfo;
142 import android.content.pm.ShortcutServiceInternal;
143 import android.content.pm.UserInfo;
144 import android.content.res.CompatibilityInfo;
145 import android.content.res.Configuration;
146 import android.content.res.Resources;
147 import android.database.ContentObserver;
148 import android.graphics.Bitmap;
149 import android.graphics.Point;
150 import android.graphics.Rect;
151 import android.location.LocationManager;
152 import android.net.Proxy;
153 import android.net.ProxyInfo;
154 import android.net.Uri;
155 import android.os.BatteryStats;
156 import android.os.Binder;
157 import android.os.Build;
158 import android.os.Bundle;
159 import android.os.Debug;
160 import android.os.DropBoxManager;
161 import android.os.Environment;
162 import android.os.FactoryTest;
163 import android.os.FileObserver;
164 import android.os.FileUtils;
165 import android.os.Handler;
166 import android.os.IBinder;
167 import android.os.IPermissionController;
168 import android.os.IProcessInfoService;
169 import android.os.IProgressListener;
170 import android.os.LocaleList;
171 import android.os.Looper;
172 import android.os.Message;
173 import android.os.Parcel;
174 import android.os.ParcelFileDescriptor;
175 import android.os.PersistableBundle;
176 import android.os.PowerManager;
177 import android.os.PowerManagerInternal;
178 import android.os.Process;
179 import android.os.RemoteCallbackList;
180 import android.os.RemoteException;
181 import android.os.ResultReceiver;
182 import android.os.ServiceManager;
183 import android.os.StrictMode;
184 import android.os.SystemClock;
185 import android.os.SystemProperties;
186 import android.os.Trace;
187 import android.os.TransactionTooLargeException;
188 import android.os.UpdateLock;
189 import android.os.UserHandle;
190 import android.os.UserManager;
191 import android.os.WorkSource;
192 import android.provider.Downloads;
193 import android.os.storage.IMountService;
194 import android.os.storage.MountServiceInternal;
195 import android.os.storage.StorageManager;
196 import android.provider.Settings;
197 import android.service.voice.IVoiceInteractionSession;
198 import android.service.voice.VoiceInteractionManagerInternal;
199 import android.service.voice.VoiceInteractionSession;
200 import android.telecom.TelecomManager;
201 import android.text.format.DateUtils;
202 import android.text.format.Time;
203 import android.text.style.SuggestionSpan;
204 import android.util.ArrayMap;
205 import android.util.ArraySet;
206 import android.util.AtomicFile;
207 import android.util.DebugUtils;
208 import android.util.DisplayMetrics;
209 import android.util.EventLog;
210 import android.util.Log;
211 import android.util.Pair;
212 import android.util.PrintWriterPrinter;
213 import android.util.Slog;
214 import android.util.SparseArray;
215 import android.util.TimeUtils;
216 import android.util.Xml;
217 import android.view.Display;
218 import android.view.Gravity;
219 import android.view.LayoutInflater;
220 import android.view.View;
221 import android.view.WindowManager;
222
223 import java.io.File;
224 import java.io.FileDescriptor;
225 import java.io.FileInputStream;
226 import java.io.FileNotFoundException;
227 import java.io.FileOutputStream;
228 import java.io.IOException;
229 import java.io.InputStreamReader;
230 import java.io.PrintWriter;
231 import java.io.StringWriter;
232 import java.lang.ref.WeakReference;
233 import java.nio.charset.StandardCharsets;
234 import java.util.ArrayList;
235 import java.util.Arrays;
236 import java.util.Collections;
237 import java.util.Comparator;
238 import java.util.HashMap;
239 import java.util.HashSet;
240 import java.util.Iterator;
241 import java.util.List;
242 import java.util.Locale;
243 import java.util.Map;
244 import java.util.Objects;
245 import java.util.Set;
246 import java.util.concurrent.atomic.AtomicBoolean;
247 import java.util.concurrent.atomic.AtomicLong;
248
249 import dalvik.system.VMRuntime;
250
251 import libcore.io.IoUtils;
252 import libcore.util.EmptyArray;
253
254 import static android.Manifest.permission.INTERACT_ACROSS_USERS;
255 import static android.Manifest.permission.INTERACT_ACROSS_USERS_FULL;
256 import static android.Manifest.permission.MANAGE_ACTIVITY_STACKS;
257 import static android.Manifest.permission.START_TASKS_FROM_RECENTS;
258 import static android.app.ActivityManager.DOCKED_STACK_CREATE_MODE_TOP_OR_LEFT;
259 import static android.app.ActivityManager.RESIZE_MODE_PRESERVE_WINDOW;
260 import static android.app.ActivityManager.StackId.DOCKED_STACK_ID;
261 import static android.app.ActivityManager.StackId.FREEFORM_WORKSPACE_STACK_ID;
262 import static android.app.ActivityManager.StackId.FULLSCREEN_WORKSPACE_STACK_ID;
263 import static android.app.ActivityManager.StackId.HOME_STACK_ID;
264 import static android.app.ActivityManager.StackId.INVALID_STACK_ID;
265 import static android.app.ActivityManager.StackId.PINNED_STACK_ID;
266 import static android.content.pm.PackageManager.FEATURE_FREEFORM_WINDOW_MANAGEMENT;
267 import static android.content.pm.PackageManager.FEATURE_LEANBACK_ONLY;
268 import static android.content.pm.PackageManager.FEATURE_PICTURE_IN_PICTURE;
269 import static android.content.pm.PackageManager.GET_PROVIDERS;
270 import static android.content.pm.PackageManager.MATCH_DEBUG_TRIAGED_MISSING;
271 import static android.content.pm.PackageManager.MATCH_DIRECT_BOOT_AWARE;
272 import static android.content.pm.PackageManager.MATCH_DIRECT_BOOT_UNAWARE;
273 import static android.content.pm.PackageManager.MATCH_SYSTEM_ONLY;
274 import static android.content.pm.PackageManager.MATCH_UNINSTALLED_PACKAGES;
275 import static android.content.pm.PackageManager.PERMISSION_GRANTED;
276 import static android.content.res.Configuration.UI_MODE_TYPE_TELEVISION;
277 import static android.os.Process.PROC_CHAR;
278 import static android.os.Process.PROC_OUT_LONG;
279 import static android.os.Process.PROC_PARENS;
280 import static android.os.Process.PROC_SPACE_TERM;
281 import static android.provider.Settings.Global.ALWAYS_FINISH_ACTIVITIES;
282 import static android.provider.Settings.Global.DEBUG_APP;
283 import static android.provider.Settings.Global.DEVELOPMENT_ENABLE_FREEFORM_WINDOWS_SUPPORT;
284 import static android.provider.Settings.Global.DEVELOPMENT_FORCE_RESIZABLE_ACTIVITIES;
285 import static android.provider.Settings.Global.DEVELOPMENT_FORCE_RTL;
286 import static android.provider.Settings.Global.LENIENT_BACKGROUND_CHECK;
287 import static android.provider.Settings.Global.WAIT_FOR_DEBUGGER;
288 import static android.provider.Settings.System.FONT_SCALE;
289 import static com.android.internal.util.XmlUtils.readBooleanAttribute;
290 import static com.android.internal.util.XmlUtils.readIntAttribute;
291 import static com.android.internal.util.XmlUtils.readLongAttribute;
292 import static com.android.internal.util.XmlUtils.writeBooleanAttribute;
293 import static com.android.internal.util.XmlUtils.writeIntAttribute;
294 import static com.android.internal.util.XmlUtils.writeLongAttribute;
295 import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_ALL;
296 import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_ANR;
297 import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_BACKUP;
298 import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_BROADCAST;
299 import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_BROADCAST_BACKGROUND;
300 import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_BROADCAST_LIGHT;
301 import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_CLEANUP;
302 import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_CONFIGURATION;
303 import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_FOCUS;
304 import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_IMMERSIVE;
305 import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_LOCKSCREEN;
306 import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_LOCKTASK;
307 import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_LRU;
308 import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_MU;
309 import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_OOM_ADJ;
310 import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_PERMISSIONS_REVIEW;
311 import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_POWER;
312 import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_POWER_QUICK;
313 import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_PROCESSES;
314 import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_PROCESS_OBSERVERS;
315 import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_PROVIDER;
316 import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_PSS;
317 import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_RECENTS;
318 import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_SERVICE;
319 import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_STACK;
320 import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_SWITCH;
321 import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_TASKS;
322 import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_UID_OBSERVERS;
323 import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_URI_PERMISSION;
324 import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_USAGE_STATS;
325 import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_VISIBILITY;
326 import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_VISIBLE_BEHIND;
327 import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_WHITELISTS;
328 import static com.android.server.am.ActivityManagerDebugConfig.POSTFIX_BACKUP;
329 import static com.android.server.am.ActivityManagerDebugConfig.POSTFIX_BROADCAST;
330 import static com.android.server.am.ActivityManagerDebugConfig.POSTFIX_CLEANUP;
331 import static com.android.server.am.ActivityManagerDebugConfig.POSTFIX_CONFIGURATION;
332 import static com.android.server.am.ActivityManagerDebugConfig.POSTFIX_FOCUS;
333 import static com.android.server.am.ActivityManagerDebugConfig.POSTFIX_IMMERSIVE;
334 import static com.android.server.am.ActivityManagerDebugConfig.POSTFIX_LOCKSCREEN;
335 import static com.android.server.am.ActivityManagerDebugConfig.POSTFIX_LOCKTASK;
336 import static com.android.server.am.ActivityManagerDebugConfig.POSTFIX_LRU;
337 import static com.android.server.am.ActivityManagerDebugConfig.POSTFIX_MU;
338 import static com.android.server.am.ActivityManagerDebugConfig.POSTFIX_OOM_ADJ;
339 import static com.android.server.am.ActivityManagerDebugConfig.POSTFIX_POWER;
340 import static com.android.server.am.ActivityManagerDebugConfig.POSTFIX_PROCESSES;
341 import static com.android.server.am.ActivityManagerDebugConfig.POSTFIX_PROCESS_OBSERVERS;
342 import static com.android.server.am.ActivityManagerDebugConfig.POSTFIX_PROVIDER;
343 import static com.android.server.am.ActivityManagerDebugConfig.POSTFIX_PSS;
344 import static com.android.server.am.ActivityManagerDebugConfig.POSTFIX_RECENTS;
345 import static com.android.server.am.ActivityManagerDebugConfig.POSTFIX_SERVICE;
346 import static com.android.server.am.ActivityManagerDebugConfig.POSTFIX_STACK;
347 import static com.android.server.am.ActivityManagerDebugConfig.POSTFIX_SWITCH;
348 import static com.android.server.am.ActivityManagerDebugConfig.POSTFIX_UID_OBSERVERS;
349 import static com.android.server.am.ActivityManagerDebugConfig.POSTFIX_URI_PERMISSION;
350 import static com.android.server.am.ActivityManagerDebugConfig.POSTFIX_VISIBILITY;
351 import static com.android.server.am.ActivityManagerDebugConfig.POSTFIX_VISIBLE_BEHIND;
352 import static com.android.server.am.ActivityManagerDebugConfig.TAG_AM;
353 import static com.android.server.am.ActivityManagerDebugConfig.TAG_WITH_CLASS_NAME;
354 import static com.android.server.am.ActivityRecord.RECENTS_ACTIVITY_TYPE;
355 import static com.android.server.am.ActivityStackSupervisor.ActivityContainer.FORCE_NEW_TASK_FLAGS;
356 import static com.android.server.am.ActivityStackSupervisor.DEFER_RESUME;
357 import static com.android.server.am.ActivityStackSupervisor.FORCE_FOCUS;
358 import static com.android.server.am.ActivityStackSupervisor.ON_TOP;
359 import static com.android.server.am.ActivityStackSupervisor.PRESERVE_WINDOWS;
360 import static com.android.server.am.ActivityStackSupervisor.RESTORE_FROM_RECENTS;
361 import static com.android.server.am.TaskRecord.INVALID_TASK_ID;
362 import static com.android.server.am.TaskRecord.LOCK_TASK_AUTH_DONT_LOCK;
363 import static com.android.server.am.TaskRecord.LOCK_TASK_AUTH_LAUNCHABLE_PRIV;
364 import static com.android.server.am.TaskRecord.LOCK_TASK_AUTH_PINNABLE;
365 import static com.android.server.wm.AppTransition.TRANSIT_ACTIVITY_OPEN;
366 import static com.android.server.wm.AppTransition.TRANSIT_ACTIVITY_RELAUNCH;
367 import static com.android.server.wm.AppTransition.TRANSIT_TASK_IN_PLACE;
368 import static com.android.server.wm.AppTransition.TRANSIT_TASK_OPEN;
369 import static com.android.server.wm.AppTransition.TRANSIT_TASK_TO_FRONT;
370 import static org.xmlpull.v1.XmlPullParser.END_DOCUMENT;
371 import static org.xmlpull.v1.XmlPullParser.START_TAG;
372
373 public final class ActivityManagerService extends ActivityManagerNative
374         implements Watchdog.Monitor, BatteryStatsImpl.BatteryCallback {
375
376     private static final String TAG = TAG_WITH_CLASS_NAME ? "ActivityManagerService" : TAG_AM;
377     private static final String TAG_BACKUP = TAG + POSTFIX_BACKUP;
378     private static final String TAG_BROADCAST = TAG + POSTFIX_BROADCAST;
379     private static final String TAG_CLEANUP = TAG + POSTFIX_CLEANUP;
380     private static final String TAG_CONFIGURATION = TAG + POSTFIX_CONFIGURATION;
381     private static final String TAG_FOCUS = TAG + POSTFIX_FOCUS;
382     private static final String TAG_IMMERSIVE = TAG + POSTFIX_IMMERSIVE;
383     private static final String TAG_LOCKSCREEN = TAG + POSTFIX_LOCKSCREEN;
384     private static final String TAG_LOCKTASK = TAG + POSTFIX_LOCKTASK;
385     private static final String TAG_LRU = TAG + POSTFIX_LRU;
386     private static final String TAG_MU = TAG + POSTFIX_MU;
387     private static final String TAG_OOM_ADJ = TAG + POSTFIX_OOM_ADJ;
388     private static final String TAG_POWER = TAG + POSTFIX_POWER;
389     private static final String TAG_PROCESS_OBSERVERS = TAG + POSTFIX_PROCESS_OBSERVERS;
390     private static final String TAG_PROCESSES = TAG + POSTFIX_PROCESSES;
391     private static final String TAG_PROVIDER = TAG + POSTFIX_PROVIDER;
392     private static final String TAG_PSS = TAG + POSTFIX_PSS;
393     private static final String TAG_RECENTS = TAG + POSTFIX_RECENTS;
394     private static final String TAG_SERVICE = TAG + POSTFIX_SERVICE;
395     private static final String TAG_STACK = TAG + POSTFIX_STACK;
396     private static final String TAG_SWITCH = TAG + POSTFIX_SWITCH;
397     private static final String TAG_UID_OBSERVERS = TAG + POSTFIX_UID_OBSERVERS;
398     private static final String TAG_URI_PERMISSION = TAG + POSTFIX_URI_PERMISSION;
399     private static final String TAG_VISIBILITY = TAG + POSTFIX_VISIBILITY;
400     private static final String TAG_VISIBLE_BEHIND = TAG + POSTFIX_VISIBLE_BEHIND;
401
402     // Mock "pretend we're idle now" broadcast action to the job scheduler; declared
403     // here so that while the job scheduler can depend on AMS, the other way around
404     // need not be the case.
405     public static final String ACTION_TRIGGER_IDLE = "com.android.server.ACTION_TRIGGER_IDLE";
406
407     /** Control over CPU and battery monitoring */
408     // write battery stats every 30 minutes.
409     static final long BATTERY_STATS_TIME = 30 * 60 * 1000;
410     static final boolean MONITOR_CPU_USAGE = true;
411     // don't sample cpu less than every 5 seconds.
412     static final long MONITOR_CPU_MIN_TIME = 5 * 1000;
413     // wait possibly forever for next cpu sample.
414     static final long MONITOR_CPU_MAX_TIME = 0x0fffffff;
415     static final boolean MONITOR_THREAD_CPU_USAGE = false;
416
417     // The flags that are set for all calls we make to the package manager.
418     static final int STOCK_PM_FLAGS = PackageManager.GET_SHARED_LIBRARY_FILES;
419
420     static final String SYSTEM_DEBUGGABLE = "ro.debuggable";
421
422     static final boolean IS_USER_BUILD = "user".equals(Build.TYPE);
423
424     // Amount of time after a call to stopAppSwitches() during which we will
425     // prevent further untrusted switches from happening.
426     static final long APP_SWITCH_DELAY_TIME = 5*1000;
427
428     // How long we wait for a launched process to attach to the activity manager
429     // before we decide it's never going to come up for real.
430     static final int PROC_START_TIMEOUT = 10*1000;
431     // How long we wait for an attached process to publish its content providers
432     // before we decide it must be hung.
433     static final int CONTENT_PROVIDER_PUBLISH_TIMEOUT = 10*1000;
434
435     // How long we will retain processes hosting content providers in the "last activity"
436     // state before allowing them to drop down to the regular cached LRU list.  This is
437     // to avoid thrashing of provider processes under low memory situations.
438     static final int CONTENT_PROVIDER_RETAIN_TIME = 20*1000;
439
440     // How long we wait for a launched process to attach to the activity manager
441     // before we decide it's never going to come up for real, when the process was
442     // started with a wrapper for instrumentation (such as Valgrind) because it
443     // could take much longer than usual.
444     static final int PROC_START_TIMEOUT_WITH_WRAPPER = 1200*1000;
445
446     // How long to wait after going idle before forcing apps to GC.
447     static final int GC_TIMEOUT = 5*1000;
448
449     // The minimum amount of time between successive GC requests for a process.
450     static final int GC_MIN_INTERVAL = 60*1000;
451
452     // The minimum amount of time between successive PSS requests for a process.
453     static final int FULL_PSS_MIN_INTERVAL = 10*60*1000;
454
455     // The minimum amount of time between successive PSS requests for a process
456     // when the request is due to the memory state being lowered.
457     static final int FULL_PSS_LOWERED_INTERVAL = 2*60*1000;
458
459     // The rate at which we check for apps using excessive power -- 15 mins.
460     static final int POWER_CHECK_DELAY = (DEBUG_POWER_QUICK ? 2 : 15) * 60*1000;
461
462     // The minimum sample duration we will allow before deciding we have
463     // enough data on wake locks to start killing things.
464     static final int WAKE_LOCK_MIN_CHECK_DURATION = (DEBUG_POWER_QUICK ? 1 : 5) * 60*1000;
465
466     // The minimum sample duration we will allow before deciding we have
467     // enough data on CPU usage to start killing things.
468     static final int CPU_MIN_CHECK_DURATION = (DEBUG_POWER_QUICK ? 1 : 5) * 60*1000;
469
470     // How long we allow a receiver to run before giving up on it.
471     static final int BROADCAST_FG_TIMEOUT = 10*1000;
472     static final int BROADCAST_BG_TIMEOUT = 60*1000;
473
474     // How long we wait until we timeout on key dispatching.
475     static final int KEY_DISPATCHING_TIMEOUT = 5*1000;
476
477     // How long we wait until we timeout on key dispatching during instrumentation.
478     static final int INSTRUMENTATION_KEY_DISPATCHING_TIMEOUT = 60*1000;
479
480     // This is the amount of time an app needs to be running a foreground service before
481     // we will consider it to be doing interaction for usage stats.
482     static final int SERVICE_USAGE_INTERACTION_TIME = 30*60*1000;
483
484     // Maximum amount of time we will allow to elapse before re-reporting usage stats
485     // interaction with foreground processes.
486     static final long USAGE_STATS_INTERACTION_INTERVAL = 24*60*60*1000L;
487
488     // This is the amount of time we allow an app to settle after it goes into the background,
489     // before we start restricting what it can do.
490     static final int BACKGROUND_SETTLE_TIME = 1*60*1000;
491
492     // How long to wait in getAssistContextExtras for the activity and foreground services
493     // to respond with the result.
494     static final int PENDING_ASSIST_EXTRAS_TIMEOUT = 500;
495
496     // How long top wait when going through the modern assist (which doesn't need to block
497     // on getting this result before starting to launch its UI).
498     static final int PENDING_ASSIST_EXTRAS_LONG_TIMEOUT = 2000;
499
500     // Maximum number of persisted Uri grants a package is allowed
501     static final int MAX_PERSISTED_URI_GRANTS = 128;
502
503     static final int MY_PID = Process.myPid();
504
505     static final String[] EMPTY_STRING_ARRAY = new String[0];
506
507     // How many bytes to write into the dropbox log before truncating
508     static final int DROPBOX_MAX_SIZE = 192 * 1024;
509     // Assumes logcat entries average around 100 bytes; that's not perfect stack traces count
510     // as one line, but close enough for now.
511     static final int RESERVED_BYTES_PER_LOGCAT_LINE = 100;
512
513     // Access modes for handleIncomingUser.
514     static final int ALLOW_NON_FULL = 0;
515     static final int ALLOW_NON_FULL_IN_PROFILE = 1;
516     static final int ALLOW_FULL_ONLY = 2;
517
518     // Delay in notifying task stack change listeners (in millis)
519     static final int NOTIFY_TASK_STACK_CHANGE_LISTENERS_DELAY = 100;
520
521     // Necessary ApplicationInfo flags to mark an app as persistent
522     private static final int PERSISTENT_MASK =
523             ApplicationInfo.FLAG_SYSTEM|ApplicationInfo.FLAG_PERSISTENT;
524
525     // Intent sent when remote bugreport collection has been completed
526     private static final String INTENT_REMOTE_BUGREPORT_FINISHED =
527             "android.intent.action.REMOTE_BUGREPORT_FINISHED";
528
529     // Delay to disable app launch boost
530     static final int APP_BOOST_MESSAGE_DELAY = 3000;
531     // Lower delay than APP_BOOST_MESSAGE_DELAY to disable the boost
532     static final int APP_BOOST_TIMEOUT = 2500;
533
534     // Used to indicate that a task is removed it should also be removed from recents.
535     private static final boolean REMOVE_FROM_RECENTS = true;
536     // Used to indicate that an app transition should be animated.
537     static final boolean ANIMATE = true;
538
539     // Determines whether to take full screen screenshots
540     static final boolean TAKE_FULLSCREEN_SCREENSHOTS = true;
541     public static final float FULLSCREEN_SCREENSHOT_SCALE = 0.6f;
542
543     private static native int nativeMigrateToBoost();
544     private static native int nativeMigrateFromBoost();
545     private boolean mIsBoosted = false;
546     private long mBoostStartTime = 0;
547
548     /** All system services */
549     SystemServiceManager mSystemServiceManager;
550
551     private Installer mInstaller;
552
553     /** Run all ActivityStacks through this */
554     final ActivityStackSupervisor mStackSupervisor;
555
556     final ActivityStarter mActivityStarter;
557
558     /** Task stack change listeners. */
559     private final RemoteCallbackList<ITaskStackListener> mTaskStackListeners =
560             new RemoteCallbackList<ITaskStackListener>();
561
562     final InstrumentationReporter mInstrumentationReporter = new InstrumentationReporter();
563
564     public IntentFirewall mIntentFirewall;
565
566     // Whether we should show our dialogs (ANR, crash, etc) or just perform their
567     // default actuion automatically.  Important for devices without direct input
568     // devices.
569     private boolean mShowDialogs = true;
570     private boolean mInVrMode = false;
571
572     BroadcastQueue mFgBroadcastQueue;
573     BroadcastQueue mBgBroadcastQueue;
574     // Convenient for easy iteration over the queues. Foreground is first
575     // so that dispatch of foreground broadcasts gets precedence.
576     final BroadcastQueue[] mBroadcastQueues = new BroadcastQueue[2];
577
578     BroadcastStats mLastBroadcastStats;
579     BroadcastStats mCurBroadcastStats;
580
581     BroadcastQueue broadcastQueueForIntent(Intent intent) {
582         final boolean isFg = (intent.getFlags() & Intent.FLAG_RECEIVER_FOREGROUND) != 0;
583         if (DEBUG_BROADCAST_BACKGROUND) Slog.i(TAG_BROADCAST,
584                 "Broadcast intent " + intent + " on "
585                 + (isFg ? "foreground" : "background") + " queue");
586         return (isFg) ? mFgBroadcastQueue : mBgBroadcastQueue;
587     }
588
589     /**
590      * Activity we have told the window manager to have key focus.
591      */
592     ActivityRecord mFocusedActivity = null;
593
594     /**
595      * User id of the last activity mFocusedActivity was set to.
596      */
597     private int mLastFocusedUserId;
598
599     /**
600      * If non-null, we are tracking the time the user spends in the currently focused app.
601      */
602     private AppTimeTracker mCurAppTimeTracker;
603
604     /**
605      * List of intents that were used to start the most recent tasks.
606      */
607     final RecentTasks mRecentTasks;
608
609     /**
610      * For addAppTask: cached of the last activity component that was added.
611      */
612     ComponentName mLastAddedTaskComponent;
613
614     /**
615      * For addAppTask: cached of the last activity uid that was added.
616      */
617     int mLastAddedTaskUid;
618
619     /**
620      * For addAppTask: cached of the last ActivityInfo that was added.
621      */
622     ActivityInfo mLastAddedTaskActivity;
623
624     /**
625      * List of packages whitelisted by DevicePolicyManager for locktask. Indexed by userId.
626      */
627     SparseArray<String[]> mLockTaskPackages = new SparseArray<>();
628
629     /**
630      * The package name of the DeviceOwner. This package is not permitted to have its data cleared.
631      */
632     String mDeviceOwnerName;
633
634     final UserController mUserController;
635
636     final AppErrors mAppErrors;
637
638     boolean mDoingSetFocusedActivity;
639
640     public boolean canShowErrorDialogs() {
641         return mShowDialogs && !mSleeping && !mShuttingDown;
642     }
643
644     // it's a semaphore; boost when 0->1, reset when 1->0
645     static ThreadLocal<Integer> sIsBoosted = new ThreadLocal<Integer>() {
646         @Override protected Integer initialValue() {
647             return 0;
648         }
649     };
650
651     static void boostPriorityForLockedSection() {
652         if (sIsBoosted.get() == 0) {
653             // boost to prio 118 while holding a global lock
654             Process.setThreadPriority(Process.myTid(), -2);
655             //Log.e(TAG, "PRIORITY BOOST:  set priority on TID " + Process.myTid());
656         }
657         int cur = sIsBoosted.get();
658         sIsBoosted.set(cur + 1);
659     }
660
661     static void resetPriorityAfterLockedSection() {
662         sIsBoosted.set(sIsBoosted.get() - 1);
663         if (sIsBoosted.get() == 0) {
664             //Log.e(TAG, "PRIORITY BOOST:  reset priority on TID " + Process.myTid());
665             Process.setThreadPriority(Process.myTid(), 0);
666         }
667     }
668     public class PendingAssistExtras extends Binder implements Runnable {
669         public final ActivityRecord activity;
670         public final Bundle extras;
671         public final Intent intent;
672         public final String hint;
673         public final IResultReceiver receiver;
674         public final int userHandle;
675         public boolean haveResult = false;
676         public Bundle result = null;
677         public AssistStructure structure = null;
678         public AssistContent content = null;
679         public Bundle receiverExtras;
680
681         public PendingAssistExtras(ActivityRecord _activity, Bundle _extras, Intent _intent,
682                 String _hint, IResultReceiver _receiver, Bundle _receiverExtras, int _userHandle) {
683             activity = _activity;
684             extras = _extras;
685             intent = _intent;
686             hint = _hint;
687             receiver = _receiver;
688             receiverExtras = _receiverExtras;
689             userHandle = _userHandle;
690         }
691         @Override
692         public void run() {
693             Slog.w(TAG, "getAssistContextExtras failed: timeout retrieving from " + activity);
694             synchronized (this) {
695                 haveResult = true;
696                 notifyAll();
697             }
698             pendingAssistExtrasTimedOut(this);
699         }
700     }
701
702     final ArrayList<PendingAssistExtras> mPendingAssistExtras
703             = new ArrayList<PendingAssistExtras>();
704
705     /**
706      * Process management.
707      */
708     final ProcessList mProcessList = new ProcessList();
709
710     /**
711      * All of the applications we currently have running organized by name.
712      * The keys are strings of the application package name (as
713      * returned by the package manager), and the keys are ApplicationRecord
714      * objects.
715      */
716     final ProcessMap<ProcessRecord> mProcessNames = new ProcessMap<ProcessRecord>();
717
718     /**
719      * Tracking long-term execution of processes to look for abuse and other
720      * bad app behavior.
721      */
722     final ProcessStatsService mProcessStats;
723
724     /**
725      * The currently running isolated processes.
726      */
727     final SparseArray<ProcessRecord> mIsolatedProcesses = new SparseArray<ProcessRecord>();
728
729     /**
730      * Counter for assigning isolated process uids, to avoid frequently reusing the
731      * same ones.
732      */
733     int mNextIsolatedProcessUid = 0;
734
735     /**
736      * The currently running heavy-weight process, if any.
737      */
738     ProcessRecord mHeavyWeightProcess = null;
739
740     /**
741      * All of the processes we currently have running organized by pid.
742      * The keys are the pid running the application.
743      *
744      * <p>NOTE: This object is protected by its own lock, NOT the global
745      * activity manager lock!
746      */
747     final SparseArray<ProcessRecord> mPidsSelfLocked = new SparseArray<ProcessRecord>();
748
749     /**
750      * All of the processes that have been forced to be foreground.  The key
751      * is the pid of the caller who requested it (we hold a death
752      * link on it).
753      */
754     abstract class ForegroundToken implements IBinder.DeathRecipient {
755         int pid;
756         IBinder token;
757     }
758     final SparseArray<ForegroundToken> mForegroundProcesses = new SparseArray<ForegroundToken>();
759
760     /**
761      * List of records for processes that someone had tried to start before the
762      * system was ready.  We don't start them at that point, but ensure they
763      * are started by the time booting is complete.
764      */
765     final ArrayList<ProcessRecord> mProcessesOnHold = new ArrayList<ProcessRecord>();
766
767     /**
768      * List of persistent applications that are in the process
769      * of being started.
770      */
771     final ArrayList<ProcessRecord> mPersistentStartingProcesses = new ArrayList<ProcessRecord>();
772
773     /**
774      * Processes that are being forcibly torn down.
775      */
776     final ArrayList<ProcessRecord> mRemovedProcesses = new ArrayList<ProcessRecord>();
777
778     /**
779      * List of running applications, sorted by recent usage.
780      * The first entry in the list is the least recently used.
781      */
782     final ArrayList<ProcessRecord> mLruProcesses = new ArrayList<ProcessRecord>();
783
784     /**
785      * Where in mLruProcesses that the processes hosting activities start.
786      */
787     int mLruProcessActivityStart = 0;
788
789     /**
790      * Where in mLruProcesses that the processes hosting services start.
791      * This is after (lower index) than mLruProcessesActivityStart.
792      */
793     int mLruProcessServiceStart = 0;
794
795     /**
796      * List of processes that should gc as soon as things are idle.
797      */
798     final ArrayList<ProcessRecord> mProcessesToGc = new ArrayList<ProcessRecord>();
799
800     /**
801      * Processes we want to collect PSS data from.
802      */
803     final ArrayList<ProcessRecord> mPendingPssProcesses = new ArrayList<ProcessRecord>();
804
805     private boolean mBinderTransactionTrackingEnabled = false;
806
807     /**
808      * Last time we requested PSS data of all processes.
809      */
810     long mLastFullPssTime = SystemClock.uptimeMillis();
811
812     /**
813      * If set, the next time we collect PSS data we should do a full collection
814      * with data from native processes and the kernel.
815      */
816     boolean mFullPssPending = false;
817
818     /**
819      * This is the process holding what we currently consider to be
820      * the "home" activity.
821      */
822     ProcessRecord mHomeProcess;
823
824     /**
825      * This is the process holding the activity the user last visited that
826      * is in a different process from the one they are currently in.
827      */
828     ProcessRecord mPreviousProcess;
829
830     /**
831      * The time at which the previous process was last visible.
832      */
833     long mPreviousProcessVisibleTime;
834
835     /**
836      * Track all uids that have actively running processes.
837      */
838     final SparseArray<UidRecord> mActiveUids = new SparseArray<>();
839
840     /**
841      * This is for verifying the UID report flow.
842      */
843     static final boolean VALIDATE_UID_STATES = true;
844     final SparseArray<UidRecord> mValidateUids = new SparseArray<>();
845
846     /**
847      * Packages that the user has asked to have run in screen size
848      * compatibility mode instead of filling the screen.
849      */
850     final CompatModePackages mCompatModePackages;
851
852     /**
853      * Set of IntentSenderRecord objects that are currently active.
854      */
855     final HashMap<PendingIntentRecord.Key, WeakReference<PendingIntentRecord>> mIntentSenderRecords
856             = new HashMap<PendingIntentRecord.Key, WeakReference<PendingIntentRecord>>();
857
858     /**
859      * Fingerprints (hashCode()) of stack traces that we've
860      * already logged DropBox entries for.  Guarded by itself.  If
861      * something (rogue user app) forces this over
862      * MAX_DUP_SUPPRESSED_STACKS entries, the contents are cleared.
863      */
864     private final HashSet<Integer> mAlreadyLoggedViolatedStacks = new HashSet<Integer>();
865     private static final int MAX_DUP_SUPPRESSED_STACKS = 5000;
866
867     /**
868      * Strict Mode background batched logging state.
869      *
870      * The string buffer is guarded by itself, and its lock is also
871      * used to determine if another batched write is already
872      * in-flight.
873      */
874     private final StringBuilder mStrictModeBuffer = new StringBuilder();
875
876     /**
877      * Keeps track of all IIntentReceivers that have been registered for broadcasts.
878      * Hash keys are the receiver IBinder, hash value is a ReceiverList.
879      */
880     final HashMap<IBinder, ReceiverList> mRegisteredReceivers = new HashMap<>();
881
882     /**
883      * Resolver for broadcast intents to registered receivers.
884      * Holds BroadcastFilter (subclass of IntentFilter).
885      */
886     final IntentResolver<BroadcastFilter, BroadcastFilter> mReceiverResolver
887             = new IntentResolver<BroadcastFilter, BroadcastFilter>() {
888         @Override
889         protected boolean allowFilterResult(
890                 BroadcastFilter filter, List<BroadcastFilter> dest) {
891             IBinder target = filter.receiverList.receiver.asBinder();
892             for (int i = dest.size() - 1; i >= 0; i--) {
893                 if (dest.get(i).receiverList.receiver.asBinder() == target) {
894                     return false;
895                 }
896             }
897             return true;
898         }
899
900         @Override
901         protected BroadcastFilter newResult(BroadcastFilter filter, int match, int userId) {
902             if (userId == UserHandle.USER_ALL || filter.owningUserId == UserHandle.USER_ALL
903                     || userId == filter.owningUserId) {
904                 return super.newResult(filter, match, userId);
905             }
906             return null;
907         }
908
909         @Override
910         protected BroadcastFilter[] newArray(int size) {
911             return new BroadcastFilter[size];
912         }
913
914         @Override
915         protected boolean isPackageForFilter(String packageName, BroadcastFilter filter) {
916             return packageName.equals(filter.packageName);
917         }
918     };
919
920     /**
921      * State of all active sticky broadcasts per user.  Keys are the action of the
922      * sticky Intent, values are an ArrayList of all broadcasted intents with
923      * that action (which should usually be one).  The SparseArray is keyed
924      * by the user ID the sticky is for, and can include UserHandle.USER_ALL
925      * for stickies that are sent to all users.
926      */
927     final SparseArray<ArrayMap<String, ArrayList<Intent>>> mStickyBroadcasts =
928             new SparseArray<ArrayMap<String, ArrayList<Intent>>>();
929
930     final ActiveServices mServices;
931
932     final static class Association {
933         final int mSourceUid;
934         final String mSourceProcess;
935         final int mTargetUid;
936         final ComponentName mTargetComponent;
937         final String mTargetProcess;
938
939         int mCount;
940         long mTime;
941
942         int mNesting;
943         long mStartTime;
944
945         // states of the source process when the bind occurred.
946         int mLastState = ActivityManager.MAX_PROCESS_STATE + 1;
947         long mLastStateUptime;
948         long[] mStateTimes = new long[ActivityManager.MAX_PROCESS_STATE
949                 - ActivityManager.MIN_PROCESS_STATE+1];
950
951         Association(int sourceUid, String sourceProcess, int targetUid,
952                 ComponentName targetComponent, String targetProcess) {
953             mSourceUid = sourceUid;
954             mSourceProcess = sourceProcess;
955             mTargetUid = targetUid;
956             mTargetComponent = targetComponent;
957             mTargetProcess = targetProcess;
958         }
959     }
960
961     /**
962      * When service association tracking is enabled, this is all of the associations we
963      * have seen.  Mapping is target uid -> target component -> source uid -> source process name
964      * -> association data.
965      */
966     final SparseArray<ArrayMap<ComponentName, SparseArray<ArrayMap<String, Association>>>>
967             mAssociations = new SparseArray<>();
968     boolean mTrackingAssociations;
969
970     /**
971      * Backup/restore process management
972      */
973     String mBackupAppName = null;
974     BackupRecord mBackupTarget = null;
975
976     final ProviderMap mProviderMap;
977
978     /**
979      * List of content providers who have clients waiting for them.  The
980      * application is currently being launched and the provider will be
981      * removed from this list once it is published.
982      */
983     final ArrayList<ContentProviderRecord> mLaunchingProviders
984             = new ArrayList<ContentProviderRecord>();
985
986     /**
987      * File storing persisted {@link #mGrantedUriPermissions}.
988      */
989     private final AtomicFile mGrantFile;
990
991     /** XML constants used in {@link #mGrantFile} */
992     private static final String TAG_URI_GRANTS = "uri-grants";
993     private static final String TAG_URI_GRANT = "uri-grant";
994     private static final String ATTR_USER_HANDLE = "userHandle";
995     private static final String ATTR_SOURCE_USER_ID = "sourceUserId";
996     private static final String ATTR_TARGET_USER_ID = "targetUserId";
997     private static final String ATTR_SOURCE_PKG = "sourcePkg";
998     private static final String ATTR_TARGET_PKG = "targetPkg";
999     private static final String ATTR_URI = "uri";
1000     private static final String ATTR_MODE_FLAGS = "modeFlags";
1001     private static final String ATTR_CREATED_TIME = "createdTime";
1002     private static final String ATTR_PREFIX = "prefix";
1003
1004     /**
1005      * Global set of specific {@link Uri} permissions that have been granted.
1006      * This optimized lookup structure maps from {@link UriPermission#targetUid}
1007      * to {@link UriPermission#uri} to {@link UriPermission}.
1008      */
1009     @GuardedBy("this")
1010     private final SparseArray<ArrayMap<GrantUri, UriPermission>>
1011             mGrantedUriPermissions = new SparseArray<ArrayMap<GrantUri, UriPermission>>();
1012
1013     public static class GrantUri {
1014         public final int sourceUserId;
1015         public final Uri uri;
1016         public boolean prefix;
1017
1018         public GrantUri(int sourceUserId, Uri uri, boolean prefix) {
1019             this.sourceUserId = sourceUserId;
1020             this.uri = uri;
1021             this.prefix = prefix;
1022         }
1023
1024         @Override
1025         public int hashCode() {
1026             int hashCode = 1;
1027             hashCode = 31 * hashCode + sourceUserId;
1028             hashCode = 31 * hashCode + uri.hashCode();
1029             hashCode = 31 * hashCode + (prefix ? 1231 : 1237);
1030             return hashCode;
1031         }
1032
1033         @Override
1034         public boolean equals(Object o) {
1035             if (o instanceof GrantUri) {
1036                 GrantUri other = (GrantUri) o;
1037                 return uri.equals(other.uri) && (sourceUserId == other.sourceUserId)
1038                         && prefix == other.prefix;
1039             }
1040             return false;
1041         }
1042
1043         @Override
1044         public String toString() {
1045             String result = Integer.toString(sourceUserId) + " @ " + uri.toString();
1046             if (prefix) result += " [prefix]";
1047             return result;
1048         }
1049
1050         public String toSafeString() {
1051             String result = Integer.toString(sourceUserId) + " @ " + uri.toSafeString();
1052             if (prefix) result += " [prefix]";
1053             return result;
1054         }
1055
1056         public static GrantUri resolve(int defaultSourceUserHandle, Uri uri) {
1057             return new GrantUri(ContentProvider.getUserIdFromUri(uri, defaultSourceUserHandle),
1058                     ContentProvider.getUriWithoutUserId(uri), false);
1059         }
1060     }
1061
1062     CoreSettingsObserver mCoreSettingsObserver;
1063
1064     FontScaleSettingObserver mFontScaleSettingObserver;
1065
1066     private final class FontScaleSettingObserver extends ContentObserver {
1067         private final Uri mFontScaleUri = Settings.System.getUriFor(FONT_SCALE);
1068
1069         public FontScaleSettingObserver() {
1070             super(mHandler);
1071             ContentResolver resolver = mContext.getContentResolver();
1072             resolver.registerContentObserver(mFontScaleUri, false, this, UserHandle.USER_ALL);
1073         }
1074
1075         @Override
1076         public void onChange(boolean selfChange, Uri uri) {
1077             if (mFontScaleUri.equals(uri)) {
1078                 updateFontScaleIfNeeded();
1079             }
1080         }
1081     }
1082
1083     /**
1084      * Thread-local storage used to carry caller permissions over through
1085      * indirect content-provider access.
1086      */
1087     private class Identity {
1088         public final IBinder token;
1089         public final int pid;
1090         public final int uid;
1091
1092         Identity(IBinder _token, int _pid, int _uid) {
1093             token = _token;
1094             pid = _pid;
1095             uid = _uid;
1096         }
1097     }
1098
1099     private static final ThreadLocal<Identity> sCallerIdentity = new ThreadLocal<Identity>();
1100
1101     /**
1102      * All information we have collected about the runtime performance of
1103      * any user id that can impact battery performance.
1104      */
1105     final BatteryStatsService mBatteryStatsService;
1106
1107     /**
1108      * Information about component usage
1109      */
1110     UsageStatsManagerInternal mUsageStatsService;
1111
1112     /**
1113      * Access to DeviceIdleController service.
1114      */
1115     DeviceIdleController.LocalService mLocalDeviceIdleController;
1116
1117     /**
1118      * Information about and control over application operations
1119      */
1120     final AppOpsService mAppOpsService;
1121
1122     /**
1123      * Current configuration information.  HistoryRecord objects are given
1124      * a reference to this object to indicate which configuration they are
1125      * currently running in, so this object must be kept immutable.
1126      */
1127     Configuration mConfiguration = new Configuration();
1128
1129     /**
1130      * Current sequencing integer of the configuration, for skipping old
1131      * configurations.
1132      */
1133     int mConfigurationSeq = 0;
1134
1135     boolean mSuppressResizeConfigChanges = false;
1136
1137     /**
1138      * Hardware-reported OpenGLES version.
1139      */
1140     final int GL_ES_VERSION;
1141
1142     /**
1143      * List of initialization arguments to pass to all processes when binding applications to them.
1144      * For example, references to the commonly used services.
1145      */
1146     HashMap<String, IBinder> mAppBindArgs;
1147     HashMap<String, IBinder> mIsolatedAppBindArgs;
1148
1149     /**
1150      * Temporary to avoid allocations.  Protected by main lock.
1151      */
1152     final StringBuilder mStringBuilder = new StringBuilder(256);
1153
1154     /**
1155      * Used to control how we initialize the service.
1156      */
1157     ComponentName mTopComponent;
1158     String mTopAction = Intent.ACTION_MAIN;
1159     String mTopData;
1160
1161     volatile boolean mProcessesReady = false;
1162     volatile boolean mSystemReady = false;
1163     volatile boolean mOnBattery = false;
1164     volatile int mFactoryTest;
1165
1166     @GuardedBy("this") boolean mBooting = false;
1167     @GuardedBy("this") boolean mCallFinishBooting = false;
1168     @GuardedBy("this") boolean mBootAnimationComplete = false;
1169     @GuardedBy("this") boolean mLaunchWarningShown = false;
1170     @GuardedBy("this") boolean mCheckedForSetup = false;
1171
1172     Context mContext;
1173
1174     /**
1175      * The time at which we will allow normal application switches again,
1176      * after a call to {@link #stopAppSwitches()}.
1177      */
1178     long mAppSwitchesAllowedTime;
1179
1180     /**
1181      * This is set to true after the first switch after mAppSwitchesAllowedTime
1182      * is set; any switches after that will clear the time.
1183      */
1184     boolean mDidAppSwitch;
1185
1186     /**
1187      * Last time (in realtime) at which we checked for power usage.
1188      */
1189     long mLastPowerCheckRealtime;
1190
1191     /**
1192      * Last time (in uptime) at which we checked for power usage.
1193      */
1194     long mLastPowerCheckUptime;
1195
1196     /**
1197      * Set while we are wanting to sleep, to prevent any
1198      * activities from being started/resumed.
1199      */
1200     private boolean mSleeping = false;
1201
1202     /**
1203      * The process state used for processes that are running the top activities.
1204      * This changes between TOP and TOP_SLEEPING to following mSleeping.
1205      */
1206     int mTopProcessState = ActivityManager.PROCESS_STATE_TOP;
1207
1208     /**
1209      * Set while we are running a voice interaction.  This overrides
1210      * sleeping while it is active.
1211      */
1212     private IVoiceInteractionSession mRunningVoice;
1213
1214     /**
1215      * For some direct access we need to power manager.
1216      */
1217     PowerManagerInternal mLocalPowerManager;
1218
1219     /**
1220      * We want to hold a wake lock while running a voice interaction session, since
1221      * this may happen with the screen off and we need to keep the CPU running to
1222      * be able to continue to interact with the user.
1223      */
1224     PowerManager.WakeLock mVoiceWakeLock;
1225
1226     /**
1227      * State of external calls telling us if the device is awake or asleep.
1228      */
1229     private int mWakefulness = PowerManagerInternal.WAKEFULNESS_AWAKE;
1230
1231     /**
1232      * A list of tokens that cause the top activity to be put to sleep.
1233      * They are used by components that may hide and block interaction with underlying
1234      * activities.
1235      */
1236     final ArrayList<SleepToken> mSleepTokens = new ArrayList<SleepToken>();
1237
1238     static final int LOCK_SCREEN_HIDDEN = 0;
1239     static final int LOCK_SCREEN_LEAVING = 1;
1240     static final int LOCK_SCREEN_SHOWN = 2;
1241     /**
1242      * State of external call telling us if the lock screen is shown.
1243      */
1244     int mLockScreenShown = LOCK_SCREEN_HIDDEN;
1245
1246     /**
1247      * Set if we are shutting down the system, similar to sleeping.
1248      */
1249     boolean mShuttingDown = false;
1250
1251     /**
1252      * Current sequence id for oom_adj computation traversal.
1253      */
1254     int mAdjSeq = 0;
1255
1256     /**
1257      * Current sequence id for process LRU updating.
1258      */
1259     int mLruSeq = 0;
1260
1261     /**
1262      * Keep track of the non-cached/empty process we last found, to help
1263      * determine how to distribute cached/empty processes next time.
1264      */
1265     int mNumNonCachedProcs = 0;
1266
1267     /**
1268      * Keep track of the number of cached hidden procs, to balance oom adj
1269      * distribution between those and empty procs.
1270      */
1271     int mNumCachedHiddenProcs = 0;
1272
1273     /**
1274      * Keep track of the number of service processes we last found, to
1275      * determine on the next iteration which should be B services.
1276      */
1277     int mNumServiceProcs = 0;
1278     int mNewNumAServiceProcs = 0;
1279     int mNewNumServiceProcs = 0;
1280
1281     /**
1282      * Allow the current computed overall memory level of the system to go down?
1283      * This is set to false when we are killing processes for reasons other than
1284      * memory management, so that the now smaller process list will not be taken as
1285      * an indication that memory is tighter.
1286      */
1287     boolean mAllowLowerMemLevel = false;
1288
1289     /**
1290      * The last computed memory level, for holding when we are in a state that
1291      * processes are going away for other reasons.
1292      */
1293     int mLastMemoryLevel = ProcessStats.ADJ_MEM_FACTOR_NORMAL;
1294
1295     /**
1296      * The last total number of process we have, to determine if changes actually look
1297      * like a shrinking number of process due to lower RAM.
1298      */
1299     int mLastNumProcesses;
1300
1301     /**
1302      * The uptime of the last time we performed idle maintenance.
1303      */
1304     long mLastIdleTime = SystemClock.uptimeMillis();
1305
1306     /**
1307      * Total time spent with RAM that has been added in the past since the last idle time.
1308      */
1309     long mLowRamTimeSinceLastIdle = 0;
1310
1311     /**
1312      * If RAM is currently low, when that horrible situation started.
1313      */
1314     long mLowRamStartTime = 0;
1315
1316     /**
1317      * For reporting to battery stats the current top application.
1318      */
1319     private String mCurResumedPackage = null;
1320     private int mCurResumedUid = -1;
1321
1322     /**
1323      * For reporting to battery stats the apps currently running foreground
1324      * service.  The ProcessMap is package/uid tuples; each of these contain
1325      * an array of the currently foreground processes.
1326      */
1327     final ProcessMap<ArrayList<ProcessRecord>> mForegroundPackages
1328             = new ProcessMap<ArrayList<ProcessRecord>>();
1329
1330     /**
1331      * This is set if we had to do a delayed dexopt of an app before launching
1332      * it, to increase the ANR timeouts in that case.
1333      */
1334     boolean mDidDexOpt;
1335
1336     /**
1337      * Set if the systemServer made a call to enterSafeMode.
1338      */
1339     boolean mSafeMode;
1340
1341     /**
1342      * If true, we are running under a test environment so will sample PSS from processes
1343      * much more rapidly to try to collect better data when the tests are rapidly
1344      * running through apps.
1345      */
1346     boolean mTestPssMode = false;
1347
1348     String mDebugApp = null;
1349     boolean mWaitForDebugger = false;
1350     boolean mDebugTransient = false;
1351     String mOrigDebugApp = null;
1352     boolean mOrigWaitForDebugger = false;
1353     boolean mAlwaysFinishActivities = false;
1354     boolean mLenientBackgroundCheck = false;
1355     boolean mForceResizableActivities;
1356     boolean mSupportsMultiWindow;
1357     boolean mSupportsFreeformWindowManagement;
1358     boolean mSupportsPictureInPicture;
1359     boolean mSupportsLeanbackOnly;
1360     Rect mDefaultPinnedStackBounds;
1361     IActivityController mController = null;
1362     boolean mControllerIsAMonkey = false;
1363     String mProfileApp = null;
1364     ProcessRecord mProfileProc = null;
1365     String mProfileFile;
1366     ParcelFileDescriptor mProfileFd;
1367     int mSamplingInterval = 0;
1368     boolean mAutoStopProfiler = false;
1369     int mProfileType = 0;
1370     final ProcessMap<Pair<Long, String>> mMemWatchProcesses = new ProcessMap<>();
1371     String mMemWatchDumpProcName;
1372     String mMemWatchDumpFile;
1373     int mMemWatchDumpPid;
1374     int mMemWatchDumpUid;
1375     String mTrackAllocationApp = null;
1376     String mNativeDebuggingApp = null;
1377
1378     final long[] mTmpLong = new long[2];
1379
1380     static final class ProcessChangeItem {
1381         static final int CHANGE_ACTIVITIES = 1<<0;
1382         static final int CHANGE_PROCESS_STATE = 1<<1;
1383         int changes;
1384         int uid;
1385         int pid;
1386         int processState;
1387         boolean foregroundActivities;
1388     }
1389
1390     final RemoteCallbackList<IProcessObserver> mProcessObservers = new RemoteCallbackList<>();
1391     ProcessChangeItem[] mActiveProcessChanges = new ProcessChangeItem[5];
1392
1393     final ArrayList<ProcessChangeItem> mPendingProcessChanges = new ArrayList<>();
1394     final ArrayList<ProcessChangeItem> mAvailProcessChanges = new ArrayList<>();
1395
1396     final RemoteCallbackList<IUidObserver> mUidObservers = new RemoteCallbackList<>();
1397     UidRecord.ChangeItem[] mActiveUidChanges = new UidRecord.ChangeItem[5];
1398
1399     final ArrayList<UidRecord.ChangeItem> mPendingUidChanges = new ArrayList<>();
1400     final ArrayList<UidRecord.ChangeItem> mAvailUidChanges = new ArrayList<>();
1401
1402     /**
1403      * Runtime CPU use collection thread.  This object's lock is used to
1404      * perform synchronization with the thread (notifying it to run).
1405      */
1406     final Thread mProcessCpuThread;
1407
1408     /**
1409      * Used to collect per-process CPU use for ANRs, battery stats, etc.
1410      * Must acquire this object's lock when accessing it.
1411      * NOTE: this lock will be held while doing long operations (trawling
1412      * through all processes in /proc), so it should never be acquired by
1413      * any critical paths such as when holding the main activity manager lock.
1414      */
1415     final ProcessCpuTracker mProcessCpuTracker = new ProcessCpuTracker(
1416             MONITOR_THREAD_CPU_USAGE);
1417     final AtomicLong mLastCpuTime = new AtomicLong(0);
1418     final AtomicBoolean mProcessCpuMutexFree = new AtomicBoolean(true);
1419
1420     long mLastWriteTime = 0;
1421
1422     /**
1423      * Used to retain an update lock when the foreground activity is in
1424      * immersive mode.
1425      */
1426     final UpdateLock mUpdateLock = new UpdateLock("immersive");
1427
1428     /**
1429      * Set to true after the system has finished booting.
1430      */
1431     boolean mBooted = false;
1432
1433     int mProcessLimit = ProcessList.MAX_CACHED_APPS;
1434     int mProcessLimitOverride = -1;
1435
1436     WindowManagerService mWindowManager;
1437     final ActivityThread mSystemThread;
1438
1439     private final class AppDeathRecipient implements IBinder.DeathRecipient {
1440         final ProcessRecord mApp;
1441         final int mPid;
1442         final IApplicationThread mAppThread;
1443
1444         AppDeathRecipient(ProcessRecord app, int pid,
1445                 IApplicationThread thread) {
1446             if (DEBUG_ALL) Slog.v(
1447                 TAG, "New death recipient " + this
1448                 + " for thread " + thread.asBinder());
1449             mApp = app;
1450             mPid = pid;
1451             mAppThread = thread;
1452         }
1453
1454         @Override
1455         public void binderDied() {
1456             if (DEBUG_ALL) Slog.v(
1457                 TAG, "Death received in " + this
1458                 + " for thread " + mAppThread.asBinder());
1459             synchronized(ActivityManagerService.this) {
1460                 appDiedLocked(mApp, mPid, mAppThread, true);
1461             }
1462         }
1463     }
1464
1465     static final int SHOW_ERROR_UI_MSG = 1;
1466     static final int SHOW_NOT_RESPONDING_UI_MSG = 2;
1467     static final int SHOW_FACTORY_ERROR_UI_MSG = 3;
1468     static final int UPDATE_CONFIGURATION_MSG = 4;
1469     static final int GC_BACKGROUND_PROCESSES_MSG = 5;
1470     static final int WAIT_FOR_DEBUGGER_UI_MSG = 6;
1471     static final int SERVICE_TIMEOUT_MSG = 12;
1472     static final int UPDATE_TIME_ZONE = 13;
1473     static final int SHOW_UID_ERROR_UI_MSG = 14;
1474     static final int SHOW_FINGERPRINT_ERROR_UI_MSG = 15;
1475     static final int PROC_START_TIMEOUT_MSG = 20;
1476     static final int DO_PENDING_ACTIVITY_LAUNCHES_MSG = 21;
1477     static final int KILL_APPLICATION_MSG = 22;
1478     static final int FINALIZE_PENDING_INTENT_MSG = 23;
1479     static final int POST_HEAVY_NOTIFICATION_MSG = 24;
1480     static final int CANCEL_HEAVY_NOTIFICATION_MSG = 25;
1481     static final int SHOW_STRICT_MODE_VIOLATION_UI_MSG = 26;
1482     static final int CHECK_EXCESSIVE_WAKE_LOCKS_MSG = 27;
1483     static final int CLEAR_DNS_CACHE_MSG = 28;
1484     static final int UPDATE_HTTP_PROXY_MSG = 29;
1485     static final int SHOW_COMPAT_MODE_DIALOG_UI_MSG = 30;
1486     static final int DISPATCH_PROCESSES_CHANGED_UI_MSG = 31;
1487     static final int DISPATCH_PROCESS_DIED_UI_MSG = 32;
1488     static final int REPORT_MEM_USAGE_MSG = 33;
1489     static final int REPORT_USER_SWITCH_MSG = 34;
1490     static final int CONTINUE_USER_SWITCH_MSG = 35;
1491     static final int USER_SWITCH_TIMEOUT_MSG = 36;
1492     static final int IMMERSIVE_MODE_LOCK_MSG = 37;
1493     static final int PERSIST_URI_GRANTS_MSG = 38;
1494     static final int REQUEST_ALL_PSS_MSG = 39;
1495     static final int START_PROFILES_MSG = 40;
1496     static final int UPDATE_TIME = 41;
1497     static final int SYSTEM_USER_START_MSG = 42;
1498     static final int SYSTEM_USER_CURRENT_MSG = 43;
1499     static final int ENTER_ANIMATION_COMPLETE_MSG = 44;
1500     static final int FINISH_BOOTING_MSG = 45;
1501     static final int START_USER_SWITCH_UI_MSG = 46;
1502     static final int SEND_LOCALE_TO_MOUNT_DAEMON_MSG = 47;
1503     static final int DISMISS_DIALOG_UI_MSG = 48;
1504     static final int NOTIFY_TASK_STACK_CHANGE_LISTENERS_MSG = 49;
1505     static final int NOTIFY_CLEARTEXT_NETWORK_MSG = 50;
1506     static final int POST_DUMP_HEAP_NOTIFICATION_MSG = 51;
1507     static final int DELETE_DUMPHEAP_MSG = 52;
1508     static final int FOREGROUND_PROFILE_CHANGED_MSG = 53;
1509     static final int DISPATCH_UIDS_CHANGED_UI_MSG = 54;
1510     static final int REPORT_TIME_TRACKER_MSG = 55;
1511     static final int REPORT_USER_SWITCH_COMPLETE_MSG = 56;
1512     static final int SHUTDOWN_UI_AUTOMATION_CONNECTION_MSG = 57;
1513     static final int APP_BOOST_DEACTIVATE_MSG = 58;
1514     static final int CONTENT_PROVIDER_PUBLISH_TIMEOUT_MSG = 59;
1515     static final int IDLE_UIDS_MSG = 60;
1516     static final int SYSTEM_USER_UNLOCK_MSG = 61;
1517     static final int LOG_STACK_STATE = 62;
1518     static final int VR_MODE_CHANGE_MSG = 63;
1519     static final int NOTIFY_ACTIVITY_PINNED_LISTENERS_MSG = 64;
1520     static final int NOTIFY_PINNED_ACTIVITY_RESTART_ATTEMPT_LISTENERS_MSG = 65;
1521     static final int NOTIFY_PINNED_STACK_ANIMATION_ENDED_LISTENERS_MSG = 66;
1522     static final int NOTIFY_FORCED_RESIZABLE_MSG = 67;
1523     static final int NOTIFY_ACTIVITY_DISMISSING_DOCKED_STACK_MSG = 68;
1524     static final int VR_MODE_APPLY_IF_NEEDED_MSG = 69;
1525     static final int SHOW_UNSUPPORTED_DISPLAY_SIZE_DIALOG_MSG = 70;
1526
1527     static final int FIRST_ACTIVITY_STACK_MSG = 100;
1528     static final int FIRST_BROADCAST_QUEUE_MSG = 200;
1529     static final int FIRST_COMPAT_MODE_MSG = 300;
1530     static final int FIRST_SUPERVISOR_STACK_MSG = 100;
1531
1532     static ServiceThread sKillThread = null;
1533     static KillHandler sKillHandler = null;
1534
1535     CompatModeDialog mCompatModeDialog;
1536     UnsupportedDisplaySizeDialog mUnsupportedDisplaySizeDialog;
1537     long mLastMemUsageReportTime = 0;
1538
1539     /**
1540      * Flag whether the current user is a "monkey", i.e. whether
1541      * the UI is driven by a UI automation tool.
1542      */
1543     private boolean mUserIsMonkey;
1544
1545     /** Flag whether the device has a Recents UI */
1546     boolean mHasRecents;
1547
1548     /** The dimensions of the thumbnails in the Recents UI. */
1549     int mThumbnailWidth;
1550     int mThumbnailHeight;
1551     float mFullscreenThumbnailScale;
1552
1553     final ServiceThread mHandlerThread;
1554     final MainHandler mHandler;
1555     final UiHandler mUiHandler;
1556
1557     PackageManagerInternal mPackageManagerInt;
1558
1559     // VoiceInteraction session ID that changes for each new request except when
1560     // being called for multiwindow assist in a single session.
1561     private int mViSessionId = 1000;
1562
1563     final class KillHandler extends Handler {
1564         static final int KILL_PROCESS_GROUP_MSG = 4000;
1565
1566         public KillHandler(Looper looper) {
1567             super(looper, null, true);
1568         }
1569
1570         @Override
1571         public void handleMessage(Message msg) {
1572             switch (msg.what) {
1573                 case KILL_PROCESS_GROUP_MSG:
1574                 {
1575                     Trace.traceBegin(Trace.TRACE_TAG_ACTIVITY_MANAGER, "killProcessGroup");
1576                     Process.killProcessGroup(msg.arg1 /* uid */, msg.arg2 /* pid */);
1577                     Trace.traceEnd(Trace.TRACE_TAG_ACTIVITY_MANAGER);
1578                 }
1579                 break;
1580
1581                 default:
1582                     super.handleMessage(msg);
1583             }
1584         }
1585     }
1586
1587     final class UiHandler extends Handler {
1588         public UiHandler() {
1589             super(com.android.server.UiThread.get().getLooper(), null, true);
1590         }
1591
1592         @Override
1593         public void handleMessage(Message msg) {
1594             switch (msg.what) {
1595             case SHOW_ERROR_UI_MSG: {
1596                 mAppErrors.handleShowAppErrorUi(msg);
1597                 ensureBootCompleted();
1598             } break;
1599             case SHOW_NOT_RESPONDING_UI_MSG: {
1600                 mAppErrors.handleShowAnrUi(msg);
1601                 ensureBootCompleted();
1602             } break;
1603             case SHOW_STRICT_MODE_VIOLATION_UI_MSG: {
1604                 HashMap<String, Object> data = (HashMap<String, Object>) msg.obj;
1605                 synchronized (ActivityManagerService.this) {
1606                     ProcessRecord proc = (ProcessRecord) data.get("app");
1607                     if (proc == null) {
1608                         Slog.e(TAG, "App not found when showing strict mode dialog.");
1609                         break;
1610                     }
1611                     if (proc.crashDialog != null) {
1612                         Slog.e(TAG, "App already has strict mode dialog: " + proc);
1613                         return;
1614                     }
1615                     AppErrorResult res = (AppErrorResult) data.get("result");
1616                     if (mShowDialogs && !mSleeping && !mShuttingDown) {
1617                         Dialog d = new StrictModeViolationDialog(mContext,
1618                                 ActivityManagerService.this, res, proc);
1619                         d.show();
1620                         proc.crashDialog = d;
1621                     } else {
1622                         // The device is asleep, so just pretend that the user
1623                         // saw a crash dialog and hit "force quit".
1624                         res.set(0);
1625                     }
1626                 }
1627                 ensureBootCompleted();
1628             } break;
1629             case SHOW_FACTORY_ERROR_UI_MSG: {
1630                 Dialog d = new FactoryErrorDialog(
1631                     mContext, msg.getData().getCharSequence("msg"));
1632                 d.show();
1633                 ensureBootCompleted();
1634             } break;
1635             case WAIT_FOR_DEBUGGER_UI_MSG: {
1636                 synchronized (ActivityManagerService.this) {
1637                     ProcessRecord app = (ProcessRecord)msg.obj;
1638                     if (msg.arg1 != 0) {
1639                         if (!app.waitedForDebugger) {
1640                             Dialog d = new AppWaitingForDebuggerDialog(
1641                                     ActivityManagerService.this,
1642                                     mContext, app);
1643                             app.waitDialog = d;
1644                             app.waitedForDebugger = true;
1645                             d.show();
1646                         }
1647                     } else {
1648                         if (app.waitDialog != null) {
1649                             app.waitDialog.dismiss();
1650                             app.waitDialog = null;
1651                         }
1652                     }
1653                 }
1654             } break;
1655             case SHOW_UID_ERROR_UI_MSG: {
1656                 if (mShowDialogs) {
1657                     AlertDialog d = new BaseErrorDialog(mContext);
1658                     d.getWindow().setType(WindowManager.LayoutParams.TYPE_SYSTEM_ERROR);
1659                     d.setCancelable(false);
1660                     d.setTitle(mContext.getText(R.string.android_system_label));
1661                     d.setMessage(mContext.getText(R.string.system_error_wipe_data));
1662                     d.setButton(DialogInterface.BUTTON_POSITIVE, mContext.getText(R.string.ok),
1663                             obtainMessage(DISMISS_DIALOG_UI_MSG, d));
1664                     d.show();
1665                 }
1666             } break;
1667             case SHOW_FINGERPRINT_ERROR_UI_MSG: {
1668                 if (mShowDialogs) {
1669                     AlertDialog d = new BaseErrorDialog(mContext);
1670                     d.getWindow().setType(WindowManager.LayoutParams.TYPE_SYSTEM_ERROR);
1671                     d.setCancelable(false);
1672                     d.setTitle(mContext.getText(R.string.android_system_label));
1673                     d.setMessage(mContext.getText(R.string.system_error_manufacturer));
1674                     d.setButton(DialogInterface.BUTTON_POSITIVE, mContext.getText(R.string.ok),
1675                             obtainMessage(DISMISS_DIALOG_UI_MSG, d));
1676                     d.show();
1677                 }
1678             } break;
1679             case SHOW_COMPAT_MODE_DIALOG_UI_MSG: {
1680                 synchronized (ActivityManagerService.this) {
1681                     ActivityRecord ar = (ActivityRecord) msg.obj;
1682                     if (mCompatModeDialog != null) {
1683                         if (mCompatModeDialog.mAppInfo.packageName.equals(
1684                                 ar.info.applicationInfo.packageName)) {
1685                             return;
1686                         }
1687                         mCompatModeDialog.dismiss();
1688                         mCompatModeDialog = null;
1689                     }
1690                     if (ar != null && false) {
1691                         if (mCompatModePackages.getPackageAskCompatModeLocked(
1692                                 ar.packageName)) {
1693                             int mode = mCompatModePackages.computeCompatModeLocked(
1694                                     ar.info.applicationInfo);
1695                             if (mode == ActivityManager.COMPAT_MODE_DISABLED
1696                                     || mode == ActivityManager.COMPAT_MODE_ENABLED) {
1697                                 mCompatModeDialog = new CompatModeDialog(
1698                                         ActivityManagerService.this, mContext,
1699                                         ar.info.applicationInfo);
1700                                 mCompatModeDialog.show();
1701                             }
1702                         }
1703                     }
1704                 }
1705                 break;
1706             }
1707             case SHOW_UNSUPPORTED_DISPLAY_SIZE_DIALOG_MSG: {
1708                 synchronized (ActivityManagerService.this) {
1709                     final ActivityRecord ar = (ActivityRecord) msg.obj;
1710                     if (mUnsupportedDisplaySizeDialog != null) {
1711                         mUnsupportedDisplaySizeDialog.dismiss();
1712                         mUnsupportedDisplaySizeDialog = null;
1713                     }
1714                     if (ar != null && mCompatModePackages.getPackageNotifyUnsupportedZoomLocked(
1715                             ar.packageName)) {
1716                         mUnsupportedDisplaySizeDialog = new UnsupportedDisplaySizeDialog(
1717                                 ActivityManagerService.this, mContext, ar.info.applicationInfo);
1718                         mUnsupportedDisplaySizeDialog.show();
1719                     }
1720                 }
1721                 break;
1722             }
1723             case START_USER_SWITCH_UI_MSG: {
1724                 mUserController.showUserSwitchDialog((Pair<UserInfo, UserInfo>) msg.obj);
1725                 break;
1726             }
1727             case DISMISS_DIALOG_UI_MSG: {
1728                 final Dialog d = (Dialog) msg.obj;
1729                 d.dismiss();
1730                 break;
1731             }
1732             case DISPATCH_PROCESSES_CHANGED_UI_MSG: {
1733                 dispatchProcessesChanged();
1734                 break;
1735             }
1736             case DISPATCH_PROCESS_DIED_UI_MSG: {
1737                 final int pid = msg.arg1;
1738                 final int uid = msg.arg2;
1739                 dispatchProcessDied(pid, uid);
1740                 break;
1741             }
1742             case DISPATCH_UIDS_CHANGED_UI_MSG: {
1743                 dispatchUidsChanged();
1744             } break;
1745             }
1746         }
1747     }
1748
1749     final class MainHandler extends Handler {
1750         public MainHandler(Looper looper) {
1751             super(looper, null, true);
1752         }
1753
1754         @Override
1755         public void handleMessage(Message msg) {
1756             switch (msg.what) {
1757             case UPDATE_CONFIGURATION_MSG: {
1758                 final ContentResolver resolver = mContext.getContentResolver();
1759                 Settings.System.putConfigurationForUser(resolver, (Configuration) msg.obj,
1760                         msg.arg1);
1761             } break;
1762             case GC_BACKGROUND_PROCESSES_MSG: {
1763                 synchronized (ActivityManagerService.this) {
1764                     performAppGcsIfAppropriateLocked();
1765                 }
1766             } break;
1767             case SERVICE_TIMEOUT_MSG: {
1768                 if (mDidDexOpt) {
1769                     mDidDexOpt = false;
1770                     Message nmsg = mHandler.obtainMessage(SERVICE_TIMEOUT_MSG);
1771                     nmsg.obj = msg.obj;
1772                     mHandler.sendMessageDelayed(nmsg, ActiveServices.SERVICE_TIMEOUT);
1773                     return;
1774                 }
1775                 mServices.serviceTimeout((ProcessRecord)msg.obj);
1776             } break;
1777             case UPDATE_TIME_ZONE: {
1778                 synchronized (ActivityManagerService.this) {
1779                     for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) {
1780                         ProcessRecord r = mLruProcesses.get(i);
1781                         if (r.thread != null) {
1782                             try {
1783                                 r.thread.updateTimeZone();
1784                             } catch (RemoteException ex) {
1785                                 Slog.w(TAG, "Failed to update time zone for: " + r.info.processName);
1786                             }
1787                         }
1788                     }
1789                 }
1790             } break;
1791             case CLEAR_DNS_CACHE_MSG: {
1792                 synchronized (ActivityManagerService.this) {
1793                     for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) {
1794                         ProcessRecord r = mLruProcesses.get(i);
1795                         if (r.thread != null) {
1796                             try {
1797                                 r.thread.clearDnsCache();
1798                             } catch (RemoteException ex) {
1799                                 Slog.w(TAG, "Failed to clear dns cache for: " + r.info.processName);
1800                             }
1801                         }
1802                     }
1803                 }
1804             } break;
1805             case UPDATE_HTTP_PROXY_MSG: {
1806                 ProxyInfo proxy = (ProxyInfo)msg.obj;
1807                 String host = "";
1808                 String port = "";
1809                 String exclList = "";
1810                 Uri pacFileUrl = Uri.EMPTY;
1811                 if (proxy != null) {
1812                     host = proxy.getHost();
1813                     port = Integer.toString(proxy.getPort());
1814                     exclList = proxy.getExclusionListAsString();
1815                     pacFileUrl = proxy.getPacFileUrl();
1816                 }
1817                 synchronized (ActivityManagerService.this) {
1818                     for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) {
1819                         ProcessRecord r = mLruProcesses.get(i);
1820                         if (r.thread != null) {
1821                             try {
1822                                 r.thread.setHttpProxy(host, port, exclList, pacFileUrl);
1823                             } catch (RemoteException ex) {
1824                                 Slog.w(TAG, "Failed to update http proxy for: " +
1825                                         r.info.processName);
1826                             }
1827                         }
1828                     }
1829                 }
1830             } break;
1831             case PROC_START_TIMEOUT_MSG: {
1832                 if (mDidDexOpt) {
1833                     mDidDexOpt = false;
1834                     Message nmsg = mHandler.obtainMessage(PROC_START_TIMEOUT_MSG);
1835                     nmsg.obj = msg.obj;
1836                     mHandler.sendMessageDelayed(nmsg, PROC_START_TIMEOUT);
1837                     return;
1838                 }
1839                 ProcessRecord app = (ProcessRecord)msg.obj;
1840                 synchronized (ActivityManagerService.this) {
1841                     processStartTimedOutLocked(app);
1842                 }
1843             } break;
1844             case CONTENT_PROVIDER_PUBLISH_TIMEOUT_MSG: {
1845                 ProcessRecord app = (ProcessRecord)msg.obj;
1846                 synchronized (ActivityManagerService.this) {
1847                     processContentProviderPublishTimedOutLocked(app);
1848                 }
1849             } break;
1850             case DO_PENDING_ACTIVITY_LAUNCHES_MSG: {
1851                 synchronized (ActivityManagerService.this) {
1852                     mActivityStarter.doPendingActivityLaunchesLocked(true);
1853                 }
1854             } break;
1855             case KILL_APPLICATION_MSG: {
1856                 synchronized (ActivityManagerService.this) {
1857                     final int appId = msg.arg1;
1858                     final int userId = msg.arg2;
1859                     Bundle bundle = (Bundle)msg.obj;
1860                     String pkg = bundle.getString("pkg");
1861                     String reason = bundle.getString("reason");
1862                     forceStopPackageLocked(pkg, appId, false, false, true, false,
1863                             false, userId, reason);
1864                 }
1865             } break;
1866             case FINALIZE_PENDING_INTENT_MSG: {
1867                 ((PendingIntentRecord)msg.obj).completeFinalize();
1868             } break;
1869             case POST_HEAVY_NOTIFICATION_MSG: {
1870                 INotificationManager inm = NotificationManager.getService();
1871                 if (inm == null) {
1872                     return;
1873                 }
1874
1875                 ActivityRecord root = (ActivityRecord)msg.obj;
1876                 ProcessRecord process = root.app;
1877                 if (process == null) {
1878                     return;
1879                 }
1880
1881                 try {
1882                     Context context = mContext.createPackageContext(process.info.packageName, 0);
1883                     String text = mContext.getString(R.string.heavy_weight_notification,
1884                             context.getApplicationInfo().loadLabel(context.getPackageManager()));
1885                     Notification notification = new Notification.Builder(context)
1886                             .setSmallIcon(com.android.internal.R.drawable.stat_sys_adb)
1887                             .setWhen(0)
1888                             .setOngoing(true)
1889                             .setTicker(text)
1890                             .setColor(mContext.getColor(
1891                                     com.android.internal.R.color.system_notification_accent_color))
1892                             .setContentTitle(text)
1893                             .setContentText(
1894                                     mContext.getText(R.string.heavy_weight_notification_detail))
1895                             .setContentIntent(PendingIntent.getActivityAsUser(mContext, 0,
1896                                     root.intent, PendingIntent.FLAG_CANCEL_CURRENT, null,
1897                                     new UserHandle(root.userId)))
1898                             .build();
1899                     try {
1900                         int[] outId = new int[1];
1901                         inm.enqueueNotificationWithTag("android", "android", null,
1902                                 R.string.heavy_weight_notification,
1903                                 notification, outId, root.userId);
1904                     } catch (RuntimeException e) {
1905                         Slog.w(ActivityManagerService.TAG,
1906                                 "Error showing notification for heavy-weight app", e);
1907                     } catch (RemoteException e) {
1908                     }
1909                 } catch (NameNotFoundException e) {
1910                     Slog.w(TAG, "Unable to create context for heavy notification", e);
1911                 }
1912             } break;
1913             case CANCEL_HEAVY_NOTIFICATION_MSG: {
1914                 INotificationManager inm = NotificationManager.getService();
1915                 if (inm == null) {
1916                     return;
1917                 }
1918                 try {
1919                     inm.cancelNotificationWithTag("android", null,
1920                             R.string.heavy_weight_notification,  msg.arg1);
1921                 } catch (RuntimeException e) {
1922                     Slog.w(ActivityManagerService.TAG,
1923                             "Error canceling notification for service", e);
1924                 } catch (RemoteException e) {
1925                 }
1926             } break;
1927             case CHECK_EXCESSIVE_WAKE_LOCKS_MSG: {
1928                 synchronized (ActivityManagerService.this) {
1929                     checkExcessivePowerUsageLocked(true);
1930                     removeMessages(CHECK_EXCESSIVE_WAKE_LOCKS_MSG);
1931                     Message nmsg = obtainMessage(CHECK_EXCESSIVE_WAKE_LOCKS_MSG);
1932                     sendMessageDelayed(nmsg, POWER_CHECK_DELAY);
1933                 }
1934             } break;
1935             case REPORT_MEM_USAGE_MSG: {
1936                 final ArrayList<ProcessMemInfo> memInfos = (ArrayList<ProcessMemInfo>)msg.obj;
1937                 Thread thread = new Thread() {
1938                     @Override public void run() {
1939                         reportMemUsage(memInfos);
1940                     }
1941                 };
1942                 thread.start();
1943                 break;
1944             }
1945             case REPORT_USER_SWITCH_MSG: {
1946                 mUserController.dispatchUserSwitch((UserState) msg.obj, msg.arg1, msg.arg2);
1947                 break;
1948             }
1949             case CONTINUE_USER_SWITCH_MSG: {
1950                 mUserController.continueUserSwitch((UserState) msg.obj, msg.arg1, msg.arg2);
1951                 break;
1952             }
1953             case USER_SWITCH_TIMEOUT_MSG: {
1954                 mUserController.timeoutUserSwitch((UserState) msg.obj, msg.arg1, msg.arg2);
1955                 break;
1956             }
1957             case IMMERSIVE_MODE_LOCK_MSG: {
1958                 final boolean nextState = (msg.arg1 != 0);
1959                 if (mUpdateLock.isHeld() != nextState) {
1960                     if (DEBUG_IMMERSIVE) Slog.d(TAG_IMMERSIVE,
1961                             "Applying new update lock state '" + nextState
1962                             + "' for " + (ActivityRecord)msg.obj);
1963                     if (nextState) {
1964                         mUpdateLock.acquire();
1965                     } else {
1966                         mUpdateLock.release();
1967                     }
1968                 }
1969                 break;
1970             }
1971             case PERSIST_URI_GRANTS_MSG: {
1972                 writeGrantedUriPermissions();
1973                 break;
1974             }
1975             case REQUEST_ALL_PSS_MSG: {
1976                 synchronized (ActivityManagerService.this) {
1977                     requestPssAllProcsLocked(SystemClock.uptimeMillis(), true, false);
1978                 }
1979                 break;
1980             }
1981             case START_PROFILES_MSG: {
1982                 synchronized (ActivityManagerService.this) {
1983                     mUserController.startProfilesLocked();
1984                 }
1985                 break;
1986             }
1987             case UPDATE_TIME: {
1988                 synchronized (ActivityManagerService.this) {
1989                     for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) {
1990                         ProcessRecord r = mLruProcesses.get(i);
1991                         if (r.thread != null) {
1992                             try {
1993                                 r.thread.updateTimePrefs(msg.arg1 == 0 ? false : true);
1994                             } catch (RemoteException ex) {
1995                                 Slog.w(TAG, "Failed to update preferences for: " + r.info.processName);
1996                             }
1997                         }
1998                     }
1999                 }
2000                 break;
2001             }
2002             case SYSTEM_USER_START_MSG: {
2003                 mBatteryStatsService.noteEvent(BatteryStats.HistoryItem.EVENT_USER_RUNNING_START,
2004                         Integer.toString(msg.arg1), msg.arg1);
2005                 mSystemServiceManager.startUser(msg.arg1);
2006                 break;
2007             }
2008             case SYSTEM_USER_UNLOCK_MSG: {
2009                 final int userId = msg.arg1;
2010                 mSystemServiceManager.unlockUser(userId);
2011                 synchronized (ActivityManagerService.this) {
2012                     mRecentTasks.loadUserRecentsLocked(userId);
2013                 }
2014                 if (userId == UserHandle.USER_SYSTEM) {
2015                     startPersistentApps(PackageManager.MATCH_DIRECT_BOOT_UNAWARE);
2016                 }
2017                 installEncryptionUnawareProviders(userId);
2018                 mUserController.finishUserUnlocked((UserState) msg.obj);
2019                 break;
2020             }
2021             case SYSTEM_USER_CURRENT_MSG: {
2022                 mBatteryStatsService.noteEvent(
2023                         BatteryStats.HistoryItem.EVENT_USER_FOREGROUND_FINISH,
2024                         Integer.toString(msg.arg2), msg.arg2);
2025                 mBatteryStatsService.noteEvent(
2026                         BatteryStats.HistoryItem.EVENT_USER_FOREGROUND_START,
2027                         Integer.toString(msg.arg1), msg.arg1);
2028                 mSystemServiceManager.switchUser(msg.arg1);
2029                 break;
2030             }
2031             case ENTER_ANIMATION_COMPLETE_MSG: {
2032                 synchronized (ActivityManagerService.this) {
2033                     ActivityRecord r = ActivityRecord.forTokenLocked((IBinder) msg.obj);
2034                     if (r != null && r.app != null && r.app.thread != null) {
2035                         try {
2036                             r.app.thread.scheduleEnterAnimationComplete(r.appToken);
2037                         } catch (RemoteException e) {
2038                         }
2039                     }
2040                 }
2041                 break;
2042             }
2043             case FINISH_BOOTING_MSG: {
2044                 if (msg.arg1 != 0) {
2045                     Trace.traceBegin(Trace.TRACE_TAG_ACTIVITY_MANAGER, "FinishBooting");
2046                     finishBooting();
2047                     Trace.traceEnd(Trace.TRACE_TAG_ACTIVITY_MANAGER);
2048                 }
2049                 if (msg.arg2 != 0) {
2050                     enableScreenAfterBoot();
2051                 }
2052                 break;
2053             }
2054             case SEND_LOCALE_TO_MOUNT_DAEMON_MSG: {
2055                 try {
2056                     Locale l = (Locale) msg.obj;
2057                     IBinder service = ServiceManager.getService("mount");
2058                     IMountService mountService = IMountService.Stub.asInterface(service);
2059                     Log.d(TAG, "Storing locale " + l.toLanguageTag() + " for decryption UI");
2060                     mountService.setField(StorageManager.SYSTEM_LOCALE_KEY, l.toLanguageTag());
2061                 } catch (RemoteException e) {
2062                     Log.e(TAG, "Error storing locale for decryption UI", e);
2063                 }
2064                 break;
2065             }
2066             case NOTIFY_TASK_STACK_CHANGE_LISTENERS_MSG: {
2067                 synchronized (ActivityManagerService.this) {
2068                     for (int i = mTaskStackListeners.beginBroadcast() - 1; i >= 0; i--) {
2069                         try {
2070                             // Make a one-way callback to the listener
2071                             mTaskStackListeners.getBroadcastItem(i).onTaskStackChanged();
2072                         } catch (RemoteException e){
2073                             // Handled by the RemoteCallbackList
2074                         }
2075                     }
2076                     mTaskStackListeners.finishBroadcast();
2077                 }
2078                 break;
2079             }
2080             case NOTIFY_ACTIVITY_PINNED_LISTENERS_MSG: {
2081                 synchronized (ActivityManagerService.this) {
2082                     for (int i = mTaskStackListeners.beginBroadcast() - 1; i >= 0; i--) {
2083                         try {
2084                             // Make a one-way callback to the listener
2085                             mTaskStackListeners.getBroadcastItem(i).onActivityPinned();
2086                         } catch (RemoteException e){
2087                             // Handled by the RemoteCallbackList
2088                         }
2089                     }
2090                     mTaskStackListeners.finishBroadcast();
2091                 }
2092                 break;
2093             }
2094             case NOTIFY_PINNED_ACTIVITY_RESTART_ATTEMPT_LISTENERS_MSG: {
2095                 synchronized (ActivityManagerService.this) {
2096                     for (int i = mTaskStackListeners.beginBroadcast() - 1; i >= 0; i--) {
2097                         try {
2098                             // Make a one-way callback to the listener
2099                             mTaskStackListeners.getBroadcastItem(i).onPinnedActivityRestartAttempt();
2100                         } catch (RemoteException e){
2101                             // Handled by the RemoteCallbackList
2102                         }
2103                     }
2104                     mTaskStackListeners.finishBroadcast();
2105                 }
2106                 break;
2107             }
2108             case NOTIFY_PINNED_STACK_ANIMATION_ENDED_LISTENERS_MSG: {
2109                 synchronized (ActivityManagerService.this) {
2110                     for (int i = mTaskStackListeners.beginBroadcast() - 1; i >= 0; i--) {
2111                         try {
2112                             // Make a one-way callback to the listener
2113                             mTaskStackListeners.getBroadcastItem(i).onPinnedStackAnimationEnded();
2114                         } catch (RemoteException e){
2115                             // Handled by the RemoteCallbackList
2116                         }
2117                     }
2118                     mTaskStackListeners.finishBroadcast();
2119                 }
2120                 break;
2121             }
2122             case NOTIFY_FORCED_RESIZABLE_MSG: {
2123                 synchronized (ActivityManagerService.this) {
2124                     for (int i = mTaskStackListeners.beginBroadcast() - 1; i >= 0; i--) {
2125                         try {
2126                             // Make a one-way callback to the listener
2127                             mTaskStackListeners.getBroadcastItem(i).onActivityForcedResizable(
2128                                     (String) msg.obj, msg.arg1);
2129                         } catch (RemoteException e){
2130                             // Handled by the RemoteCallbackList
2131                         }
2132                     }
2133                     mTaskStackListeners.finishBroadcast();
2134                 }
2135                 break;
2136             }
2137                 case NOTIFY_ACTIVITY_DISMISSING_DOCKED_STACK_MSG: {
2138                     synchronized (ActivityManagerService.this) {
2139                         for (int i = mTaskStackListeners.beginBroadcast() - 1; i >= 0; i--) {
2140                             try {
2141                                 // Make a one-way callback to the listener
2142                                 mTaskStackListeners.getBroadcastItem(i)
2143                                         .onActivityDismissingDockedStack();
2144                             } catch (RemoteException e){
2145                                 // Handled by the RemoteCallbackList
2146                             }
2147                         }
2148                         mTaskStackListeners.finishBroadcast();
2149                     }
2150                     break;
2151                 }
2152             case NOTIFY_CLEARTEXT_NETWORK_MSG: {
2153                 final int uid = msg.arg1;
2154                 final byte[] firstPacket = (byte[]) msg.obj;
2155
2156                 synchronized (mPidsSelfLocked) {
2157                     for (int i = 0; i < mPidsSelfLocked.size(); i++) {
2158                         final ProcessRecord p = mPidsSelfLocked.valueAt(i);
2159                         if (p.uid == uid) {
2160                             try {
2161                                 p.thread.notifyCleartextNetwork(firstPacket);
2162                             } catch (RemoteException ignored) {
2163                             }
2164                         }
2165                     }
2166                 }
2167                 break;
2168             }
2169             case POST_DUMP_HEAP_NOTIFICATION_MSG: {
2170                 final String procName;
2171                 final int uid;
2172                 final long memLimit;
2173                 final String reportPackage;
2174                 synchronized (ActivityManagerService.this) {
2175                     procName = mMemWatchDumpProcName;
2176                     uid = mMemWatchDumpUid;
2177                     Pair<Long, String> val = mMemWatchProcesses.get(procName, uid);
2178                     if (val == null) {
2179                         val = mMemWatchProcesses.get(procName, 0);
2180                     }
2181                     if (val != null) {
2182                         memLimit = val.first;
2183                         reportPackage = val.second;
2184                     } else {
2185                         memLimit = 0;
2186                         reportPackage = null;
2187                     }
2188                 }
2189                 if (procName == null) {
2190                     return;
2191                 }
2192
2193                 if (DEBUG_PSS) Slog.d(TAG_PSS,
2194                         "Showing dump heap notification from " + procName + "/" + uid);
2195
2196                 INotificationManager inm = NotificationManager.getService();
2197                 if (inm == null) {
2198                     return;
2199                 }
2200
2201                 String text = mContext.getString(R.string.dump_heap_notification, procName);
2202
2203
2204                 Intent deleteIntent = new Intent();
2205                 deleteIntent.setAction(DumpHeapActivity.ACTION_DELETE_DUMPHEAP);
2206                 Intent intent = new Intent();
2207                 intent.setClassName("android", DumpHeapActivity.class.getName());
2208                 intent.putExtra(DumpHeapActivity.KEY_PROCESS, procName);
2209                 intent.putExtra(DumpHeapActivity.KEY_SIZE, memLimit);
2210                 if (reportPackage != null) {
2211                     intent.putExtra(DumpHeapActivity.KEY_DIRECT_LAUNCH, reportPackage);
2212                 }
2213                 int userId = UserHandle.getUserId(uid);
2214                 Notification notification = new Notification.Builder(mContext)
2215                         .setSmallIcon(com.android.internal.R.drawable.stat_sys_adb)
2216                         .setWhen(0)
2217                         .setOngoing(true)
2218                         .setAutoCancel(true)
2219                         .setTicker(text)
2220                         .setColor(mContext.getColor(
2221                                 com.android.internal.R.color.system_notification_accent_color))
2222                         .setContentTitle(text)
2223                         .setContentText(
2224                                 mContext.getText(R.string.dump_heap_notification_detail))
2225                         .setContentIntent(PendingIntent.getActivityAsUser(mContext, 0,
2226                                 intent, PendingIntent.FLAG_CANCEL_CURRENT, null,
2227                                 new UserHandle(userId)))
2228                         .setDeleteIntent(PendingIntent.getBroadcastAsUser(mContext, 0,
2229                                 deleteIntent, 0, UserHandle.SYSTEM))
2230                         .build();
2231
2232                 try {
2233                     int[] outId = new int[1];
2234                     inm.enqueueNotificationWithTag("android", "android", null,
2235                             R.string.dump_heap_notification,
2236                             notification, outId, userId);
2237                 } catch (RuntimeException e) {
2238                     Slog.w(ActivityManagerService.TAG,
2239                             "Error showing notification for dump heap", e);
2240                 } catch (RemoteException e) {
2241                 }
2242             } break;
2243             case DELETE_DUMPHEAP_MSG: {
2244                 revokeUriPermission(ActivityThread.currentActivityThread().getApplicationThread(),
2245                         DumpHeapActivity.JAVA_URI,
2246                         Intent.FLAG_GRANT_READ_URI_PERMISSION
2247                                 | Intent.FLAG_GRANT_WRITE_URI_PERMISSION,
2248                         UserHandle.myUserId());
2249                 synchronized (ActivityManagerService.this) {
2250                     mMemWatchDumpFile = null;
2251                     mMemWatchDumpProcName = null;
2252                     mMemWatchDumpPid = -1;
2253                     mMemWatchDumpUid = -1;
2254                 }
2255             } break;
2256             case FOREGROUND_PROFILE_CHANGED_MSG: {
2257                 mUserController.dispatchForegroundProfileChanged(msg.arg1);
2258             } break;
2259             case REPORT_TIME_TRACKER_MSG: {
2260                 AppTimeTracker tracker = (AppTimeTracker)msg.obj;
2261                 tracker.deliverResult(mContext);
2262             } break;
2263             case REPORT_USER_SWITCH_COMPLETE_MSG: {
2264                 mUserController.dispatchUserSwitchComplete(msg.arg1);
2265             } break;
2266             case SHUTDOWN_UI_AUTOMATION_CONNECTION_MSG: {
2267                 IUiAutomationConnection connection = (IUiAutomationConnection) msg.obj;
2268                 try {
2269                     connection.shutdown();
2270                 } catch (RemoteException e) {
2271                     Slog.w(TAG, "Error shutting down UiAutomationConnection");
2272                 }
2273                 // Only a UiAutomation can set this flag and now that
2274                 // it is finished we make sure it is reset to its default.
2275                 mUserIsMonkey = false;
2276             } break;
2277             case APP_BOOST_DEACTIVATE_MSG: {
2278                 synchronized(ActivityManagerService.this) {
2279                     if (mIsBoosted) {
2280                         if (mBoostStartTime < (SystemClock.uptimeMillis() - APP_BOOST_TIMEOUT)) {
2281                             nativeMigrateFromBoost();
2282                             mIsBoosted = false;
2283                             mBoostStartTime = 0;
2284                         } else {
2285                             Message newmsg = mHandler.obtainMessage(APP_BOOST_DEACTIVATE_MSG);
2286                             mHandler.sendMessageDelayed(newmsg, APP_BOOST_TIMEOUT);
2287                         }
2288                     }
2289                 }
2290             } break;
2291             case IDLE_UIDS_MSG: {
2292                 idleUids();
2293             } break;
2294             case LOG_STACK_STATE: {
2295                 synchronized (ActivityManagerService.this) {
2296                     mStackSupervisor.logStackState();
2297                 }
2298             } break;
2299             case VR_MODE_CHANGE_MSG: {
2300                 VrManagerInternal vrService = LocalServices.getService(VrManagerInternal.class);
2301                 final ActivityRecord r = (ActivityRecord) msg.obj;
2302                 boolean vrMode;
2303                 ComponentName requestedPackage;
2304                 ComponentName callingPackage;
2305                 int userId;
2306                 synchronized (ActivityManagerService.this) {
2307                     vrMode = r.requestedVrComponent != null;
2308                     requestedPackage = r.requestedVrComponent;
2309                     userId = r.userId;
2310                     callingPackage = r.info.getComponentName();
2311                     if (mInVrMode != vrMode) {
2312                         mInVrMode = vrMode;
2313                         mShowDialogs = shouldShowDialogs(mConfiguration, mInVrMode);
2314                     }
2315                 }
2316                 vrService.setVrMode(vrMode, requestedPackage, userId, callingPackage);
2317             } break;
2318             case VR_MODE_APPLY_IF_NEEDED_MSG: {
2319                 final ActivityRecord r = (ActivityRecord) msg.obj;
2320                 final boolean needsVrMode = r != null && r.requestedVrComponent != null;
2321                 if (needsVrMode) {
2322                     applyVrMode(msg.arg1 == 1, r.requestedVrComponent, r.userId,
2323                             r.info.getComponentName(), false);
2324                 }
2325             } break;
2326             }
2327         }
2328     };
2329
2330     static final int COLLECT_PSS_BG_MSG = 1;
2331
2332     final Handler mBgHandler = new Handler(BackgroundThread.getHandler().getLooper()) {
2333         @Override
2334         public void handleMessage(Message msg) {
2335             switch (msg.what) {
2336             case COLLECT_PSS_BG_MSG: {
2337                 long start = SystemClock.uptimeMillis();
2338                 MemInfoReader memInfo = null;
2339                 synchronized (ActivityManagerService.this) {
2340                     if (mFullPssPending) {
2341                         mFullPssPending = false;
2342                         memInfo = new MemInfoReader();
2343                     }
2344                 }
2345                 if (memInfo != null) {
2346                     updateCpuStatsNow();
2347                     long nativeTotalPss = 0;
2348                     synchronized (mProcessCpuTracker) {
2349                         final int N = mProcessCpuTracker.countStats();
2350                         for (int j=0; j<N; j++) {
2351                             ProcessCpuTracker.Stats st = mProcessCpuTracker.getStats(j);
2352                             if (st.vsize <= 0 || st.uid >= Process.FIRST_APPLICATION_UID) {
2353                                 // This is definitely an application process; skip it.
2354                                 continue;
2355                             }
2356                             synchronized (mPidsSelfLocked) {
2357                                 if (mPidsSelfLocked.indexOfKey(st.pid) >= 0) {
2358                                     // This is one of our own processes; skip it.
2359                                     continue;
2360                                 }
2361                             }
2362                             nativeTotalPss += Debug.getPss(st.pid, null, null);
2363                         }
2364                     }
2365                     memInfo.readMemInfo();
2366                     synchronized (ActivityManagerService.this) {
2367                         if (DEBUG_PSS) Slog.d(TAG_PSS, "Collected native and kernel memory in "
2368                                 + (SystemClock.uptimeMillis()-start) + "ms");
2369                         final long cachedKb = memInfo.getCachedSizeKb();
2370                         final long freeKb = memInfo.getFreeSizeKb();
2371                         final long zramKb = memInfo.getZramTotalSizeKb();
2372                         final long kernelKb = memInfo.getKernelUsedSizeKb();
2373                         EventLogTags.writeAmMeminfo(cachedKb*1024, freeKb*1024, zramKb*1024,
2374                                 kernelKb*1024, nativeTotalPss*1024);
2375                         mProcessStats.addSysMemUsageLocked(cachedKb, freeKb, zramKb, kernelKb,
2376                                 nativeTotalPss);
2377                     }
2378                 }
2379
2380                 int num = 0;
2381                 long[] tmp = new long[2];
2382                 do {
2383                     ProcessRecord proc;
2384                     int procState;
2385                     int pid;
2386                     long lastPssTime;
2387                     synchronized (ActivityManagerService.this) {
2388                         if (mPendingPssProcesses.size() <= 0) {
2389                             if (mTestPssMode || DEBUG_PSS) Slog.d(TAG_PSS,
2390                                     "Collected PSS of " + num + " processes in "
2391                                     + (SystemClock.uptimeMillis() - start) + "ms");
2392                             mPendingPssProcesses.clear();
2393                             return;
2394                         }
2395                         proc = mPendingPssProcesses.remove(0);
2396                         procState = proc.pssProcState;
2397                         lastPssTime = proc.lastPssTime;
2398                         if (proc.thread != null && procState == proc.setProcState
2399                                 && (lastPssTime+ProcessList.PSS_SAFE_TIME_FROM_STATE_CHANGE)
2400                                         < SystemClock.uptimeMillis()) {
2401                             pid = proc.pid;
2402                         } else {
2403                             proc = null;
2404                             pid = 0;
2405                         }
2406                     }
2407                     if (proc != null) {
2408                         long pss = Debug.getPss(pid, tmp, null);
2409                         synchronized (ActivityManagerService.this) {
2410                             if (pss != 0 && proc.thread != null && proc.setProcState == procState
2411                                     && proc.pid == pid && proc.lastPssTime == lastPssTime) {
2412                                 num++;
2413                                 recordPssSampleLocked(proc, procState, pss, tmp[0], tmp[1],
2414                                         SystemClock.uptimeMillis());
2415                             }
2416                         }
2417                     }
2418                 } while (true);
2419             }
2420             }
2421         }
2422     };
2423
2424     public void setSystemProcess() {
2425         try {
2426             ServiceManager.addService(Context.ACTIVITY_SERVICE, this, true);
2427             ServiceManager.addService(ProcessStats.SERVICE_NAME, mProcessStats);
2428             ServiceManager.addService("meminfo", new MemBinder(this));
2429             ServiceManager.addService("gfxinfo", new GraphicsBinder(this));
2430             ServiceManager.addService("dbinfo", new DbBinder(this));
2431             if (MONITOR_CPU_USAGE) {
2432                 ServiceManager.addService("cpuinfo", new CpuBinder(this));
2433             }
2434             ServiceManager.addService("permission", new PermissionController(this));
2435             ServiceManager.addService("processinfo", new ProcessInfoService(this));
2436
2437             ApplicationInfo info = mContext.getPackageManager().getApplicationInfo(
2438                     "android", STOCK_PM_FLAGS | MATCH_SYSTEM_ONLY);
2439             mSystemThread.installSystemApplicationInfo(info, getClass().getClassLoader());
2440
2441             synchronized (this) {
2442                 ProcessRecord app = newProcessRecordLocked(info, info.processName, false, 0);
2443                 app.persistent = true;
2444                 app.pid = MY_PID;
2445                 app.maxAdj = ProcessList.SYSTEM_ADJ;
2446                 app.makeActive(mSystemThread.getApplicationThread(), mProcessStats);
2447                 synchronized (mPidsSelfLocked) {
2448                     mPidsSelfLocked.put(app.pid, app);
2449                 }
2450                 updateLruProcessLocked(app, false, null);
2451                 updateOomAdjLocked();
2452             }
2453         } catch (PackageManager.NameNotFoundException e) {
2454             throw new RuntimeException(
2455                     "Unable to find android system package", e);
2456         }
2457     }
2458
2459     public void setWindowManager(WindowManagerService wm) {
2460         mWindowManager = wm;
2461         mStackSupervisor.setWindowManager(wm);
2462         mActivityStarter.setWindowManager(wm);
2463     }
2464
2465     public void setUsageStatsManager(UsageStatsManagerInternal usageStatsManager) {
2466         mUsageStatsService = usageStatsManager;
2467     }
2468
2469     public void startObservingNativeCrashes() {
2470         final NativeCrashListener ncl = new NativeCrashListener(this);
2471         ncl.start();
2472     }
2473
2474     public IAppOpsService getAppOpsService() {
2475         return mAppOpsService;
2476     }
2477
2478     static class MemBinder extends Binder {
2479         ActivityManagerService mActivityManagerService;
2480         MemBinder(ActivityManagerService activityManagerService) {
2481             mActivityManagerService = activityManagerService;
2482         }
2483
2484         @Override
2485         protected void dump(FileDescriptor fd, PrintWriter pw, String[] args) {
2486             if (mActivityManagerService.checkCallingPermission(android.Manifest.permission.DUMP)
2487                     != PackageManager.PERMISSION_GRANTED) {
2488                 pw.println("Permission Denial: can't dump meminfo from from pid="
2489                         + Binder.getCallingPid() + ", uid=" + Binder.getCallingUid()
2490                         + " without permission " + android.Manifest.permission.DUMP);
2491                 return;
2492             }
2493
2494             mActivityManagerService.dumpApplicationMemoryUsage(fd, pw, "  ", args, false, null);
2495         }
2496     }
2497
2498     static class GraphicsBinder extends Binder {
2499         ActivityManagerService mActivityManagerService;
2500         GraphicsBinder(ActivityManagerService activityManagerService) {
2501             mActivityManagerService = activityManagerService;
2502         }
2503
2504         @Override
2505         protected void dump(FileDescriptor fd, PrintWriter pw, String[] args) {
2506             if (mActivityManagerService.checkCallingPermission(android.Manifest.permission.DUMP)
2507                     != PackageManager.PERMISSION_GRANTED) {
2508                 pw.println("Permission Denial: can't dump gfxinfo from from pid="
2509                         + Binder.getCallingPid() + ", uid=" + Binder.getCallingUid()
2510                         + " without permission " + android.Manifest.permission.DUMP);
2511                 return;
2512             }
2513
2514             mActivityManagerService.dumpGraphicsHardwareUsage(fd, pw, args);
2515         }
2516     }
2517
2518     static class DbBinder extends Binder {
2519         ActivityManagerService mActivityManagerService;
2520         DbBinder(ActivityManagerService activityManagerService) {
2521             mActivityManagerService = activityManagerService;
2522         }
2523
2524         @Override
2525         protected void dump(FileDescriptor fd, PrintWriter pw, String[] args) {
2526             if (mActivityManagerService.checkCallingPermission(android.Manifest.permission.DUMP)
2527                     != PackageManager.PERMISSION_GRANTED) {
2528                 pw.println("Permission Denial: can't dump dbinfo from from pid="
2529                         + Binder.getCallingPid() + ", uid=" + Binder.getCallingUid()
2530                         + " without permission " + android.Manifest.permission.DUMP);
2531                 return;
2532             }
2533
2534             mActivityManagerService.dumpDbInfo(fd, pw, args);
2535         }
2536     }
2537
2538     static class CpuBinder extends Binder {
2539         ActivityManagerService mActivityManagerService;
2540         CpuBinder(ActivityManagerService activityManagerService) {
2541             mActivityManagerService = activityManagerService;
2542         }
2543
2544         @Override
2545         protected void dump(FileDescriptor fd, PrintWriter pw, String[] args) {
2546             if (mActivityManagerService.checkCallingPermission(android.Manifest.permission.DUMP)
2547                     != PackageManager.PERMISSION_GRANTED) {
2548                 pw.println("Permission Denial: can't dump cpuinfo from from pid="
2549                         + Binder.getCallingPid() + ", uid=" + Binder.getCallingUid()
2550                         + " without permission " + android.Manifest.permission.DUMP);
2551                 return;
2552             }
2553
2554             synchronized (mActivityManagerService.mProcessCpuTracker) {
2555                 pw.print(mActivityManagerService.mProcessCpuTracker.printCurrentLoad());
2556                 pw.print(mActivityManagerService.mProcessCpuTracker.printCurrentState(
2557                         SystemClock.uptimeMillis()));
2558             }
2559         }
2560     }
2561
2562     public static final class Lifecycle extends SystemService {
2563         private final ActivityManagerService mService;
2564
2565         public Lifecycle(Context context) {
2566             super(context);
2567             mService = new ActivityManagerService(context);
2568         }
2569
2570         @Override
2571         public void onStart() {
2572             mService.start();
2573         }
2574
2575         public ActivityManagerService getService() {
2576             return mService;
2577         }
2578     }
2579
2580     // Note: This method is invoked on the main thread but may need to attach various
2581     // handlers to other threads.  So take care to be explicit about the looper.
2582     public ActivityManagerService(Context systemContext) {
2583         mContext = systemContext;
2584         mFactoryTest = FactoryTest.getMode();
2585         mSystemThread = ActivityThread.currentActivityThread();
2586
2587         Slog.i(TAG, "Memory class: " + ActivityManager.staticGetMemoryClass());
2588
2589         mHandlerThread = new ServiceThread(TAG,
2590                 android.os.Process.THREAD_PRIORITY_FOREGROUND, false /*allowIo*/);
2591         mHandlerThread.start();
2592         mHandler = new MainHandler(mHandlerThread.getLooper());
2593         mUiHandler = new UiHandler();
2594
2595         /* static; one-time init here */
2596         if (sKillHandler == null) {
2597             sKillThread = new ServiceThread(TAG + ":kill",
2598                     android.os.Process.THREAD_PRIORITY_BACKGROUND, true /* allowIo */);
2599             sKillThread.start();
2600             sKillHandler = new KillHandler(sKillThread.getLooper());
2601         }
2602
2603         mFgBroadcastQueue = new BroadcastQueue(this, mHandler,
2604                 "foreground", BROADCAST_FG_TIMEOUT, false);
2605         mBgBroadcastQueue = new BroadcastQueue(this, mHandler,
2606                 "background", BROADCAST_BG_TIMEOUT, true);
2607         mBroadcastQueues[0] = mFgBroadcastQueue;
2608         mBroadcastQueues[1] = mBgBroadcastQueue;
2609
2610         mServices = new ActiveServices(this);
2611         mProviderMap = new ProviderMap(this);
2612         mAppErrors = new AppErrors(mContext, this);
2613
2614         // TODO: Move creation of battery stats service outside of activity manager service.
2615         File dataDir = Environment.getDataDirectory();
2616         File systemDir = new File(dataDir, "system");
2617         systemDir.mkdirs();
2618         mBatteryStatsService = new BatteryStatsService(systemDir, mHandler);
2619         mBatteryStatsService.getActiveStatistics().readLocked();
2620         mBatteryStatsService.scheduleWriteToDisk();
2621         mOnBattery = DEBUG_POWER ? true
2622                 : mBatteryStatsService.getActiveStatistics().getIsOnBattery();
2623         mBatteryStatsService.getActiveStatistics().setCallback(this);
2624
2625         mProcessStats = new ProcessStatsService(this, new File(systemDir, "procstats"));
2626
2627         mAppOpsService = new AppOpsService(new File(systemDir, "appops.xml"), mHandler);
2628         mAppOpsService.startWatchingMode(AppOpsManager.OP_RUN_IN_BACKGROUND, null,
2629                 new IAppOpsCallback.Stub() {
2630                     @Override public void opChanged(int op, int uid, String packageName) {
2631                         if (op == AppOpsManager.OP_RUN_IN_BACKGROUND && packageName != null) {
2632                             if (mAppOpsService.checkOperation(op, uid, packageName)
2633                                     != AppOpsManager.MODE_ALLOWED) {
2634                                 runInBackgroundDisabled(uid);
2635                             }
2636                         }
2637                     }
2638                 });
2639
2640         mGrantFile = new AtomicFile(new File(systemDir, "urigrants.xml"));
2641
2642         mUserController = new UserController(this);
2643
2644         GL_ES_VERSION = SystemProperties.getInt("ro.opengles.version",
2645             ConfigurationInfo.GL_ES_VERSION_UNDEFINED);
2646
2647         mTrackingAssociations = "1".equals(SystemProperties.get("debug.track-associations"));
2648
2649         mConfiguration.setToDefaults();
2650         mConfiguration.setLocales(LocaleList.getDefault());
2651
2652         mConfigurationSeq = mConfiguration.seq = 1;
2653         mProcessCpuTracker.init();
2654
2655         mCompatModePackages = new CompatModePackages(this, systemDir, mHandler);
2656         mIntentFirewall = new IntentFirewall(new IntentFirewallInterface(), mHandler);
2657         mStackSupervisor = new ActivityStackSupervisor(this);
2658         mActivityStarter = new ActivityStarter(this, mStackSupervisor);
2659         mRecentTasks = new RecentTasks(this, mStackSupervisor);
2660
2661         mProcessCpuThread = new Thread("CpuTracker") {
2662             @Override
2663             public void run() {
2664                 while (true) {
2665                     try {
2666                         try {
2667                             synchronized(this) {
2668                                 final long now = SystemClock.uptimeMillis();
2669                                 long nextCpuDelay = (mLastCpuTime.get()+MONITOR_CPU_MAX_TIME)-now;
2670                                 long nextWriteDelay = (mLastWriteTime+BATTERY_STATS_TIME)-now;
2671                                 //Slog.i(TAG, "Cpu delay=" + nextCpuDelay
2672                                 //        + ", write delay=" + nextWriteDelay);
2673                                 if (nextWriteDelay < nextCpuDelay) {
2674                                     nextCpuDelay = nextWriteDelay;
2675                                 }
2676                                 if (nextCpuDelay > 0) {
2677                                     mProcessCpuMutexFree.set(true);
2678                                     this.wait(nextCpuDelay);
2679                                 }
2680                             }
2681                         } catch (InterruptedException e) {
2682                         }
2683                         updateCpuStatsNow();
2684                     } catch (Exception e) {
2685                         Slog.e(TAG, "Unexpected exception collecting process stats", e);
2686                     }
2687                 }
2688             }
2689         };
2690
2691         Watchdog.getInstance().addMonitor(this);
2692         Watchdog.getInstance().addThread(mHandler);
2693     }
2694
2695     public void setSystemServiceManager(SystemServiceManager mgr) {
2696         mSystemServiceManager = mgr;
2697     }
2698
2699     public void setInstaller(Installer installer) {
2700         mInstaller = installer;
2701     }
2702
2703     private void start() {
2704         Process.removeAllProcessGroups();
2705         mProcessCpuThread.start();
2706
2707         mBatteryStatsService.publish(mContext);
2708         mAppOpsService.publish(mContext);
2709         Slog.d("AppOps", "AppOpsService published");
2710         LocalServices.addService(ActivityManagerInternal.class, new LocalService());
2711     }
2712
2713     void onUserStoppedLocked(int userId) {
2714         mRecentTasks.unloadUserDataFromMemoryLocked(userId);
2715     }
2716
2717     public void initPowerManagement() {
2718         mStackSupervisor.initPowerManagement();
2719         mBatteryStatsService.initPowerManagement();
2720         mLocalPowerManager = LocalServices.getService(PowerManagerInternal.class);
2721         PowerManager pm = (PowerManager)mContext.getSystemService(Context.POWER_SERVICE);
2722         mVoiceWakeLock = pm.newWakeLock(PowerManager.PARTIAL_WAKE_LOCK, "*voice*");
2723         mVoiceWakeLock.setReferenceCounted(false);
2724     }
2725
2726     @Override
2727     public boolean onTransact(int code, Parcel data, Parcel reply, int flags)
2728             throws RemoteException {
2729         if (code == SYSPROPS_TRANSACTION) {
2730             // We need to tell all apps about the system property change.
2731             ArrayList<IBinder> procs = new ArrayList<IBinder>();
2732             synchronized(this) {
2733                 final int NP = mProcessNames.getMap().size();
2734                 for (int ip=0; ip<NP; ip++) {
2735                     SparseArray<ProcessRecord> apps = mProcessNames.getMap().valueAt(ip);
2736                     final int NA = apps.size();
2737                     for (int ia=0; ia<NA; ia++) {
2738                         ProcessRecord app = apps.valueAt(ia);
2739                         if (app.thread != null) {
2740                             procs.add(app.thread.asBinder());
2741                         }
2742                     }
2743                 }
2744             }
2745
2746             int N = procs.size();
2747             for (int i=0; i<N; i++) {
2748                 Parcel data2 = Parcel.obtain();
2749                 try {
2750                     procs.get(i).transact(IBinder.SYSPROPS_TRANSACTION, data2, null, 0);
2751                 } catch (RemoteException e) {
2752                 }
2753                 data2.recycle();
2754             }
2755         }
2756         try {
2757             return super.onTransact(code, data, reply, flags);
2758         } catch (RuntimeException e) {
2759             // The activity manager only throws security exceptions, so let's
2760             // log all others.
2761             if (!(e instanceof SecurityException)) {
2762                 Slog.wtf(TAG, "Activity Manager Crash", e);
2763             }
2764             throw e;
2765         }
2766     }
2767
2768     void updateCpuStats() {
2769         final long now = SystemClock.uptimeMillis();
2770         if (mLastCpuTime.get() >= now - MONITOR_CPU_MIN_TIME) {
2771             return;
2772         }
2773         if (mProcessCpuMutexFree.compareAndSet(true, false)) {
2774             synchronized (mProcessCpuThread) {
2775                 mProcessCpuThread.notify();
2776             }
2777         }
2778     }
2779
2780     void updateCpuStatsNow() {
2781         synchronized (mProcessCpuTracker) {
2782             mProcessCpuMutexFree.set(false);
2783             final long now = SystemClock.uptimeMillis();
2784             boolean haveNewCpuStats = false;
2785
2786             if (MONITOR_CPU_USAGE &&
2787                     mLastCpuTime.get() < (now-MONITOR_CPU_MIN_TIME)) {
2788                 mLastCpuTime.set(now);
2789                 mProcessCpuTracker.update();
2790                 if (mProcessCpuTracker.hasGoodLastStats()) {
2791                     haveNewCpuStats = true;
2792                     //Slog.i(TAG, mProcessCpu.printCurrentState());
2793                     //Slog.i(TAG, "Total CPU usage: "
2794                     //        + mProcessCpu.getTotalCpuPercent() + "%");
2795
2796                     // Slog the cpu usage if the property is set.
2797                     if ("true".equals(SystemProperties.get("events.cpu"))) {
2798                         int user = mProcessCpuTracker.getLastUserTime();
2799                         int system = mProcessCpuTracker.getLastSystemTime();
2800                         int iowait = mProcessCpuTracker.getLastIoWaitTime();
2801                         int irq = mProcessCpuTracker.getLastIrqTime();
2802                         int softIrq = mProcessCpuTracker.getLastSoftIrqTime();
2803                         int idle = mProcessCpuTracker.getLastIdleTime();
2804
2805                         int total = user + system + iowait + irq + softIrq + idle;
2806                         if (total == 0) total = 1;
2807
2808                         EventLog.writeEvent(EventLogTags.CPU,
2809                                 ((user+system+iowait+irq+softIrq) * 100) / total,
2810                                 (user * 100) / total,
2811                                 (system * 100) / total,
2812                                 (iowait * 100) / total,
2813                                 (irq * 100) / total,
2814                                 (softIrq * 100) / total);
2815                     }
2816                 }
2817             }
2818
2819             final BatteryStatsImpl bstats = mBatteryStatsService.getActiveStatistics();
2820             synchronized(bstats) {
2821                 synchronized(mPidsSelfLocked) {
2822                     if (haveNewCpuStats) {
2823                         if (bstats.startAddingCpuLocked()) {
2824                             int totalUTime = 0;
2825                             int totalSTime = 0;
2826                             final int N = mProcessCpuTracker.countStats();
2827                             for (int i=0; i<N; i++) {
2828                                 ProcessCpuTracker.Stats st = mProcessCpuTracker.getStats(i);
2829                                 if (!st.working) {
2830                                     continue;
2831                                 }
2832                                 ProcessRecord pr = mPidsSelfLocked.get(st.pid);
2833                                 totalUTime += st.rel_utime;
2834                                 totalSTime += st.rel_stime;
2835                                 if (pr != null) {
2836                                     BatteryStatsImpl.Uid.Proc ps = pr.curProcBatteryStats;
2837                                     if (ps == null || !ps.isActive()) {
2838                                         pr.curProcBatteryStats = ps = bstats.getProcessStatsLocked(
2839                                                 pr.info.uid, pr.processName);
2840                                     }
2841                                     ps.addCpuTimeLocked(st.rel_utime, st.rel_stime);
2842                                     pr.curCpuTime += st.rel_utime + st.rel_stime;
2843                                 } else {
2844                                     BatteryStatsImpl.Uid.Proc ps = st.batteryStats;
2845                                     if (ps == null || !ps.isActive()) {
2846                                         st.batteryStats = ps = bstats.getProcessStatsLocked(
2847                                                 bstats.mapUid(st.uid), st.name);
2848                                     }
2849                                     ps.addCpuTimeLocked(st.rel_utime, st.rel_stime);
2850                                 }
2851                             }
2852                             final int userTime = mProcessCpuTracker.getLastUserTime();
2853                             final int systemTime = mProcessCpuTracker.getLastSystemTime();
2854                             final int iowaitTime = mProcessCpuTracker.getLastIoWaitTime();
2855                             final int irqTime = mProcessCpuTracker.getLastIrqTime();
2856                             final int softIrqTime = mProcessCpuTracker.getLastSoftIrqTime();
2857                             final int idleTime = mProcessCpuTracker.getLastIdleTime();
2858                             bstats.finishAddingCpuLocked(totalUTime, totalSTime, userTime,
2859                                     systemTime, iowaitTime, irqTime, softIrqTime, idleTime);
2860                         }
2861                     }
2862                 }
2863
2864                 if (mLastWriteTime < (now-BATTERY_STATS_TIME)) {
2865                     mLastWriteTime = now;
2866                     mBatteryStatsService.scheduleWriteToDisk();
2867                 }
2868             }
2869         }
2870     }
2871
2872     @Override
2873     public void batteryNeedsCpuUpdate() {
2874         updateCpuStatsNow();
2875     }
2876
2877     @Override
2878     public void batteryPowerChanged(boolean onBattery) {
2879         // When plugging in, update the CPU stats first before changing
2880         // the plug state.
2881         updateCpuStatsNow();
2882         synchronized (this) {
2883             synchronized(mPidsSelfLocked) {
2884                 mOnBattery = DEBUG_POWER ? true : onBattery;
2885             }
2886         }
2887     }
2888
2889     @Override
2890     public void batterySendBroadcast(Intent intent) {
2891         broadcastIntentLocked(null, null, intent, null, null, 0, null, null, null,
2892                 AppOpsManager.OP_NONE, null, false, false,
2893                 -1, Process.SYSTEM_UID, UserHandle.USER_ALL);
2894     }
2895
2896     /**
2897      * Initialize the application bind args. These are passed to each
2898      * process when the bindApplication() IPC is sent to the process. They're
2899      * lazily setup to make sure the services are running when they're asked for.
2900      */
2901     private HashMap<String, IBinder> getCommonServicesLocked(boolean isolated) {
2902         // Isolated processes won't get this optimization, so that we don't
2903         // violate the rules about which services they have access to.
2904         if (isolated) {
2905             if (mIsolatedAppBindArgs == null) {
2906                 mIsolatedAppBindArgs = new HashMap<>();
2907                 mIsolatedAppBindArgs.put("package", ServiceManager.getService("package"));
2908             }
2909             return mIsolatedAppBindArgs;
2910         }
2911
2912         if (mAppBindArgs == null) {
2913             mAppBindArgs = new HashMap<>();
2914
2915             // Setup the application init args
2916             mAppBindArgs.put("package", ServiceManager.getService("package"));
2917             mAppBindArgs.put("window", ServiceManager.getService("window"));
2918             mAppBindArgs.put(Context.ALARM_SERVICE,
2919                     ServiceManager.getService(Context.ALARM_SERVICE));
2920         }
2921         return mAppBindArgs;
2922     }
2923
2924     boolean setFocusedActivityLocked(ActivityRecord r, String reason) {
2925         if (r == null || mFocusedActivity == r) {
2926             return false;
2927         }
2928
2929         if (!r.isFocusable()) {
2930             if (DEBUG_FOCUS) Slog.d(TAG_FOCUS, "setFocusedActivityLocked: unfocusable r=" + r);
2931             return false;
2932         }
2933
2934         if (DEBUG_FOCUS) Slog.d(TAG_FOCUS, "setFocusedActivityLocked: r=" + r);
2935
2936         final boolean wasDoingSetFocusedActivity = mDoingSetFocusedActivity;
2937         if (wasDoingSetFocusedActivity) Slog.w(TAG,
2938                 "setFocusedActivityLocked: called recursively, r=" + r + ", reason=" + reason);
2939         mDoingSetFocusedActivity = true;
2940
2941         final ActivityRecord last = mFocusedActivity;
2942         mFocusedActivity = r;
2943         if (r.task.isApplicationTask()) {
2944             if (mCurAppTimeTracker != r.appTimeTracker) {
2945                 // We are switching app tracking.  Complete the current one.
2946                 if (mCurAppTimeTracker != null) {
2947                     mCurAppTimeTracker.stop();
2948                     mHandler.obtainMessage(
2949                             REPORT_TIME_TRACKER_MSG, mCurAppTimeTracker).sendToTarget();
2950                     mStackSupervisor.clearOtherAppTimeTrackers(r.appTimeTracker);
2951                     mCurAppTimeTracker = null;
2952                 }
2953                 if (r.appTimeTracker != null) {
2954                     mCurAppTimeTracker = r.appTimeTracker;
2955                     startTimeTrackingFocusedActivityLocked();
2956                 }
2957             } else {
2958                 startTimeTrackingFocusedActivityLocked();
2959             }
2960         } else {
2961             r.appTimeTracker = null;
2962         }
2963         // TODO: VI Maybe r.task.voiceInteractor || r.voiceInteractor != null
2964         // TODO: Probably not, because we don't want to resume voice on switching
2965         // back to this activity
2966         if (r.task.voiceInteractor != null) {
2967             startRunningVoiceLocked(r.task.voiceSession, r.info.applicationInfo.uid);
2968         } else {
2969             finishRunningVoiceLocked();
2970             IVoiceInteractionSession session;
2971             if (last != null && ((session = last.task.voiceSession) != null
2972                     || (session = last.voiceSession) != null)) {
2973                 // We had been in a voice interaction session, but now focused has
2974                 // move to something different.  Just finish the session, we can't
2975                 // return to it and retain the proper state and synchronization with
2976                 // the voice interaction service.
2977                 finishVoiceTask(session);
2978             }
2979         }
2980         if (mStackSupervisor.moveActivityStackToFront(r, reason + " setFocusedActivity")) {
2981             mWindowManager.setFocusedApp(r.appToken, true);
2982         }
2983         applyUpdateLockStateLocked(r);
2984         applyUpdateVrModeLocked(r);
2985         if (mFocusedActivity.userId != mLastFocusedUserId) {
2986             mHandler.removeMessages(FOREGROUND_PROFILE_CHANGED_MSG);
2987             mHandler.obtainMessage(
2988                     FOREGROUND_PROFILE_CHANGED_MSG, mFocusedActivity.userId, 0).sendToTarget();
2989             mLastFocusedUserId = mFocusedActivity.userId;
2990         }
2991
2992         // Log a warning if the focused app is changed during the process. This could
2993         // indicate a problem of the focus setting logic!
2994         if (mFocusedActivity != r) Slog.w(TAG,
2995                 "setFocusedActivityLocked: r=" + r + " but focused to " + mFocusedActivity);
2996         mDoingSetFocusedActivity = wasDoingSetFocusedActivity;
2997
2998         EventLogTags.writeAmFocusedActivity(
2999                 mFocusedActivity == null ? -1 : mFocusedActivity.userId,
3000                 mFocusedActivity == null ? "NULL" : mFocusedActivity.shortComponentName,
3001                 reason);
3002         return true;
3003     }
3004
3005     final void resetFocusedActivityIfNeededLocked(ActivityRecord goingAway) {
3006         if (mFocusedActivity != goingAway) {
3007             return;
3008         }
3009
3010         final ActivityStack focusedStack = mStackSupervisor.getFocusedStack();
3011         if (focusedStack != null) {
3012             final ActivityRecord top = focusedStack.topActivity();
3013             if (top != null && top.userId != mLastFocusedUserId) {
3014                 mHandler.removeMessages(FOREGROUND_PROFILE_CHANGED_MSG);
3015                 mHandler.sendMessage(
3016                         mHandler.obtainMessage(FOREGROUND_PROFILE_CHANGED_MSG, top.userId, 0));
3017                 mLastFocusedUserId = top.userId;
3018             }
3019         }
3020
3021         // Try to move focus to another activity if possible.
3022         if (setFocusedActivityLocked(
3023                 focusedStack.topRunningActivityLocked(), "resetFocusedActivityIfNeeded")) {
3024             return;
3025         }
3026
3027         if (DEBUG_FOCUS) Slog.d(TAG_FOCUS, "resetFocusedActivityIfNeeded: Setting focus to NULL "
3028                 + "prev mFocusedActivity=" + mFocusedActivity + " goingAway=" + goingAway);
3029         mFocusedActivity = null;
3030         EventLogTags.writeAmFocusedActivity(-1, "NULL", "resetFocusedActivityIfNeeded");
3031     }
3032
3033     @Override
3034     public void setFocusedStack(int stackId) {
3035         enforceCallingPermission(MANAGE_ACTIVITY_STACKS, "setFocusedStack()");
3036         if (DEBUG_FOCUS) Slog.d(TAG_FOCUS, "setFocusedStack: stackId=" + stackId);
3037         final long callingId = Binder.clearCallingIdentity();
3038         try {
3039             synchronized (this) {
3040                 final ActivityStack stack = mStackSupervisor.getStack(stackId);
3041                 if (stack == null) {
3042                     return;
3043                 }
3044                 final ActivityRecord r = stack.topRunningActivityLocked();
3045                 if (setFocusedActivityLocked(r, "setFocusedStack")) {
3046                     mStackSupervisor.resumeFocusedStackTopActivityLocked();
3047                 }
3048             }
3049         } finally {
3050             Binder.restoreCallingIdentity(callingId);
3051         }
3052     }
3053
3054     @Override
3055     public void setFocusedTask(int taskId) {
3056         enforceCallingPermission(MANAGE_ACTIVITY_STACKS, "setFocusedTask()");
3057         if (DEBUG_FOCUS) Slog.d(TAG_FOCUS, "setFocusedTask: taskId=" + taskId);
3058         final long callingId = Binder.clearCallingIdentity();
3059         try {
3060             synchronized (this) {
3061                 final TaskRecord task = mStackSupervisor.anyTaskForIdLocked(taskId);
3062                 if (task == null) {
3063                     return;
3064                 }
3065                 if (mUserController.shouldConfirmCredentials(task.userId)) {
3066                     mActivityStarter.showConfirmDeviceCredential(task.userId);
3067                     if (task.stack != null && task.stack.mStackId == FREEFORM_WORKSPACE_STACK_ID) {
3068                         mStackSupervisor.moveTaskToStackLocked(task.taskId,
3069                                 FULLSCREEN_WORKSPACE_STACK_ID, !ON_TOP, !FORCE_FOCUS,
3070                                 "setFocusedTask", ANIMATE);
3071                     }
3072                     return;
3073                 }
3074                 final ActivityRecord r = task.topRunningActivityLocked();
3075                 if (setFocusedActivityLocked(r, "setFocusedTask")) {
3076                     mStackSupervisor.resumeFocusedStackTopActivityLocked();
3077                 }
3078             }
3079         } finally {
3080             Binder.restoreCallingIdentity(callingId);
3081         }
3082     }
3083
3084     /** Sets the task stack listener that gets callbacks when a task stack changes. */
3085     @Override
3086     public void registerTaskStackListener(ITaskStackListener listener) throws RemoteException {
3087         enforceCallingPermission(MANAGE_ACTIVITY_STACKS, "registerTaskStackListener()");
3088         synchronized (this) {
3089             if (listener != null) {
3090                 mTaskStackListeners.register(listener);
3091             }
3092         }
3093     }
3094
3095     @Override
3096     public void notifyActivityDrawn(IBinder token) {
3097         if (DEBUG_VISIBILITY) Slog.d(TAG_VISIBILITY, "notifyActivityDrawn: token=" + token);
3098         synchronized (this) {
3099             ActivityRecord r = mStackSupervisor.isInAnyStackLocked(token);
3100             if (r != null) {
3101                 r.task.stack.notifyActivityDrawnLocked(r);
3102             }
3103         }
3104     }
3105
3106     final void applyUpdateLockStateLocked(ActivityRecord r) {
3107         // Modifications to the UpdateLock state are done on our handler, outside
3108         // the activity manager's locks.  The new state is determined based on the
3109         // state *now* of the relevant activity record.  The object is passed to
3110         // the handler solely for logging detail, not to be consulted/modified.
3111         final boolean nextState = r != null && r.immersive;
3112         mHandler.sendMessage(
3113                 mHandler.obtainMessage(IMMERSIVE_MODE_LOCK_MSG, (nextState) ? 1 : 0, 0, r));
3114     }
3115
3116     final void applyUpdateVrModeLocked(ActivityRecord r) {
3117         mHandler.sendMessage(
3118                 mHandler.obtainMessage(VR_MODE_CHANGE_MSG, 0, 0, r));
3119     }
3120
3121     private void applyVrModeIfNeededLocked(ActivityRecord r, boolean enable) {
3122         mHandler.sendMessage(
3123                 mHandler.obtainMessage(VR_MODE_APPLY_IF_NEEDED_MSG, enable ? 1 : 0, 0, r));
3124     }
3125
3126     private void applyVrMode(boolean enabled, ComponentName packageName, int userId,
3127             ComponentName callingPackage, boolean immediate) {
3128         VrManagerInternal vrService =
3129                 LocalServices.getService(VrManagerInternal.class);
3130         if (immediate) {
3131             vrService.setVrModeImmediate(enabled, packageName, userId, callingPackage);
3132         } else {
3133             vrService.setVrMode(enabled, packageName, userId, callingPackage);
3134         }
3135     }
3136
3137     final void showAskCompatModeDialogLocked(ActivityRecord r) {
3138         Message msg = Message.obtain();
3139         msg.what = SHOW_COMPAT_MODE_DIALOG_UI_MSG;
3140         msg.obj = r.task.askedCompatMode ? null : r;
3141         mUiHandler.sendMessage(msg);
3142     }
3143
3144     final void showUnsupportedZoomDialogIfNeededLocked(ActivityRecord r) {
3145         if (mConfiguration.densityDpi != DisplayMetrics.DENSITY_DEVICE_STABLE
3146                 && r.appInfo.requiresSmallestWidthDp > mConfiguration.smallestScreenWidthDp) {
3147             final Message msg = Message.obtain();
3148             msg.what = SHOW_UNSUPPORTED_DISPLAY_SIZE_DIALOG_MSG;
3149             msg.obj = r;
3150             mUiHandler.sendMessage(msg);
3151         }
3152     }
3153
3154     private int updateLruProcessInternalLocked(ProcessRecord app, long now, int index,
3155             String what, Object obj, ProcessRecord srcApp) {
3156         app.lastActivityTime = now;
3157
3158         if (app.activities.size() > 0) {
3159             // Don't want to touch dependent processes that are hosting activities.
3160             return index;
3161         }
3162
3163         int lrui = mLruProcesses.lastIndexOf(app);
3164         if (lrui < 0) {
3165             Slog.wtf(TAG, "Adding dependent process " + app + " not on LRU list: "
3166                     + what + " " + obj + " from " + srcApp);
3167             return index;
3168         }
3169
3170         if (lrui >= index) {
3171             // Don't want to cause this to move dependent processes *back* in the
3172             // list as if they were less frequently used.
3173             return index;
3174         }
3175
3176         if (lrui >= mLruProcessActivityStart) {
3177             // Don't want to touch dependent processes that are hosting activities.
3178             return index;
3179         }
3180
3181         mLruProcesses.remove(lrui);
3182         if (index > 0) {
3183             index--;
3184         }
3185         if (DEBUG_LRU) Slog.d(TAG_LRU, "Moving dep from " + lrui + " to " + index
3186                 + " in LRU list: " + app);
3187         mLruProcesses.add(index, app);
3188         return index;
3189     }
3190
3191     static void killProcessGroup(int uid, int pid) {
3192         if (sKillHandler != null) {
3193             sKillHandler.sendMessage(
3194                     sKillHandler.obtainMessage(KillHandler.KILL_PROCESS_GROUP_MSG, uid, pid));
3195         } else {
3196             Slog.w(TAG, "Asked to kill process group before system bringup!");
3197             Process.killProcessGroup(uid, pid);
3198         }
3199     }
3200
3201     final void removeLruProcessLocked(ProcessRecord app) {
3202         int lrui = mLruProcesses.lastIndexOf(app);
3203         if (lrui >= 0) {
3204             if (!app.killed) {
3205                 Slog.wtfStack(TAG, "Removing process that hasn't been killed: " + app);
3206                 Process.killProcessQuiet(app.pid);
3207                 killProcessGroup(app.uid, app.pid);
3208             }
3209             if (lrui <= mLruProcessActivityStart) {
3210                 mLruProcessActivityStart--;
3211             }
3212             if (lrui <= mLruProcessServiceStart) {
3213                 mLruProcessServiceStart--;
3214             }
3215             mLruProcesses.remove(lrui);
3216         }
3217     }
3218
3219     final void updateLruProcessLocked(ProcessRecord app, boolean activityChange,
3220             ProcessRecord client) {
3221         final boolean hasActivity = app.activities.size() > 0 || app.hasClientActivities
3222                 || app.treatLikeActivity;
3223         final boolean hasService = false; // not impl yet. app.services.size() > 0;
3224         if (!activityChange && hasActivity) {
3225             // The process has activities, so we are only allowing activity-based adjustments
3226             // to move it.  It should be kept in the front of the list with other
3227             // processes that have activities, and we don't want those to change their
3228             // order except due to activity operations.
3229             return;
3230         }
3231
3232         mLruSeq++;
3233         final long now = SystemClock.uptimeMillis();
3234         app.lastActivityTime = now;
3235
3236         // First a quick reject: if the app is already at the position we will
3237         // put it, then there is nothing to do.
3238         if (hasActivity) {
3239             final int N = mLruProcesses.size();
3240             if (N > 0 && mLruProcesses.get(N-1) == app) {
3241                 if (DEBUG_LRU) Slog.d(TAG_LRU, "Not moving, already top activity: " + app);
3242                 return;
3243             }
3244         } else {
3245             if (mLruProcessServiceStart > 0
3246                     && mLruProcesses.get(mLruProcessServiceStart-1) == app) {
3247                 if (DEBUG_LRU) Slog.d(TAG_LRU, "Not moving, already top other: " + app);
3248                 return;
3249             }
3250         }
3251
3252         int lrui = mLruProcesses.lastIndexOf(app);
3253
3254         if (app.persistent && lrui >= 0) {
3255             // We don't care about the position of persistent processes, as long as
3256             // they are in the list.
3257             if (DEBUG_LRU) Slog.d(TAG_LRU, "Not moving, persistent: " + app);
3258             return;
3259         }
3260
3261         /* In progress: compute new position first, so we can avoid doing work
3262            if the process is not actually going to move.  Not yet working.
3263         int addIndex;
3264         int nextIndex;
3265         boolean inActivity = false, inService = false;
3266         if (hasActivity) {
3267             // Process has activities, put it at the very tipsy-top.
3268             addIndex = mLruProcesses.size();
3269             nextIndex = mLruProcessServiceStart;
3270             inActivity = true;
3271         } else if (hasService) {
3272             // Process has services, put it at the top of the service list.
3273             addIndex = mLruProcessActivityStart;
3274             nextIndex = mLruProcessServiceStart;
3275             inActivity = true;
3276             inService = true;
3277         } else  {
3278             // Process not otherwise of interest, it goes to the top of the non-service area.
3279             addIndex = mLruProcessServiceStart;
3280             if (client != null) {
3281                 int clientIndex = mLruProcesses.lastIndexOf(client);
3282                 if (clientIndex < 0) Slog.d(TAG, "Unknown client " + client + " when updating "
3283                         + app);
3284                 if (clientIndex >= 0 && addIndex > clientIndex) {
3285                     addIndex = clientIndex;
3286                 }
3287             }
3288             nextIndex = addIndex > 0 ? addIndex-1 : addIndex;
3289         }
3290
3291         Slog.d(TAG, "Update LRU at " + lrui + " to " + addIndex + " (act="
3292                 + mLruProcessActivityStart + "): " + app);
3293         */
3294
3295         if (lrui >= 0) {
3296             if (lrui < mLruProcessActivityStart) {
3297                 mLruProcessActivityStart--;
3298             }
3299             if (lrui < mLruProcessServiceStart) {
3300                 mLruProcessServiceStart--;
3301             }
3302             /*
3303             if (addIndex > lrui) {
3304                 addIndex--;
3305             }
3306             if (nextIndex > lrui) {
3307                 nextIndex--;
3308             }
3309             */
3310             mLruProcesses.remove(lrui);
3311         }
3312
3313         /*
3314         mLruProcesses.add(addIndex, app);
3315         if (inActivity) {
3316             mLruProcessActivityStart++;
3317         }
3318         if (inService) {
3319             mLruProcessActivityStart++;
3320         }
3321         */
3322
3323         int nextIndex;
3324         if (hasActivity) {
3325             final int N = mLruProcesses.size();
3326             if (app.activities.size() == 0 && mLruProcessActivityStart < (N - 1)) {
3327                 // Process doesn't have activities, but has clients with
3328                 // activities...  move it up, but one below the top (the top
3329                 // should always have a real activity).
3330                 if (DEBUG_LRU) Slog.d(TAG_LRU,
3331                         "Adding to second-top of LRU activity list: " + app);
3332                 mLruProcesses.add(N - 1, app);
3333                 // To keep it from spamming the LRU list (by making a bunch of clients),
3334                 // we will push down any other entries owned by the app.
3335                 final int uid = app.info.uid;
3336                 for (int i = N - 2; i > mLruProcessActivityStart; i--) {
3337                     ProcessRecord subProc = mLruProcesses.get(i);
3338                     if (subProc.info.uid == uid) {
3339                         // We want to push this one down the list.  If the process after
3340                         // it is for the same uid, however, don't do so, because we don't
3341                         // want them internally to be re-ordered.
3342                         if (mLruProcesses.get(i - 1).info.uid != uid) {
3343                             if (DEBUG_LRU) Slog.d(TAG_LRU,
3344                                     "Pushing uid " + uid + " swapping at " + i + ": "
3345                                     + mLruProcesses.get(i) + " : " + mLruProcesses.get(i - 1));
3346                             ProcessRecord tmp = mLruProcesses.get(i);
3347                             mLruProcesses.set(i, mLruProcesses.get(i - 1));
3348                             mLruProcesses.set(i - 1, tmp);
3349                             i--;
3350                         }
3351                     } else {
3352                         // A gap, we can stop here.
3353                         break;
3354                     }
3355                 }
3356             } else {
3357                 // Process has activities, put it at the very tipsy-top.
3358                 if (DEBUG_LRU) Slog.d(TAG_LRU, "Adding to top of LRU activity list: " + app);
3359                 mLruProcesses.add(app);
3360             }
3361             nextIndex = mLruProcessServiceStart;
3362         } else if (hasService) {
3363             // Process has services, put it at the top of the service list.
3364             if (DEBUG_LRU) Slog.d(TAG_LRU, "Adding to top of LRU service list: " + app);
3365             mLruProcesses.add(mLruProcessActivityStart, app);
3366             nextIndex = mLruProcessServiceStart;
3367             mLruProcessActivityStart++;
3368         } else  {
3369             // Process not otherwise of interest, it goes to the top of the non-service area.
3370             int index = mLruProcessServiceStart;
3371             if (client != null) {
3372                 // If there is a client, don't allow the process to be moved up higher
3373                 // in the list than that client.
3374                 int clientIndex = mLruProcesses.lastIndexOf(client);
3375                 if (DEBUG_LRU && clientIndex < 0) Slog.d(TAG_LRU, "Unknown client " + client
3376                         + " when updating " + app);
3377                 if (clientIndex <= lrui) {
3378                     // Don't allow the client index restriction to push it down farther in the
3379                     // list than it already is.
3380                     clientIndex = lrui;
3381                 }
3382                 if (clientIndex >= 0 && index > clientIndex) {
3383                     index = clientIndex;
3384                 }
3385             }
3386             if (DEBUG_LRU) Slog.d(TAG_LRU, "Adding at " + index + " of LRU list: " + app);
3387             mLruProcesses.add(index, app);
3388             nextIndex = index-1;
3389             mLruProcessActivityStart++;
3390             mLruProcessServiceStart++;
3391         }
3392
3393         // If the app is currently using a content provider or service,
3394         // bump those processes as well.
3395         for (int j=app.connections.size()-1; j>=0; j--) {
3396             ConnectionRecord cr = app.connections.valueAt(j);
3397             if (cr.binding != null && !cr.serviceDead && cr.binding.service != null
3398                     && cr.binding.service.app != null
3399                     && cr.binding.service.app.lruSeq != mLruSeq
3400                     && !cr.binding.service.app.persistent) {
3401                 nextIndex = updateLruProcessInternalLocked(cr.binding.service.app, now, nextIndex,
3402                         "service connection", cr, app);
3403             }
3404         }
3405         for (int j=app.conProviders.size()-1; j>=0; j--) {
3406             ContentProviderRecord cpr = app.conProviders.get(j).provider;
3407             if (cpr.proc != null && cpr.proc.lruSeq != mLruSeq && !cpr.proc.persistent) {
3408                 nextIndex = updateLruProcessInternalLocked(cpr.proc, now, nextIndex,
3409                         "provider reference", cpr, app);
3410             }
3411         }
3412     }
3413
3414     final ProcessRecord getProcessRecordLocked(String processName, int uid, boolean keepIfLarge) {
3415         if (uid == Process.SYSTEM_UID) {
3416             // The system gets to run in any process.  If there are multiple
3417             // processes with the same uid, just pick the first (this
3418             // should never happen).
3419             SparseArray<ProcessRecord> procs = mProcessNames.getMap().get(processName);
3420             if (procs == null) return null;
3421             final int procCount = procs.size();
3422             for (int i = 0; i < procCount; i++) {
3423                 final int procUid = procs.keyAt(i);
3424                 if (UserHandle.isApp(procUid) || !UserHandle.isSameUser(procUid, uid)) {
3425                     // Don't use an app process or different user process for system component.
3426                     continue;
3427                 }
3428                 return procs.valueAt(i);
3429             }
3430         }
3431         ProcessRecord proc = mProcessNames.get(processName, uid);
3432         if (false && proc != null && !keepIfLarge
3433                 && proc.setProcState >= ActivityManager.PROCESS_STATE_CACHED_EMPTY
3434                 && proc.lastCachedPss >= 4000) {
3435             // Turn this condition on to cause killing to happen regularly, for testing.
3436             if (proc.baseProcessTracker != null) {
3437                 proc.baseProcessTracker.reportCachedKill(proc.pkgList, proc.lastCachedPss);
3438             }
3439             proc.kill(Long.toString(proc.lastCachedPss) + "k from cached", true);
3440         } else if (proc != null && !keepIfLarge
3441                 && mLastMemoryLevel > ProcessStats.ADJ_MEM_FACTOR_NORMAL
3442                 && proc.setProcState >= ActivityManager.PROCESS_STATE_CACHED_EMPTY) {
3443             if (DEBUG_PSS) Slog.d(TAG_PSS, "May not keep " + proc + ": pss=" + proc.lastCachedPss);
3444             if (proc.lastCachedPss >= mProcessList.getCachedRestoreThresholdKb()) {
3445                 if (proc.baseProcessTracker != null) {
3446                     proc.baseProcessTracker.reportCachedKill(proc.pkgList, proc.lastCachedPss);
3447                 }
3448                 proc.kill(Long.toString(proc.lastCachedPss) + "k from cached", true);
3449             }
3450         }
3451         return proc;
3452     }
3453
3454     void notifyPackageUse(String packageName, int reason) {
3455         IPackageManager pm = AppGlobals.getPackageManager();
3456         try {
3457             pm.notifyPackageUse(packageName, reason);
3458         } catch (RemoteException e) {
3459         }
3460     }
3461
3462     boolean isNextTransitionForward() {
3463         int transit = mWindowManager.getPendingAppTransition();
3464         return transit == TRANSIT_ACTIVITY_OPEN
3465                 || transit == TRANSIT_TASK_OPEN
3466                 || transit == TRANSIT_TASK_TO_FRONT;
3467     }
3468
3469     int startIsolatedProcess(String entryPoint, String[] entryPointArgs,
3470             String processName, String abiOverride, int uid, Runnable crashHandler) {
3471         synchronized(this) {
3472             ApplicationInfo info = new ApplicationInfo();
3473             // In general the ApplicationInfo.uid isn't neccesarily equal to ProcessRecord.uid.
3474             // For isolated processes, the former contains the parent's uid and the latter the
3475             // actual uid of the isolated process.
3476             // In the special case introduced by this method (which is, starting an isolated
3477             // process directly from the SystemServer without an actual parent app process) the
3478             // closest thing to a parent's uid is SYSTEM_UID.
3479             // The only important thing here is to keep AI.uid != PR.uid, in order to trigger
3480             // the |isolated| logic in the ProcessRecord constructor.
3481             info.uid = Process.SYSTEM_UID;
3482             info.processName = processName;
3483             info.className = entryPoint;
3484             info.packageName = "android";
3485             ProcessRecord proc = startProcessLocked(processName, info /* info */,
3486                     false /* knownToBeDead */, 0 /* intentFlags */, ""  /* hostingType */,
3487                     null /* hostingName */, true /* allowWhileBooting */, true /* isolated */,
3488                     uid, true /* keepIfLarge */, abiOverride, entryPoint, entryPointArgs,
3489                     crashHandler);
3490             return proc != null ? proc.pid : 0;
3491         }
3492     }
3493
3494     final ProcessRecord startProcessLocked(String processName,
3495             ApplicationInfo info, boolean knownToBeDead, int intentFlags,
3496             String hostingType, ComponentName hostingName, boolean allowWhileBooting,
3497             boolean isolated, boolean keepIfLarge) {
3498         return startProcessLocked(processName, info, knownToBeDead, intentFlags, hostingType,
3499                 hostingName, allowWhileBooting, isolated, 0 /* isolatedUid */, keepIfLarge,
3500                 null /* ABI override */, null /* entryPoint */, null /* entryPointArgs */,
3501                 null /* crashHandler */);
3502     }
3503
3504     final ProcessRecord startProcessLocked(String processName, ApplicationInfo info,
3505             boolean knownToBeDead, int intentFlags, String hostingType, ComponentName hostingName,
3506             boolean allowWhileBooting, boolean isolated, int isolatedUid, boolean keepIfLarge,
3507             String abiOverride, String entryPoint, String[] entryPointArgs, Runnable crashHandler) {
3508         long startTime = SystemClock.elapsedRealtime();
3509         ProcessRecord app;
3510         if (!isolated) {
3511             app = getProcessRecordLocked(processName, info.uid, keepIfLarge);
3512             checkTime(startTime, "startProcess: after getProcessRecord");
3513
3514             if ((intentFlags & Intent.FLAG_FROM_BACKGROUND) != 0) {
3515                 // If we are in the background, then check to see if this process
3516                 // is bad.  If so, we will just silently fail.
3517                 if (mAppErrors.isBadProcessLocked(info)) {
3518                     if (DEBUG_PROCESSES) Slog.v(TAG, "Bad process: " + info.uid
3519                             + "/" + info.processName);
3520                     return null;
3521                 }
3522             } else {
3523                 // When the user is explicitly starting a process, then clear its
3524                 // crash count so that we won't make it bad until they see at
3525                 // least one crash dialog again, and make the process good again
3526                 // if it had been bad.
3527                 if (DEBUG_PROCESSES) Slog.v(TAG, "Clearing bad process: " + info.uid
3528                         + "/" + info.processName);
3529                 mAppErrors.resetProcessCrashTimeLocked(info);
3530                 if (mAppErrors.isBadProcessLocked(info)) {
3531                     EventLog.writeEvent(EventLogTags.AM_PROC_GOOD,
3532                             UserHandle.getUserId(info.uid), info.uid,
3533                             info.processName);
3534                     mAppErrors.clearBadProcessLocked(info);
3535                     if (app != null) {
3536                         app.bad = false;
3537                     }
3538                 }
3539             }
3540         } else {
3541             // If this is an isolated process, it can't re-use an existing process.
3542             app = null;
3543         }
3544
3545         // app launch boost for big.little configurations
3546         // use cpusets to migrate freshly launched tasks to big cores
3547         nativeMigrateToBoost();
3548         mIsBoosted = true;
3549         mBoostStartTime = SystemClock.uptimeMillis();
3550         Message msg = mHandler.obtainMessage(APP_BOOST_DEACTIVATE_MSG);
3551         mHandler.sendMessageDelayed(msg, APP_BOOST_MESSAGE_DELAY);
3552
3553         // We don't have to do anything more if:
3554         // (1) There is an existing application record; and
3555         // (2) The caller doesn't think it is dead, OR there is no thread
3556         //     object attached to it so we know it couldn't have crashed; and
3557         // (3) There is a pid assigned to it, so it is either starting or
3558         //     already running.
3559         if (DEBUG_PROCESSES) Slog.v(TAG_PROCESSES, "startProcess: name=" + processName
3560                 + " app=" + app + " knownToBeDead=" + knownToBeDead
3561                 + " thread=" + (app != null ? app.thread : null)
3562                 + " pid=" + (app != null ? app.pid : -1));
3563         if (app != null && app.pid > 0) {
3564             if ((!knownToBeDead && !app.killed) || app.thread == null) {
3565                 // We already have the app running, or are waiting for it to
3566                 // come up (we have a pid but not yet its thread), so keep it.
3567                 if (DEBUG_PROCESSES) Slog.v(TAG_PROCESSES, "App already running: " + app);
3568                 // If this is a new package in the process, add the package to the list
3569                 app.addPackage(info.packageName, info.versionCode, mProcessStats);
3570                 checkTime(startTime, "startProcess: done, added package to proc");
3571                 return app;
3572             }
3573
3574             // An application record is attached to a previous process,
3575             // clean it up now.
3576             if (DEBUG_PROCESSES || DEBUG_CLEANUP) Slog.v(TAG_PROCESSES, "App died: " + app);
3577             checkTime(startTime, "startProcess: bad proc running, killing");
3578             killProcessGroup(app.uid, app.pid);
3579             handleAppDiedLocked(app, true, true);
3580             checkTime(startTime, "startProcess: done killing old proc");
3581         }
3582
3583         String hostingNameStr = hostingName != null
3584                 ? hostingName.flattenToShortString() : null;
3585
3586         if (app == null) {
3587             checkTime(startTime, "startProcess: creating new process record");
3588             app = newProcessRecordLocked(info, processName, isolated, isolatedUid);
3589             if (app == null) {
3590                 Slog.w(TAG, "Failed making new process record for "
3591                         + processName + "/" + info.uid + " isolated=" + isolated);
3592                 return null;
3593             }
3594             app.crashHandler = crashHandler;
3595             checkTime(startTime, "startProcess: done creating new process record");
3596         } else {
3597             // If this is a new package in the process, add the package to the list
3598             app.addPackage(info.packageName, info.versionCode, mProcessStats);
3599             checkTime(startTime, "startProcess: added package to existing proc");
3600         }
3601
3602         // If the system is not ready yet, then hold off on starting this
3603         // process until it is.
3604         if (!mProcessesReady
3605                 && !isAllowedWhileBooting(info)
3606                 && !allowWhileBooting) {
3607             if (!mProcessesOnHold.contains(app)) {
3608                 mProcessesOnHold.add(app);
3609             }
3610             if (DEBUG_PROCESSES) Slog.v(TAG_PROCESSES,
3611                     "System not ready, putting on hold: " + app);
3612             checkTime(startTime, "startProcess: returning with proc on hold");
3613             return app;
3614         }
3615
3616         checkTime(startTime, "startProcess: stepping in to startProcess");
3617         startProcessLocked(
3618                 app, hostingType, hostingNameStr, abiOverride, entryPoint, entryPointArgs);
3619         checkTime(startTime, "startProcess: done starting proc!");
3620         return (app.pid != 0) ? app : null;
3621     }
3622
3623     boolean isAllowedWhileBooting(ApplicationInfo ai) {
3624         return (ai.flags&ApplicationInfo.FLAG_PERSISTENT) != 0;
3625     }
3626
3627     private final void startProcessLocked(ProcessRecord app,
3628             String hostingType, String hostingNameStr) {
3629         startProcessLocked(app, hostingType, hostingNameStr, null /* abiOverride */,
3630                 null /* entryPoint */, null /* entryPointArgs */);
3631     }
3632
3633     private final void startProcessLocked(ProcessRecord app, String hostingType,
3634             String hostingNameStr, String abiOverride, String entryPoint, String[] entryPointArgs) {
3635         long startTime = SystemClock.elapsedRealtime();
3636         if (app.pid > 0 && app.pid != MY_PID) {
3637             checkTime(startTime, "startProcess: removing from pids map");
3638             synchronized (mPidsSelfLocked) {
3639                 mPidsSelfLocked.remove(app.pid);
3640                 mHandler.removeMessages(PROC_START_TIMEOUT_MSG, app);
3641             }
3642             checkTime(startTime, "startProcess: done removing from pids map");
3643             app.setPid(0);
3644         }
3645
3646         if (DEBUG_PROCESSES && mProcessesOnHold.contains(app)) Slog.v(TAG_PROCESSES,
3647                 "startProcessLocked removing on hold: " + app);
3648         mProcessesOnHold.remove(app);
3649
3650         checkTime(startTime, "startProcess: starting to update cpu stats");
3651         updateCpuStats();
3652         checkTime(startTime, "startProcess: done updating cpu stats");
3653
3654         try {
3655             try {
3656                 final int userId = UserHandle.getUserId(app.uid);
3657                 AppGlobals.getPackageManager().checkPackageStartable(app.info.packageName, userId);
3658             } catch (RemoteException e) {
3659                 throw e.rethrowAsRuntimeException();
3660             }
3661
3662             int uid = app.uid;
3663             int[] gids = null;
3664             int mountExternal = Zygote.MOUNT_EXTERNAL_NONE;
3665             if (!app.isolated) {
3666                 int[] permGids = null;
3667                 try {
3668                     checkTime(startTime, "startProcess: getting gids from package manager");
3669                     final IPackageManager pm = AppGlobals.getPackageManager();
3670                     permGids = pm.getPackageGids(app.info.packageName,
3671                             MATCH_DEBUG_TRIAGED_MISSING, app.userId);
3672                     MountServiceInternal mountServiceInternal = LocalServices.getService(
3673                             MountServiceInternal.class);
3674                     mountExternal = mountServiceInternal.getExternalStorageMountMode(uid,
3675                             app.info.packageName);
3676                 } catch (RemoteException e) {
3677                     throw e.rethrowAsRuntimeException();
3678                 }
3679
3680                 /*
3681                  * Add shared application and profile GIDs so applications can share some
3682                  * resources like shared libraries and access user-wide resources
3683                  */
3684                 if (ArrayUtils.isEmpty(permGids)) {
3685                     gids = new int[2];
3686                 } else {
3687                     gids = new int[permGids.length + 2];
3688                     System.arraycopy(permGids, 0, gids, 2, permGids.length);
3689                 }
3690                 gids[0] = UserHandle.getSharedAppGid(UserHandle.getAppId(uid));
3691                 gids[1] = UserHandle.getUserGid(UserHandle.getUserId(uid));
3692             }
3693             checkTime(startTime, "startProcess: building args");
3694             if (mFactoryTest != FactoryTest.FACTORY_TEST_OFF) {
3695                 if (mFactoryTest == FactoryTest.FACTORY_TEST_LOW_LEVEL
3696                         && mTopComponent != null
3697                         && app.processName.equals(mTopComponent.getPackageName())) {
3698                     uid = 0;
3699                 }
3700                 if (mFactoryTest == FactoryTest.FACTORY_TEST_HIGH_LEVEL
3701                         && (app.info.flags&ApplicationInfo.FLAG_FACTORY_TEST) != 0) {
3702                     uid = 0;
3703                 }
3704             }
3705             int debugFlags = 0;
3706             if ((app.info.flags & ApplicationInfo.FLAG_DEBUGGABLE) != 0) {
3707                 debugFlags |= Zygote.DEBUG_ENABLE_DEBUGGER;
3708                 // Also turn on CheckJNI for debuggable apps. It's quite
3709                 // awkward to turn on otherwise.
3710                 debugFlags |= Zygote.DEBUG_ENABLE_CHECKJNI;
3711             }
3712             // Run the app in safe mode if its manifest requests so or the
3713             // system is booted in safe mode.
3714             if ((app.info.flags & ApplicationInfo.FLAG_VM_SAFE_MODE) != 0 ||
3715                 mSafeMode == true) {
3716                 debugFlags |= Zygote.DEBUG_ENABLE_SAFEMODE;
3717             }
3718             if ("1".equals(SystemProperties.get("debug.checkjni"))) {
3719                 debugFlags |= Zygote.DEBUG_ENABLE_CHECKJNI;
3720             }
3721             String genDebugInfoProperty = SystemProperties.get("debug.generate-debug-info");
3722             if ("true".equals(genDebugInfoProperty)) {
3723                 debugFlags |= Zygote.DEBUG_GENERATE_DEBUG_INFO;
3724             }
3725             if ("1".equals(SystemProperties.get("debug.jni.logging"))) {
3726                 debugFlags |= Zygote.DEBUG_ENABLE_JNI_LOGGING;
3727             }
3728             if ("1".equals(SystemProperties.get("debug.assert"))) {
3729                 debugFlags |= Zygote.DEBUG_ENABLE_ASSERT;
3730             }
3731             if (mNativeDebuggingApp != null && mNativeDebuggingApp.equals(app.processName)) {
3732                 // Enable all debug flags required by the native debugger.
3733                 debugFlags |= Zygote.DEBUG_ALWAYS_JIT;          // Don't interpret anything
3734                 debugFlags |= Zygote.DEBUG_GENERATE_DEBUG_INFO; // Generate debug info
3735                 debugFlags |= Zygote.DEBUG_NATIVE_DEBUGGABLE;   // Disbale optimizations
3736                 mNativeDebuggingApp = null;
3737             }
3738
3739             String requiredAbi = (abiOverride != null) ? abiOverride : app.info.primaryCpuAbi;
3740             if (requiredAbi == null) {
3741                 requiredAbi = Build.SUPPORTED_ABIS[0];
3742             }
3743
3744             String instructionSet = null;
3745             if (app.info.primaryCpuAbi != null) {
3746                 instructionSet = VMRuntime.getInstructionSet(app.info.primaryCpuAbi);
3747             }
3748
3749             app.gids = gids;
3750             app.requiredAbi = requiredAbi;
3751             app.instructionSet = instructionSet;
3752
3753             // Start the process.  It will either succeed and return a result containing
3754             // the PID of the new process, or else throw a RuntimeException.
3755             boolean isActivityProcess = (entryPoint == null);
3756             if (entryPoint == null) entryPoint = "android.app.ActivityThread";
3757             Trace.traceBegin(Trace.TRACE_TAG_ACTIVITY_MANAGER, "Start proc: " +
3758                     app.processName);
3759             checkTime(startTime, "startProcess: asking zygote to start proc");
3760             Process.ProcessStartResult startResult = Process.start(entryPoint,
3761                     app.processName, uid, uid, gids, debugFlags, mountExternal,
3762                     app.info.targetSdkVersion, app.info.seinfo, requiredAbi, instructionSet,
3763                     app.info.dataDir, entryPointArgs);
3764             checkTime(startTime, "startProcess: returned from zygote!");
3765             Trace.traceEnd(Trace.TRACE_TAG_ACTIVITY_MANAGER);
3766
3767             if (app.isolated) {
3768                 mBatteryStatsService.addIsolatedUid(app.uid, app.info.uid);
3769             }
3770             mBatteryStatsService.noteProcessStart(app.processName, app.info.uid);
3771             checkTime(startTime, "startProcess: done updating battery stats");
3772
3773             EventLog.writeEvent(EventLogTags.AM_PROC_START,
3774                     UserHandle.getUserId(uid), startResult.pid, uid,
3775                     app.processName, hostingType,
3776                     hostingNameStr != null ? hostingNameStr : "");
3777
3778             try {
3779                 AppGlobals.getPackageManager().logAppProcessStartIfNeeded(app.processName, app.uid,
3780                         app.info.seinfo, app.info.sourceDir, startResult.pid);
3781             } catch (RemoteException ex) {
3782                 // Ignore
3783             }
3784
3785             if (app.persistent) {
3786                 Watchdog.getInstance().processStarted(app.processName, startResult.pid);
3787             }
3788
3789             checkTime(startTime, "startProcess: building log message");
3790             StringBuilder buf = mStringBuilder;
3791             buf.setLength(0);
3792             buf.append("Start proc ");
3793             buf.append(startResult.pid);
3794             buf.append(':');
3795             buf.append(app.processName);
3796             buf.append('/');
3797             UserHandle.formatUid(buf, uid);
3798             if (!isActivityProcess) {
3799                 buf.append(" [");
3800                 buf.append(entryPoint);
3801                 buf.append("]");
3802             }
3803             buf.append(" for ");
3804             buf.append(hostingType);
3805             if (hostingNameStr != null) {
3806                 buf.append(" ");
3807                 buf.append(hostingNameStr);
3808             }
3809             Slog.i(TAG, buf.toString());
3810             app.setPid(startResult.pid);
3811             app.usingWrapper = startResult.usingWrapper;
3812             app.removed = false;
3813             app.killed = false;
3814             app.killedByAm = false;
3815             checkTime(startTime, "startProcess: starting to update pids map");
3816             ProcessRecord oldApp;
3817             synchronized (mPidsSelfLocked) {
3818                 oldApp = mPidsSelfLocked.get(startResult.pid);
3819             }
3820             // If there is already an app occupying that pid that hasn't been cleaned up
3821             if (oldApp != null && !app.isolated) {
3822                 // Clean up anything relating to this pid first
3823                 Slog.w(TAG, "Reusing pid " + startResult.pid
3824                         + " while app is still mapped to it");
3825                 cleanUpApplicationRecordLocked(oldApp, false, false, -1,
3826                         true /*replacingPid*/);
3827             }
3828             synchronized (mPidsSelfLocked) {
3829                 this.mPidsSelfLocked.put(startResult.pid, app);
3830                 if (isActivityProcess) {
3831                     Message msg = mHandler.obtainMessage(PROC_START_TIMEOUT_MSG);
3832                     msg.obj = app;
3833                     mHandler.sendMessageDelayed(msg, startResult.usingWrapper
3834                             ? PROC_START_TIMEOUT_WITH_WRAPPER : PROC_START_TIMEOUT);
3835                 }
3836             }
3837             checkTime(startTime, "startProcess: done updating pids map");
3838         } catch (RuntimeException e) {
3839             Slog.e(TAG, "Failure starting process " + app.processName, e);
3840
3841             // Something went very wrong while trying to start this process; one
3842             // common case is when the package is frozen due to an active
3843             // upgrade. To recover, clean up any active bookkeeping related to
3844             // starting this process. (We already invoked this method once when
3845             // the package was initially frozen through KILL_APPLICATION_MSG, so
3846             // it doesn't hurt to use it again.)
3847             forceStopPackageLocked(app.info.packageName, UserHandle.getAppId(app.uid), false,
3848                     false, true, false, false, UserHandle.getUserId(app.userId), "start failure");
3849         }
3850     }
3851
3852     void updateUsageStats(ActivityRecord component, boolean resumed) {
3853         if (DEBUG_SWITCH) Slog.d(TAG_SWITCH,
3854                 "updateUsageStats: comp=" + component + "res=" + resumed);
3855         final BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
3856         if (resumed) {
3857             if (mUsageStatsService != null) {
3858                 mUsageStatsService.reportEvent(component.realActivity, component.userId,
3859                         UsageEvents.Event.MOVE_TO_FOREGROUND);
3860             }
3861             synchronized (stats) {
3862                 stats.noteActivityResumedLocked(component.app.uid);
3863             }
3864         } else {
3865             if (mUsageStatsService != null) {
3866                 mUsageStatsService.reportEvent(component.realActivity, component.userId,
3867                         UsageEvents.Event.MOVE_TO_BACKGROUND);
3868             }
3869             synchronized (stats) {
3870                 stats.noteActivityPausedLocked(component.app.uid);
3871             }
3872         }
3873     }
3874
3875     Intent getHomeIntent() {
3876         Intent intent = new Intent(mTopAction, mTopData != null ? Uri.parse(mTopData) : null);
3877         intent.setComponent(mTopComponent);
3878         intent.addFlags(Intent.FLAG_DEBUG_TRIAGED_MISSING);
3879         if (mFactoryTest != FactoryTest.FACTORY_TEST_LOW_LEVEL) {
3880             intent.addCategory(Intent.CATEGORY_HOME);
3881         }
3882         return intent;
3883     }
3884
3885     boolean startHomeActivityLocked(int userId, String reason) {
3886         if (mFactoryTest == FactoryTest.FACTORY_TEST_LOW_LEVEL
3887                 && mTopAction == null) {
3888             // We are running in factory test mode, but unable to find
3889             // the factory test app, so just sit around displaying the
3890             // error message and don't try to start anything.
3891             return false;
3892         }
3893         Intent intent = getHomeIntent();
3894         ActivityInfo aInfo = resolveActivityInfo(intent, STOCK_PM_FLAGS, userId);
3895         if (aInfo != null) {
3896             intent.setComponent(new ComponentName(aInfo.applicationInfo.packageName, aInfo.name));
3897             // Don't do this if the home app is currently being
3898             // instrumented.
3899             aInfo = new ActivityInfo(aInfo);
3900             aInfo.applicationInfo = getAppInfoForUser(aInfo.applicationInfo, userId);
3901             ProcessRecord app = getProcessRecordLocked(aInfo.processName,
3902                     aInfo.applicationInfo.uid, true);
3903             if (app == null || app.instrumentationClass == null) {
3904                 intent.setFlags(intent.getFlags() | Intent.FLAG_ACTIVITY_NEW_TASK);
3905                 mActivityStarter.startHomeActivityLocked(intent, aInfo, reason);
3906             }
3907         } else {
3908             Slog.wtf(TAG, "No home screen found for " + intent, new Throwable());
3909         }
3910
3911         return true;
3912     }
3913
3914     private ActivityInfo resolveActivityInfo(Intent intent, int flags, int userId) {
3915         ActivityInfo ai = null;
3916         ComponentName comp = intent.getComponent();
3917         try {
3918             if (comp != null) {
3919                 // Factory test.
3920                 ai = AppGlobals.getPackageManager().getActivityInfo(comp, flags, userId);
3921             } else {
3922                 ResolveInfo info = AppGlobals.getPackageManager().resolveIntent(
3923                         intent,
3924                         intent.resolveTypeIfNeeded(mContext.getContentResolver()),
3925                         flags, userId);
3926
3927                 if (info != null) {
3928                     ai = info.activityInfo;
3929                 }
3930             }
3931         } catch (RemoteException e) {
3932             // ignore
3933         }
3934
3935         return ai;
3936     }
3937
3938     /**
3939      * Starts the "new version setup screen" if appropriate.
3940      */
3941     void startSetupActivityLocked() {
3942         // Only do this once per boot.
3943         if (mCheckedForSetup) {
3944             return;
3945         }
3946
3947         // We will show this screen if the current one is a different
3948         // version than the last one shown, and we are not running in
3949         // low-level factory test mode.
3950         final ContentResolver resolver = mContext.getContentResolver();
3951         if (mFactoryTest != FactoryTest.FACTORY_TEST_LOW_LEVEL &&
3952                 Settings.Global.getInt(resolver,
3953                         Settings.Global.DEVICE_PROVISIONED, 0) != 0) {
3954             mCheckedForSetup = true;
3955
3956             // See if we should be showing the platform update setup UI.
3957             final Intent intent = new Intent(Intent.ACTION_UPGRADE_SETUP);
3958             final List<ResolveInfo> ris = mContext.getPackageManager().queryIntentActivities(intent,
3959                     PackageManager.MATCH_SYSTEM_ONLY | PackageManager.GET_META_DATA);
3960             if (!ris.isEmpty()) {
3961                 final ResolveInfo ri = ris.get(0);
3962                 String vers = ri.activityInfo.metaData != null
3963                         ? ri.activityInfo.metaData.getString(Intent.METADATA_SETUP_VERSION)
3964                         : null;
3965                 if (vers == null && ri.activityInfo.applicationInfo.metaData != null) {
3966                     vers = ri.activityInfo.applicationInfo.metaData.getString(
3967                             Intent.METADATA_SETUP_VERSION);
3968                 }
3969                 String lastVers = Settings.Secure.getString(
3970                         resolver, Settings.Secure.LAST_SETUP_SHOWN);
3971                 if (vers != null && !vers.equals(lastVers)) {
3972                     intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
3973                     intent.setComponent(new ComponentName(
3974                             ri.activityInfo.packageName, ri.activityInfo.name));
3975                     mActivityStarter.startActivityLocked(null, intent, null /*ephemeralIntent*/,
3976                             null, ri.activityInfo, null /*rInfo*/, null, null, null, null, 0, 0, 0,
3977                             null, 0, 0, 0, null, false, false, null, null, null);
3978                 }
3979             }
3980         }
3981     }
3982
3983     CompatibilityInfo compatibilityInfoForPackageLocked(ApplicationInfo ai) {
3984         return mCompatModePackages.compatibilityInfoForPackageLocked(ai);
3985     }
3986
3987     void enforceNotIsolatedCaller(String caller) {
3988         if (UserHandle.isIsolated(Binder.getCallingUid())) {
3989             throw new SecurityException("Isolated process not allowed to call " + caller);
3990         }
3991     }
3992
3993     void enforceShellRestriction(String restriction, int userHandle) {
3994         if (Binder.getCallingUid() == Process.SHELL_UID) {
3995             if (userHandle < 0 || mUserController.hasUserRestriction(restriction, userHandle)) {
3996                 throw new SecurityException("Shell does not have permission to access user "
3997                         + userHandle);
3998             }
3999         }
4000     }
4001
4002     @Override
4003     public int getFrontActivityScreenCompatMode() {
4004         enforceNotIsolatedCaller("getFrontActivityScreenCompatMode");
4005         synchronized (this) {
4006             return mCompatModePackages.getFrontActivityScreenCompatModeLocked();
4007         }
4008     }
4009
4010     @Override
4011     public void setFrontActivityScreenCompatMode(int mode) {
4012         enforceCallingPermission(android.Manifest.permission.SET_SCREEN_COMPATIBILITY,
4013                 "setFrontActivityScreenCompatMode");
4014         synchronized (this) {
4015             mCompatModePackages.setFrontActivityScreenCompatModeLocked(mode);
4016         }
4017     }
4018
4019     @Override
4020     public int getPackageScreenCompatMode(String packageName) {
4021         enforceNotIsolatedCaller("getPackageScreenCompatMode");
4022         synchronized (this) {
4023             return mCompatModePackages.getPackageScreenCompatModeLocked(packageName);
4024         }
4025     }
4026
4027     @Override
4028     public void setPackageScreenCompatMode(String packageName, int mode) {
4029         enforceCallingPermission(android.Manifest.permission.SET_SCREEN_COMPATIBILITY,
4030                 "setPackageScreenCompatMode");
4031         synchronized (this) {
4032             mCompatModePackages.setPackageScreenCompatModeLocked(packageName, mode);
4033         }
4034     }
4035
4036     @Override
4037     public boolean getPackageAskScreenCompat(String packageName) {
4038         enforceNotIsolatedCaller("getPackageAskScreenCompat");
4039         synchronized (this) {
4040             return mCompatModePackages.getPackageAskCompatModeLocked(packageName);
4041         }
4042     }
4043
4044     @Override
4045     public void setPackageAskScreenCompat(String packageName, boolean ask) {
4046         enforceCallingPermission(android.Manifest.permission.SET_SCREEN_COMPATIBILITY,
4047                 "setPackageAskScreenCompat");
4048         synchronized (this) {
4049             mCompatModePackages.setPackageAskCompatModeLocked(packageName, ask);
4050         }
4051     }
4052
4053     private boolean hasUsageStatsPermission(String callingPackage) {
4054         final int mode = mAppOpsService.checkOperation(AppOpsManager.OP_GET_USAGE_STATS,
4055                 Binder.getCallingUid(), callingPackage);
4056         if (mode == AppOpsManager.MODE_DEFAULT) {
4057             return checkCallingPermission(Manifest.permission.PACKAGE_USAGE_STATS)
4058                     == PackageManager.PERMISSION_GRANTED;
4059         }
4060         return mode == AppOpsManager.MODE_ALLOWED;
4061     }
4062
4063     @Override
4064     public int getPackageProcessState(String packageName, String callingPackage) {
4065         if (!hasUsageStatsPermission(callingPackage)) {
4066             enforceCallingPermission(android.Manifest.permission.GET_PACKAGE_IMPORTANCE,
4067                     "getPackageProcessState");
4068         }
4069
4070         int procState = ActivityManager.PROCESS_STATE_NONEXISTENT;
4071         synchronized (this) {
4072             for (int i=mLruProcesses.size()-1; i>=0; i--) {
4073                 final ProcessRecord proc = mLruProcesses.get(i);
4074                 if (procState == ActivityManager.PROCESS_STATE_NONEXISTENT
4075                         || procState > proc.setProcState) {
4076                     boolean found = false;
4077                     for (int j=proc.pkgList.size()-1; j>=0 && !found; j--) {
4078                         if (proc.pkgList.keyAt(j).equals(packageName)) {
4079                             procState = proc.setProcState;
4080                             found = true;
4081                         }
4082                     }
4083                     if (proc.pkgDeps != null && !found) {
4084                         for (int j=proc.pkgDeps.size()-1; j>=0; j--) {
4085                             if (proc.pkgDeps.valueAt(j).equals(packageName)) {
4086                                 procState = proc.setProcState;
4087                                 break;
4088                             }
4089                         }
4090                     }
4091                 }
4092             }
4093         }
4094         return procState;
4095     }
4096
4097     @Override
4098     public boolean setProcessMemoryTrimLevel(String process, int userId, int level) {
4099         synchronized (this) {
4100             final ProcessRecord app = findProcessLocked(process, userId, "setProcessMemoryTrimLevel");
4101             if (app == null) {
4102                 return false;
4103             }
4104             if (app.trimMemoryLevel < level && app.thread != null &&
4105                     (level < ComponentCallbacks2.TRIM_MEMORY_UI_HIDDEN ||
4106                             app.curProcState >= ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND)) {
4107                 try {
4108                     app.thread.scheduleTrimMemory(level);
4109                     app.trimMemoryLevel = level;
4110                     return true;
4111                 } catch (RemoteException e) {
4112                     // Fallthrough to failure case.
4113                 }
4114             }
4115         }
4116         return false;
4117     }
4118
4119     private void dispatchProcessesChanged() {
4120         int N;
4121         synchronized (this) {
4122             N = mPendingProcessChanges.size();
4123             if (mActiveProcessChanges.length < N) {
4124                 mActiveProcessChanges = new ProcessChangeItem[N];
4125             }
4126             mPendingProcessChanges.toArray(mActiveProcessChanges);
4127             mPendingProcessChanges.clear();
4128             if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG_PROCESS_OBSERVERS,
4129                     "*** Delivering " + N + " process changes");
4130         }
4131
4132         int i = mProcessObservers.beginBroadcast();
4133         while (i > 0) {
4134             i--;
4135             final IProcessObserver observer = mProcessObservers.getBroadcastItem(i);
4136             if (observer != null) {
4137                 try {
4138                     for (int j=0; j<N; j++) {
4139                         ProcessChangeItem item = mActiveProcessChanges[j];
4140                         if ((item.changes&ProcessChangeItem.CHANGE_ACTIVITIES) != 0) {
4141                             if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG_PROCESS_OBSERVERS,
4142                                     "ACTIVITIES CHANGED pid=" + item.pid + " uid="
4143                                     + item.uid + ": " + item.foregroundActivities);
4144                             observer.onForegroundActivitiesChanged(item.pid, item.uid,
4145                                     item.foregroundActivities);
4146                         }
4147                         if ((item.changes&ProcessChangeItem.CHANGE_PROCESS_STATE) != 0) {
4148                             if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG_PROCESS_OBSERVERS,
4149                                     "PROCSTATE CHANGED pid=" + item.pid + " uid=" + item.uid
4150                                     + ": " + item.processState);
4151                             observer.onProcessStateChanged(item.pid, item.uid, item.processState);
4152                         }
4153                     }
4154                 } catch (RemoteException e) {
4155                 }
4156             }
4157         }
4158         mProcessObservers.finishBroadcast();
4159
4160         synchronized (this) {
4161             for (int j=0; j<N; j++) {
4162                 mAvailProcessChanges.add(mActiveProcessChanges[j]);
4163             }
4164         }
4165     }
4166
4167     private void dispatchProcessDied(int pid, int uid) {
4168         int i = mProcessObservers.beginBroadcast();
4169         while (i > 0) {
4170             i--;
4171             final IProcessObserver observer = mProcessObservers.getBroadcastItem(i);
4172             if (observer != null) {
4173                 try {
4174                     observer.onProcessDied(pid, uid);
4175                 } catch (RemoteException e) {
4176                 }
4177             }
4178         }
4179         mProcessObservers.finishBroadcast();
4180     }
4181
4182     private void dispatchUidsChanged() {
4183         int N;
4184         synchronized (this) {
4185             N = mPendingUidChanges.size();
4186             if (mActiveUidChanges.length < N) {
4187                 mActiveUidChanges = new UidRecord.ChangeItem[N];
4188             }
4189             for (int i=0; i<N; i++) {
4190                 final UidRecord.ChangeItem change = mPendingUidChanges.get(i);
4191                 mActiveUidChanges[i] = change;
4192                 if (change.uidRecord != null) {
4193                     change.uidRecord.pendingChange = null;
4194                     change.uidRecord = null;
4195                 }
4196             }
4197             mPendingUidChanges.clear();
4198             if (DEBUG_UID_OBSERVERS) Slog.i(TAG_UID_OBSERVERS,
4199                     "*** Delivering " + N + " uid changes");
4200         }
4201
4202         if (mLocalPowerManager != null) {
4203             for (int j=0; j<N; j++) {
4204                 UidRecord.ChangeItem item = mActiveUidChanges[j];
4205                 if (item.change == UidRecord.CHANGE_GONE
4206                         || item.change == UidRecord.CHANGE_GONE_IDLE) {
4207                     mLocalPowerManager.uidGone(item.uid);
4208                 } else {
4209                     mLocalPowerManager.updateUidProcState(item.uid, item.processState);
4210                 }
4211             }
4212         }
4213
4214         int i = mUidObservers.beginBroadcast();
4215         while (i > 0) {
4216             i--;
4217             final IUidObserver observer = mUidObservers.getBroadcastItem(i);
4218             final int which = (Integer)mUidObservers.getBroadcastCookie(i);
4219             if (observer != null) {
4220                 try {
4221                     for (int j=0; j<N; j++) {
4222                         UidRecord.ChangeItem item = mActiveUidChanges[j];
4223                         final int change = item.change;
4224                         UidRecord validateUid = null;
4225                         if (VALIDATE_UID_STATES && i == 0) {
4226                             validateUid = mValidateUids.get(item.uid);
4227                             if (validateUid == null && change != UidRecord.CHANGE_GONE
4228                                     && change != UidRecord.CHANGE_GONE_IDLE) {
4229                                 validateUid = new UidRecord(item.uid);
4230                                 mValidateUids.put(item.uid, validateUid);
4231                             }
4232                         }
4233                         if (change == UidRecord.CHANGE_IDLE
4234                                 || change == UidRecord.CHANGE_GONE_IDLE) {
4235                             if ((which & ActivityManager.UID_OBSERVER_IDLE) != 0) {
4236                                 if (DEBUG_UID_OBSERVERS) Slog.i(TAG_UID_OBSERVERS,
4237                                         "UID idle uid=" + item.uid);
4238                                 observer.onUidIdle(item.uid);
4239                             }
4240                             if (VALIDATE_UID_STATES && i == 0) {
4241                                 if (validateUid != null) {
4242                                     validateUid.idle = true;
4243                                 }
4244                             }
4245                         } else if (change == UidRecord.CHANGE_ACTIVE) {
4246                             if ((which & ActivityManager.UID_OBSERVER_ACTIVE) != 0) {
4247                                 if (DEBUG_UID_OBSERVERS) Slog.i(TAG_UID_OBSERVERS,
4248                                         "UID active uid=" + item.uid);
4249                                 observer.onUidActive(item.uid);
4250                             }
4251                             if (VALIDATE_UID_STATES && i == 0) {
4252                                 validateUid.idle = false;
4253                             }
4254                         }
4255                         if (change == UidRecord.CHANGE_GONE
4256                                 || change == UidRecord.CHANGE_GONE_IDLE) {
4257                             if ((which & ActivityManager.UID_OBSERVER_GONE) != 0) {
4258                                 if (DEBUG_UID_OBSERVERS) Slog.i(TAG_UID_OBSERVERS,
4259                                         "UID gone uid=" + item.uid);
4260                                 observer.onUidGone(item.uid);
4261                             }
4262                             if (VALIDATE_UID_STATES && i == 0) {
4263                                 if (validateUid != null) {
4264                                     mValidateUids.remove(item.uid);
4265                                 }
4266                             }
4267                         } else {
4268                             if ((which & ActivityManager.UID_OBSERVER_PROCSTATE) != 0) {
4269                                 if (DEBUG_UID_OBSERVERS) Slog.i(TAG_UID_OBSERVERS,
4270                                         "UID CHANGED uid=" + item.uid
4271                                                 + ": " + item.processState);
4272                                 observer.onUidStateChanged(item.uid, item.processState);
4273                             }
4274                             if (VALIDATE_UID_STATES && i == 0) {
4275                                 validateUid.curProcState = validateUid.setProcState
4276                                         = item.processState;
4277                             }
4278                         }
4279                     }
4280                 } catch (RemoteException e) {
4281                 }
4282             }
4283         }
4284         mUidObservers.finishBroadcast();
4285
4286         synchronized (this) {
4287             for (int j=0; j<N; j++) {
4288                 mAvailUidChanges.add(mActiveUidChanges[j]);
4289             }
4290         }
4291     }
4292
4293     @Override
4294     public final int startActivity(IApplicationThread caller, String callingPackage,
4295             Intent intent, String resolvedType, IBinder resultTo, String resultWho, int requestCode,
4296             int startFlags, ProfilerInfo profilerInfo, Bundle bOptions) {
4297         return startActivityAsUser(caller, callingPackage, intent, resolvedType, resultTo,
4298                 resultWho, requestCode, startFlags, profilerInfo, bOptions,
4299                 UserHandle.getCallingUserId());
4300     }
4301
4302     final int startActivity(Intent intent, ActivityStackSupervisor.ActivityContainer container) {
4303         enforceNotIsolatedCaller("ActivityContainer.startActivity");
4304         final int userId = mUserController.handleIncomingUser(Binder.getCallingPid(),
4305                 Binder.getCallingUid(), mStackSupervisor.mCurrentUser, false,
4306                 ActivityManagerService.ALLOW_FULL_ONLY, "ActivityContainer", null);
4307
4308         // TODO: Switch to user app stacks here.
4309         String mimeType = intent.getType();
4310         final Uri data = intent.getData();
4311         if (mimeType == null && data != null && "content".equals(data.getScheme())) {
4312             mimeType = getProviderMimeType(data, userId);
4313         }
4314         container.checkEmbeddedAllowedInner(userId, intent, mimeType);
4315
4316         intent.addFlags(FORCE_NEW_TASK_FLAGS);
4317         return mActivityStarter.startActivityMayWait(null, -1, null, intent, mimeType, null, null, null,
4318                 null, 0, 0, null, null, null, null, false, userId, container, null);
4319     }
4320
4321     @Override
4322     public final int startActivityAsUser(IApplicationThread caller, String callingPackage,
4323             Intent intent, String resolvedType, IBinder resultTo, String resultWho, int requestCode,
4324             int startFlags, ProfilerInfo profilerInfo, Bundle bOptions, int userId) {
4325         enforceNotIsolatedCaller("startActivity");
4326         userId = mUserController.handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(),
4327                 userId, false, ALLOW_FULL_ONLY, "startActivity", null);
4328         // TODO: Switch to user app stacks here.
4329         return mActivityStarter.startActivityMayWait(caller, -1, callingPackage, intent,
4330                 resolvedType, null, null, resultTo, resultWho, requestCode, startFlags,
4331                 profilerInfo, null, null, bOptions, false, userId, null, null);
4332     }
4333
4334     @Override
4335     public final int startActivityAsCaller(IApplicationThread caller, String callingPackage,
4336             Intent intent, String resolvedType, IBinder resultTo, String resultWho, int requestCode,
4337             int startFlags, ProfilerInfo profilerInfo, Bundle bOptions, boolean ignoreTargetSecurity,
4338             int userId) {
4339
4340         // This is very dangerous -- it allows you to perform a start activity (including
4341         // permission grants) as any app that may launch one of your own activities.  So
4342         // we will only allow this to be done from activities that are part of the core framework,
4343         // and then only when they are running as the system.
4344         final ActivityRecord sourceRecord;
4345         final int targetUid;
4346         final String targetPackage;
4347         synchronized (this) {
4348             if (resultTo == null) {
4349                 throw new SecurityException("Must be called from an activity");
4350             }
4351             sourceRecord = mStackSupervisor.isInAnyStackLocked(resultTo);
4352             if (sourceRecord == null) {
4353                 throw new SecurityException("Called with bad activity token: " + resultTo);
4354             }
4355             if (!sourceRecord.info.packageName.equals("android")) {
4356                 throw new SecurityException(
4357                         "Must be called from an activity that is declared in the android package");
4358             }
4359             if (sourceRecord.app == null) {
4360                 throw new SecurityException("Called without a process attached to activity");
4361             }
4362             if (UserHandle.getAppId(sourceRecord.app.uid) != Process.SYSTEM_UID) {
4363                 // This is still okay, as long as this activity is running under the
4364                 // uid of the original calling activity.
4365                 if (sourceRecord.app.uid != sourceRecord.launchedFromUid) {
4366                     throw new SecurityException(
4367                             "Calling activity in uid " + sourceRecord.app.uid
4368                                     + " must be system uid or original calling uid "
4369                                     + sourceRecord.launchedFromUid);
4370                 }
4371             }
4372             if (ignoreTargetSecurity) {
4373                 if (intent.getComponent() == null) {
4374                     throw new SecurityException(
4375                             "Component must be specified with ignoreTargetSecurity");
4376                 }
4377                 if (intent.getSelector() != null) {
4378                     throw new SecurityException(
4379                             "Selector not allowed with ignoreTargetSecurity");
4380                 }
4381             }
4382             targetUid = sourceRecord.launchedFromUid;
4383             targetPackage = sourceRecord.launchedFromPackage;
4384         }
4385
4386         if (userId == UserHandle.USER_NULL) {
4387             userId = UserHandle.getUserId(sourceRecord.app.uid);
4388         }
4389
4390         // TODO: Switch to user app stacks here.
4391         try {
4392             int ret = mActivityStarter.startActivityMayWait(null, targetUid, targetPackage, intent,
4393                     resolvedType, null, null, resultTo, resultWho, requestCode, startFlags, null,
4394                     null, null, bOptions, ignoreTargetSecurity, userId, null, null);
4395             return ret;
4396         } catch (SecurityException e) {
4397             // XXX need to figure out how to propagate to original app.
4398             // A SecurityException here is generally actually a fault of the original
4399             // calling activity (such as a fairly granting permissions), so propagate it
4400             // back to them.
4401             /*
4402             StringBuilder msg = new StringBuilder();
4403             msg.append("While launching");
4404             msg.append(intent.toString());
4405             msg.append(": ");
4406             msg.append(e.getMessage());
4407             */
4408             throw e;
4409         }
4410     }
4411
4412     @Override
4413     public final WaitResult startActivityAndWait(IApplicationThread caller, String callingPackage,
4414             Intent intent, String resolvedType, IBinder resultTo, String resultWho, int requestCode,
4415             int startFlags, ProfilerInfo profilerInfo, Bundle bOptions, int userId) {
4416         enforceNotIsolatedCaller("startActivityAndWait");
4417         userId = mUserController.handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(),
4418                 userId, false, ALLOW_FULL_ONLY, "startActivityAndWait", null);
4419         WaitResult res = new WaitResult();
4420         // TODO: Switch to user app stacks here.
4421         mActivityStarter.startActivityMayWait(caller, -1, callingPackage, intent, resolvedType,
4422                 null, null, resultTo, resultWho, requestCode, startFlags, profilerInfo, res, null,
4423                 bOptions, false, userId, null, null);
4424         return res;
4425     }
4426
4427     @Override
4428     public final int startActivityWithConfig(IApplicationThread caller, String callingPackage,
4429             Intent intent, String resolvedType, IBinder resultTo, String resultWho, int requestCode,
4430             int startFlags, Configuration config, Bundle bOptions, int userId) {
4431         enforceNotIsolatedCaller("startActivityWithConfig");
4432         userId = mUserController.handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(),
4433                 userId, false, ALLOW_FULL_ONLY, "startActivityWithConfig", null);
4434         // TODO: Switch to user app stacks here.
4435         int ret = mActivityStarter.startActivityMayWait(caller, -1, callingPackage, intent,
4436                 resolvedType, null, null, resultTo, resultWho, requestCode, startFlags,
4437                 null, null, config, bOptions, false, userId, null, null);
4438         return ret;
4439     }
4440
4441     @Override
4442     public int startActivityIntentSender(IApplicationThread caller, IntentSender intent,
4443             Intent fillInIntent, String resolvedType, IBinder resultTo, String resultWho,
4444             int requestCode, int flagsMask, int flagsValues, Bundle bOptions)
4445             throws TransactionTooLargeException {
4446         enforceNotIsolatedCaller("startActivityIntentSender");
4447         // Refuse possible leaked file descriptors
4448         if (fillInIntent != null && fillInIntent.hasFileDescriptors()) {
4449             throw new IllegalArgumentException("File descriptors passed in Intent");
4450         }
4451
4452         IIntentSender sender = intent.getTarget();
4453         if (!(sender instanceof PendingIntentRecord)) {
4454             throw new IllegalArgumentException("Bad PendingIntent object");
4455         }
4456
4457         PendingIntentRecord pir = (PendingIntentRecord)sender;
4458
4459         synchronized (this) {
4460             // If this is coming from the currently resumed activity, it is
4461             // effectively saying that app switches are allowed at this point.
4462             final ActivityStack stack = getFocusedStack();
4463             if (stack.mResumedActivity != null &&
4464                     stack.mResumedActivity.info.applicationInfo.uid == Binder.getCallingUid()) {
4465                 mAppSwitchesAllowedTime = 0;
4466             }
4467         }
4468         int ret = pir.sendInner(0, fillInIntent, resolvedType, null, null,
4469                 resultTo, resultWho, requestCode, flagsMask, flagsValues, bOptions, null);
4470         return ret;
4471     }
4472
4473     @Override
4474     public int startVoiceActivity(String callingPackage, int callingPid, int callingUid,
4475             Intent intent, String resolvedType, IVoiceInteractionSession session,
4476             IVoiceInteractor interactor, int startFlags, ProfilerInfo profilerInfo,
4477             Bundle bOptions, int userId) {
4478         if (checkCallingPermission(Manifest.permission.BIND_VOICE_INTERACTION)
4479                 != PackageManager.PERMISSION_GRANTED) {
4480             String msg = "Permission Denial: startVoiceActivity() from pid="
4481                     + Binder.getCallingPid()
4482                     + ", uid=" + Binder.getCallingUid()
4483                     + " requires " + android.Manifest.permission.BIND_VOICE_INTERACTION;
4484             Slog.w(TAG, msg);
4485             throw new SecurityException(msg);
4486         }
4487         if (session == null || interactor == null) {
4488             throw new NullPointerException("null session or interactor");
4489         }
4490         userId = mUserController.handleIncomingUser(callingPid, callingUid, userId, false,
4491                 ALLOW_FULL_ONLY, "startVoiceActivity", null);
4492         // TODO: Switch to user app stacks here.
4493         return mActivityStarter.startActivityMayWait(null, callingUid, callingPackage, intent,
4494                 resolvedType, session, interactor, null, null, 0, startFlags, profilerInfo, null,
4495                 null, bOptions, false, userId, null, null);
4496     }
4497
4498     @Override
4499     public void startLocalVoiceInteraction(IBinder callingActivity, Bundle options)
4500             throws RemoteException {
4501         Slog.i(TAG, "Activity tried to startVoiceInteraction");
4502         synchronized (this) {
4503             ActivityRecord activity = getFocusedStack().topActivity();
4504             if (ActivityRecord.forTokenLocked(callingActivity) != activity) {
4505                 throw new SecurityException("Only focused activity can call startVoiceInteraction");
4506             }
4507             if (mRunningVoice != null || activity.task.voiceSession != null
4508                     || activity.voiceSession != null) {
4509                 Slog.w(TAG, "Already in a voice interaction, cannot start new voice interaction");
4510                 return;
4511             }
4512             if (activity.pendingVoiceInteractionStart) {
4513                 Slog.w(TAG, "Pending start of voice interaction already.");
4514                 return;
4515             }
4516             activity.pendingVoiceInteractionStart = true;
4517         }
4518         LocalServices.getService(VoiceInteractionManagerInternal.class)
4519                 .startLocalVoiceInteraction(callingActivity, options);
4520     }
4521
4522     @Override
4523     public void stopLocalVoiceInteraction(IBinder callingActivity) throws RemoteException {
4524         LocalServices.getService(VoiceInteractionManagerInternal.class)
4525                 .stopLocalVoiceInteraction(callingActivity);
4526     }
4527
4528     @Override
4529     public boolean supportsLocalVoiceInteraction() throws RemoteException {
4530         return LocalServices.getService(VoiceInteractionManagerInternal.class)
4531                 .supportsLocalVoiceInteraction();
4532     }
4533
4534     void onLocalVoiceInteractionStartedLocked(IBinder activity,
4535             IVoiceInteractionSession voiceSession, IVoiceInteractor voiceInteractor) {
4536         ActivityRecord activityToCallback = ActivityRecord.forTokenLocked(activity);
4537         if (activityToCallback == null) return;
4538         activityToCallback.setVoiceSessionLocked(voiceSession);
4539
4540         // Inform the activity
4541         try {
4542             activityToCallback.app.thread.scheduleLocalVoiceInteractionStarted(activity,
4543                     voiceInteractor);
4544             long token = Binder.clearCallingIdentity();
4545             try {
4546                 startRunningVoiceLocked(voiceSession, activityToCallback.appInfo.uid);
4547             } finally {
4548                 Binder.restoreCallingIdentity(token);
4549             }
4550             // TODO: VI Should we cache the activity so that it's easier to find later
4551             // rather than scan through all the stacks and activities?
4552         } catch (RemoteException re) {
4553             activityToCallback.clearVoiceSessionLocked();
4554             // TODO: VI Should this terminate the voice session?
4555         }
4556     }
4557
4558     @Override
4559     public void setVoiceKeepAwake(IVoiceInteractionSession session, boolean keepAwake) {
4560         synchronized (this) {
4561             if (mRunningVoice != null && mRunningVoice.asBinder() == session.asBinder()) {
4562                 if (keepAwake) {
4563                     mVoiceWakeLock.acquire();
4564                 } else {
4565                     mVoiceWakeLock.release();
4566                 }
4567             }
4568         }
4569     }
4570
4571     @Override
4572     public boolean startNextMatchingActivity(IBinder callingActivity,
4573             Intent intent, Bundle bOptions) {
4574         // Refuse possible leaked file descriptors
4575         if (intent != null && intent.hasFileDescriptors() == true) {
4576             throw new IllegalArgumentException("File descriptors passed in Intent");
4577         }
4578         ActivityOptions options = ActivityOptions.fromBundle(bOptions);
4579
4580         synchronized (this) {
4581             final ActivityRecord r = ActivityRecord.isInStackLocked(callingActivity);
4582             if (r == null) {
4583                 ActivityOptions.abort(options);
4584                 return false;
4585             }
4586             if (r.app == null || r.app.thread == null) {
4587                 // The caller is not running...  d'oh!
4588                 ActivityOptions.abort(options);
4589                 return false;
4590             }
4591             intent = new Intent(intent);
4592             // The caller is not allowed to change the data.
4593             intent.setDataAndType(r.intent.getData(), r.intent.getType());
4594             // And we are resetting to find the next component...
4595             intent.setComponent(null);
4596
4597             final boolean debug = ((intent.getFlags() & Intent.FLAG_DEBUG_LOG_RESOLUTION) != 0);
4598
4599             ActivityInfo aInfo = null;
4600             try {
4601                 List<ResolveInfo> resolves =
4602                     AppGlobals.getPackageManager().queryIntentActivities(
4603                             intent, r.resolvedType,
4604                             PackageManager.MATCH_DEFAULT_ONLY | STOCK_PM_FLAGS,
4605                             UserHandle.getCallingUserId()).getList();
4606
4607                 // Look for the original activity in the list...
4608                 final int N = resolves != null ? resolves.size() : 0;
4609                 for (int i=0; i<N; i++) {
4610                     ResolveInfo rInfo = resolves.get(i);
4611                     if (rInfo.activityInfo.packageName.equals(r.packageName)
4612                             && rInfo.activityInfo.name.equals(r.info.name)) {
4613                         // We found the current one...  the next matching is
4614                         // after it.
4615                         i++;
4616                         if (i<N) {
4617                             aInfo = resolves.get(i).activityInfo;
4618                         }
4619                         if (debug) {
4620                             Slog.v(TAG, "Next matching activity: found current " + r.packageName
4621                                     + "/" + r.info.name);
4622                             Slog.v(TAG, "Next matching activity: next is " + ((aInfo == null)
4623                                     ? "null" : aInfo.packageName + "/" + aInfo.name));
4624                         }
4625                         break;
4626                     }
4627                 }
4628             } catch (RemoteException e) {
4629             }
4630
4631             if (aInfo == null) {
4632                 // Nobody who is next!
4633                 ActivityOptions.abort(options);
4634                 if (debug) Slog.d(TAG, "Next matching activity: nothing found");
4635                 return false;
4636             }
4637
4638             intent.setComponent(new ComponentName(
4639                     aInfo.applicationInfo.packageName, aInfo.name));
4640             intent.setFlags(intent.getFlags()&~(
4641                     Intent.FLAG_ACTIVITY_FORWARD_RESULT|
4642                     Intent.FLAG_ACTIVITY_CLEAR_TOP|
4643                     Intent.FLAG_ACTIVITY_MULTIPLE_TASK|
4644                     Intent.FLAG_ACTIVITY_NEW_TASK));
4645
4646             // Okay now we need to start the new activity, replacing the
4647             // currently running activity.  This is a little tricky because
4648             // we want to start the new one as if the current one is finished,
4649             // but not finish the current one first so that there is no flicker.
4650             // And thus...
4651             final boolean wasFinishing = r.finishing;
4652             r.finishing = true;
4653
4654             // Propagate reply information over to the new activity.
4655             final ActivityRecord resultTo = r.resultTo;
4656             final String resultWho = r.resultWho;
4657             final int requestCode = r.requestCode;
4658             r.resultTo = null;
4659             if (resultTo != null) {
4660                 resultTo.removeResultsLocked(r, resultWho, requestCode);
4661             }
4662
4663             final long origId = Binder.clearCallingIdentity();
4664             int res = mActivityStarter.startActivityLocked(r.app.thread, intent,
4665                     null /*ephemeralIntent*/, r.resolvedType, aInfo, null /*rInfo*/, null,
4666                     null, resultTo != null ? resultTo.appToken : null, resultWho, requestCode, -1,
4667                     r.launchedFromUid, r.launchedFromPackage, -1, r.launchedFromUid, 0, options,
4668                     false, false, null, null, null);
4669             Binder.restoreCallingIdentity(origId);
4670
4671             r.finishing = wasFinishing;
4672             if (res != ActivityManager.START_SUCCESS) {
4673                 return false;
4674             }
4675             return true;
4676         }
4677     }
4678
4679     @Override
4680     public final int startActivityFromRecents(int taskId, Bundle bOptions) {
4681         if (checkCallingPermission(START_TASKS_FROM_RECENTS) != PackageManager.PERMISSION_GRANTED) {
4682             String msg = "Permission Denial: startActivityFromRecents called without " +
4683                     START_TASKS_FROM_RECENTS;
4684             Slog.w(TAG, msg);
4685             throw new SecurityException(msg);
4686         }
4687         final long origId = Binder.clearCallingIdentity();
4688         try {
4689             synchronized (this) {
4690                 return mStackSupervisor.startActivityFromRecentsInner(taskId, bOptions);
4691             }
4692         } finally {
4693             Binder.restoreCallingIdentity(origId);
4694         }
4695     }
4696
4697     final int startActivityInPackage(int uid, String callingPackage,
4698             Intent intent, String resolvedType, IBinder resultTo,
4699             String resultWho, int requestCode, int startFlags, Bundle bOptions, int userId,
4700             IActivityContainer container, TaskRecord inTask) {
4701
4702         userId = mUserController.handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(),
4703                 userId, false, ALLOW_FULL_ONLY, "startActivityInPackage", null);
4704
4705         // TODO: Switch to user app stacks here.
4706         int ret = mActivityStarter.startActivityMayWait(null, uid, callingPackage, intent,
4707                 resolvedType, null, null, resultTo, resultWho, requestCode, startFlags,
4708                 null, null, null, bOptions, false, userId, container, inTask);
4709         return ret;
4710     }
4711
4712     @Override
4713     public final int startActivities(IApplicationThread caller, String callingPackage,
4714             Intent[] intents, String[] resolvedTypes, IBinder resultTo, Bundle bOptions,
4715             int userId) {
4716         enforceNotIsolatedCaller("startActivities");
4717         userId = mUserController.handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(),
4718                 userId, false, ALLOW_FULL_ONLY, "startActivity", null);
4719         // TODO: Switch to user app stacks here.
4720         int ret = mActivityStarter.startActivities(caller, -1, callingPackage, intents,
4721                 resolvedTypes, resultTo, bOptions, userId);
4722         return ret;
4723     }
4724
4725     final int startActivitiesInPackage(int uid, String callingPackage,
4726             Intent[] intents, String[] resolvedTypes, IBinder resultTo,
4727             Bundle bOptions, int userId) {
4728
4729         userId = mUserController.handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(),
4730                 userId, false, ALLOW_FULL_ONLY, "startActivityInPackage", null);
4731         // TODO: Switch to user app stacks here.
4732         int ret = mActivityStarter.startActivities(null, uid, callingPackage, intents, resolvedTypes,
4733                 resultTo, bOptions, userId);
4734         return ret;
4735     }
4736
4737     @Override
4738     public void reportActivityFullyDrawn(IBinder token) {
4739         synchronized (this) {
4740             ActivityRecord r = ActivityRecord.isInStackLocked(token);
4741             if (r == null) {
4742                 return;
4743             }
4744             r.reportFullyDrawnLocked();
4745         }
4746     }
4747
4748     @Override
4749     public void setRequestedOrientation(IBinder token, int requestedOrientation) {
4750         synchronized (this) {
4751             ActivityRecord r = ActivityRecord.isInStackLocked(token);
4752             if (r == null) {
4753                 return;
4754             }
4755             TaskRecord task = r.task;
4756             if (task != null && (!task.mFullscreen || !task.stack.mFullscreen)) {
4757                 // Fixed screen orientation isn't supported when activities aren't in full screen
4758                 // mode.
4759                 return;
4760             }
4761             final long origId = Binder.clearCallingIdentity();
4762             mWindowManager.setAppOrientation(r.appToken, requestedOrientation);
4763             Configuration config = mWindowManager.updateOrientationFromAppTokens(
4764                     mConfiguration, r.mayFreezeScreenLocked(r.app) ? r.appToken : null);
4765             if (config != null) {
4766                 r.frozenBeforeDestroy = true;
4767                 if (!updateConfigurationLocked(config, r, false)) {
4768                     mStackSupervisor.resumeFocusedStackTopActivityLocked();
4769                 }
4770             }
4771             Binder.restoreCallingIdentity(origId);
4772         }
4773     }
4774
4775     @Override
4776     public int getRequestedOrientation(IBinder token) {
4777         synchronized (this) {
4778             ActivityRecord r = ActivityRecord.isInStackLocked(token);
4779             if (r == null) {
4780                 return ActivityInfo.SCREEN_ORIENTATION_UNSPECIFIED;
4781             }
4782             return mWindowManager.getAppOrientation(r.appToken);
4783         }
4784     }
4785
4786     /**
4787      * This is the internal entry point for handling Activity.finish().
4788      *
4789      * @param token The Binder token referencing the Activity we want to finish.
4790      * @param resultCode Result code, if any, from this Activity.
4791      * @param resultData Result data (Intent), if any, from this Activity.
4792      * @param finishTask Whether to finish the task associated with this Activity.
4793      *
4794      * @return Returns true if the activity successfully finished, or false if it is still running.
4795      */
4796     @Override
4797     public final boolean finishActivity(IBinder token, int resultCode, Intent resultData,
4798             int finishTask) {
4799         // Refuse possible leaked file descriptors
4800         if (resultData != null && resultData.hasFileDescriptors() == true) {
4801             throw new IllegalArgumentException("File descriptors passed in Intent");
4802         }
4803
4804         synchronized(this) {
4805             ActivityRecord r = ActivityRecord.isInStackLocked(token);
4806             if (r == null) {
4807                 return true;
4808             }
4809             // Keep track of the root activity of the task before we finish it
4810             TaskRecord tr = r.task;
4811             ActivityRecord rootR = tr.getRootActivity();
4812             if (rootR == null) {
4813                 Slog.w(TAG, "Finishing task with all activities already finished");
4814             }
4815             // Do not allow task to finish if last task in lockTask mode. Launchable priv-apps can
4816             // finish.
4817             if (tr.mLockTaskAuth != LOCK_TASK_AUTH_LAUNCHABLE_PRIV && rootR == r &&
4818                     mStackSupervisor.isLastLockedTask(tr)) {
4819                 Slog.i(TAG, "Not finishing task in lock task mode");
4820                 mStackSupervisor.showLockTaskToast();
4821                 return false;
4822             }
4823             if (mController != null) {
4824                 // Find the first activity that is not finishing.
4825                 ActivityRecord next = r.task.stack.topRunningActivityLocked(token, 0);
4826                 if (next != null) {
4827                     // ask watcher if this is allowed
4828                     boolean resumeOK = true;
4829                     try {
4830                         resumeOK = mController.activityResuming(next.packageName);
4831                     } catch (RemoteException e) {
4832                         mController = null;
4833                         Watchdog.getInstance().setActivityController(null);
4834                     }
4835
4836                     if (!resumeOK) {
4837                         Slog.i(TAG, "Not finishing activity because controller resumed");
4838                         return false;
4839                     }
4840                 }
4841             }
4842             final long origId = Binder.clearCallingIdentity();
4843             try {
4844                 boolean res;
4845                 final boolean finishWithRootActivity =
4846                         finishTask == Activity.FINISH_TASK_WITH_ROOT_ACTIVITY;
4847                 if (finishTask == Activity.FINISH_TASK_WITH_ACTIVITY
4848                         || (finishWithRootActivity && r == rootR)) {
4849                     // If requested, remove the task that is associated to this activity only if it
4850                     // was the root activity in the task. The result code and data is ignored
4851                     // because we don't support returning them across task boundaries. Also, to
4852                     // keep backwards compatibility we remove the task from recents when finishing
4853                     // task with root activity.
4854                     res = removeTaskByIdLocked(tr.taskId, false, finishWithRootActivity);
4855                     if (!res) {
4856                         Slog.i(TAG, "Removing task failed to finish activity");
4857                     }
4858                 } else {
4859                     res = tr.stack.requestFinishActivityLocked(token, resultCode,
4860                             resultData, "app-request", true);
4861                     if (!res) {
4862                         Slog.i(TAG, "Failed to finish by app-request");
4863                     }
4864                 }
4865                 return res;
4866             } finally {
4867                 Binder.restoreCallingIdentity(origId);
4868             }
4869         }
4870     }
4871
4872     @Override
4873     public final void finishHeavyWeightApp() {
4874         if (checkCallingPermission(android.Manifest.permission.FORCE_STOP_PACKAGES)
4875                 != PackageManager.PERMISSION_GRANTED) {
4876             String msg = "Permission Denial: finishHeavyWeightApp() from pid="
4877                     + Binder.getCallingPid()
4878                     + ", uid=" + Binder.getCallingUid()
4879                     + " requires " + android.Manifest.permission.FORCE_STOP_PACKAGES;
4880             Slog.w(TAG, msg);
4881             throw new SecurityException(msg);
4882         }
4883
4884         synchronized(this) {
4885             if (mHeavyWeightProcess == null) {
4886                 return;
4887             }
4888
4889             ArrayList<ActivityRecord> activities = new ArrayList<>(mHeavyWeightProcess.activities);
4890             for (int i = 0; i < activities.size(); i++) {
4891                 ActivityRecord r = activities.get(i);
4892                 if (!r.finishing && r.isInStackLocked()) {
4893                     r.task.stack.finishActivityLocked(r, Activity.RESULT_CANCELED,
4894                             null, "finish-heavy", true);
4895                 }
4896             }
4897
4898             mHandler.sendMessage(mHandler.obtainMessage(CANCEL_HEAVY_NOTIFICATION_MSG,
4899                     mHeavyWeightProcess.userId, 0));
4900             mHeavyWeightProcess = null;
4901         }
4902     }
4903
4904     @Override
4905     public void crashApplication(int uid, int initialPid, String packageName,
4906             String message) {
4907         if (checkCallingPermission(android.Manifest.permission.FORCE_STOP_PACKAGES)
4908                 != PackageManager.PERMISSION_GRANTED) {
4909             String msg = "Permission Denial: crashApplication() from pid="
4910                     + Binder.getCallingPid()
4911                     + ", uid=" + Binder.getCallingUid()
4912                     + " requires " + android.Manifest.permission.FORCE_STOP_PACKAGES;
4913             Slog.w(TAG, msg);
4914             throw new SecurityException(msg);
4915         }
4916
4917         synchronized(this) {
4918             mAppErrors.scheduleAppCrashLocked(uid, initialPid, packageName, message);
4919         }
4920     }
4921
4922     @Override
4923     public final void finishSubActivity(IBinder token, String resultWho,
4924             int requestCode) {
4925         synchronized(this) {
4926             final long origId = Binder.clearCallingIdentity();
4927             ActivityRecord r = ActivityRecord.isInStackLocked(token);
4928             if (r != null) {
4929                 r.task.stack.finishSubActivityLocked(r, resultWho, requestCode);
4930             }
4931             Binder.restoreCallingIdentity(origId);
4932         }
4933     }
4934
4935     @Override
4936     public boolean finishActivityAffinity(IBinder token) {
4937         synchronized(this) {
4938             final long origId = Binder.clearCallingIdentity();
4939             try {
4940                 ActivityRecord r = ActivityRecord.isInStackLocked(token);
4941                 if (r == null) {
4942                     return false;
4943                 }
4944
4945                 // Do not allow task to finish if last task in lockTask mode. Launchable priv-apps
4946                 // can finish.
4947                 final TaskRecord task = r.task;
4948                 if (task.mLockTaskAuth != LOCK_TASK_AUTH_LAUNCHABLE_PRIV &&
4949                         mStackSupervisor.isLastLockedTask(task) && task.getRootActivity() == r) {
4950                     mStackSupervisor.showLockTaskToast();
4951                     return false;
4952                 }
4953                 return task.stack.finishActivityAffinityLocked(r);
4954             } finally {
4955                 Binder.restoreCallingIdentity(origId);
4956             }
4957         }
4958     }
4959
4960     @Override
4961     public void finishVoiceTask(IVoiceInteractionSession session) {
4962         synchronized (this) {
4963             final long origId = Binder.clearCallingIdentity();
4964             try {
4965                 // TODO: VI Consider treating local voice interactions and voice tasks
4966                 // differently here
4967                 mStackSupervisor.finishVoiceTask(session);
4968             } finally {
4969                 Binder.restoreCallingIdentity(origId);
4970             }
4971         }
4972
4973     }
4974
4975     @Override
4976     public boolean releaseActivityInstance(IBinder token) {
4977         synchronized(this) {
4978             final long origId = Binder.clearCallingIdentity();
4979             try {
4980                 ActivityRecord r = ActivityRecord.isInStackLocked(token);
4981                 if (r == null) {
4982                     return false;
4983                 }
4984                 return r.task.stack.safelyDestroyActivityLocked(r, "app-req");
4985             } finally {
4986                 Binder.restoreCallingIdentity(origId);
4987             }
4988         }
4989     }
4990
4991     @Override
4992     public void releaseSomeActivities(IApplicationThread appInt) {
4993         synchronized(this) {
4994             final long origId = Binder.clearCallingIdentity();
4995             try {
4996                 ProcessRecord app = getRecordForAppLocked(appInt);
4997                 mStackSupervisor.releaseSomeActivitiesLocked(app, "low-mem");
4998             } finally {
4999                 Binder.restoreCallingIdentity(origId);
5000             }
5001         }
5002     }
5003
5004     @Override
5005     public boolean willActivityBeVisible(IBinder token) {
5006         synchronized(this) {
5007             ActivityStack stack = ActivityRecord.getStackLocked(token);
5008             if (stack != null) {
5009                 return stack.willActivityBeVisibleLocked(token);
5010             }
5011             return false;
5012         }
5013     }
5014
5015     @Override
5016     public void overridePendingTransition(IBinder token, String packageName,
5017             int enterAnim, int exitAnim) {
5018         synchronized(this) {
5019             ActivityRecord self = ActivityRecord.isInStackLocked(token);
5020             if (self == null) {
5021                 return;
5022             }
5023
5024             final long origId = Binder.clearCallingIdentity();
5025
5026             if (self.state == ActivityState.RESUMED
5027                     || self.state == ActivityState.PAUSING) {
5028                 mWindowManager.overridePendingAppTransition(packageName,
5029                         enterAnim, exitAnim, null);
5030             }
5031
5032             Binder.restoreCallingIdentity(origId);
5033         }
5034     }
5035
5036     /**
5037      * Main function for removing an existing process from the activity manager
5038      * as a result of that process going away.  Clears out all connections
5039      * to the process.
5040      */
5041     private final void handleAppDiedLocked(ProcessRecord app,
5042             boolean restarting, boolean allowRestart) {
5043         int pid = app.pid;
5044         boolean kept = cleanUpApplicationRecordLocked(app, restarting, allowRestart, -1,
5045                 false /*replacingPid*/);
5046         if (!kept && !restarting) {
5047             removeLruProcessLocked(app);
5048             if (pid > 0) {
5049                 ProcessList.remove(pid);
5050             }
5051         }
5052
5053         if (mProfileProc == app) {
5054             clearProfilerLocked();
5055         }
5056
5057         // Remove this application's activities from active lists.
5058         boolean hasVisibleActivities = mStackSupervisor.handleAppDiedLocked(app);
5059
5060         app.activities.clear();
5061
5062         if (app.instrumentationClass != null) {
5063             Slog.w(TAG, "Crash of app " + app.processName
5064                   + " running instrumentation " + app.instrumentationClass);
5065             Bundle info = new Bundle();
5066             info.putString("shortMsg", "Process crashed.");
5067             finishInstrumentationLocked(app, Activity.RESULT_CANCELED, info);
5068         }
5069
5070         if (!restarting && hasVisibleActivities
5071                 && !mStackSupervisor.resumeFocusedStackTopActivityLocked()) {
5072             // If there was nothing to resume, and we are not already restarting this process, but
5073             // there is a visible activity that is hosted by the process...  then make sure all
5074             // visible activities are running, taking care of restarting this process.
5075             mStackSupervisor.ensureActivitiesVisibleLocked(null, 0, !PRESERVE_WINDOWS);
5076         }
5077     }
5078
5079     private final int getLRURecordIndexForAppLocked(IApplicationThread thread) {
5080         IBinder threadBinder = thread.asBinder();
5081         // Find the application record.
5082         for (int i=mLruProcesses.size()-1; i>=0; i--) {
5083             ProcessRecord rec = mLruProcesses.get(i);
5084             if (rec.thread != null && rec.thread.asBinder() == threadBinder) {
5085                 return i;
5086             }
5087         }
5088         return -1;
5089     }
5090
5091     final ProcessRecord getRecordForAppLocked(
5092             IApplicationThread thread) {
5093         if (thread == null) {
5094             return null;
5095         }
5096
5097         int appIndex = getLRURecordIndexForAppLocked(thread);
5098         return appIndex >= 0 ? mLruProcesses.get(appIndex) : null;
5099     }
5100
5101     final void doLowMemReportIfNeededLocked(ProcessRecord dyingProc) {
5102         // If there are no longer any background processes running,
5103         // and the app that died was not running instrumentation,
5104         // then tell everyone we are now low on memory.
5105         boolean haveBg = false;
5106         for (int i=mLruProcesses.size()-1; i>=0; i--) {
5107             ProcessRecord rec = mLruProcesses.get(i);
5108             if (rec.thread != null
5109                     && rec.setProcState >= ActivityManager.PROCESS_STATE_CACHED_ACTIVITY) {
5110                 haveBg = true;
5111                 break;
5112             }
5113         }
5114
5115         if (!haveBg) {
5116             boolean doReport = "1".equals(SystemProperties.get(SYSTEM_DEBUGGABLE, "0"));
5117             if (doReport) {
5118                 long now = SystemClock.uptimeMillis();
5119                 if (now < (mLastMemUsageReportTime+5*60*1000)) {
5120                     doReport = false;
5121                 } else {
5122                     mLastMemUsageReportTime = now;
5123                 }
5124             }
5125             final ArrayList<ProcessMemInfo> memInfos
5126                     = doReport ? new ArrayList<ProcessMemInfo>(mLruProcesses.size()) : null;
5127             EventLog.writeEvent(EventLogTags.AM_LOW_MEMORY, mLruProcesses.size());
5128             long now = SystemClock.uptimeMillis();
5129             for (int i=mLruProcesses.size()-1; i>=0; i--) {
5130                 ProcessRecord rec = mLruProcesses.get(i);
5131                 if (rec == dyingProc || rec.thread == null) {
5132                     continue;
5133                 }
5134                 if (doReport) {
5135                     memInfos.add(new ProcessMemInfo(rec.processName, rec.pid, rec.setAdj,
5136                             rec.setProcState, rec.adjType, rec.makeAdjReason()));
5137                 }
5138                 if ((rec.lastLowMemory+GC_MIN_INTERVAL) <= now) {
5139                     // The low memory report is overriding any current
5140                     // state for a GC request.  Make sure to do
5141                     // heavy/important/visible/foreground processes first.
5142                     if (rec.setAdj <= ProcessList.HEAVY_WEIGHT_APP_ADJ) {
5143                         rec.lastRequestedGc = 0;
5144                     } else {
5145                         rec.lastRequestedGc = rec.lastLowMemory;
5146                     }
5147                     rec.reportLowMemory = true;
5148                     rec.lastLowMemory = now;
5149                     mProcessesToGc.remove(rec);
5150                     addProcessToGcListLocked(rec);
5151                 }
5152             }
5153             if (doReport) {
5154                 Message msg = mHandler.obtainMessage(REPORT_MEM_USAGE_MSG, memInfos);
5155                 mHandler.sendMessage(msg);
5156             }
5157             scheduleAppGcsLocked();
5158         }
5159     }
5160
5161     final void appDiedLocked(ProcessRecord app) {
5162        appDiedLocked(app, app.pid, app.thread, false);
5163     }
5164
5165     final void appDiedLocked(ProcessRecord app, int pid, IApplicationThread thread,
5166             boolean fromBinderDied) {
5167         // First check if this ProcessRecord is actually active for the pid.
5168         synchronized (mPidsSelfLocked) {
5169             ProcessRecord curProc = mPidsSelfLocked.get(pid);
5170             if (curProc != app) {
5171                 Slog.w(TAG, "Spurious death for " + app + ", curProc for " + pid + ": " + curProc);
5172                 return;
5173             }
5174         }
5175
5176         BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
5177         synchronized (stats) {
5178             stats.noteProcessDiedLocked(app.info.uid, pid);
5179         }
5180
5181         if (!app.killed) {
5182             if (!fromBinderDied) {
5183                 Process.killProcessQuiet(pid);
5184             }
5185             killProcessGroup(app.uid, pid);
5186             app.killed = true;
5187         }
5188
5189         // Clean up already done if the process has been re-started.
5190         if (app.pid == pid && app.thread != null &&
5191                 app.thread.asBinder() == thread.asBinder()) {
5192             boolean doLowMem = app.instrumentationClass == null;
5193             boolean doOomAdj = doLowMem;
5194             if (!app.killedByAm) {
5195                 Slog.i(TAG, "Process " + app.processName + " (pid " + pid
5196                         + ") has died");
5197                 mAllowLowerMemLevel = true;
5198             } else {
5199                 // Note that we always want to do oom adj to update our state with the
5200                 // new number of procs.
5201                 mAllowLowerMemLevel = false;
5202                 doLowMem = false;
5203             }
5204             EventLog.writeEvent(EventLogTags.AM_PROC_DIED, app.userId, app.pid, app.processName);
5205             if (DEBUG_CLEANUP) Slog.v(TAG_CLEANUP,
5206                 "Dying app: " + app + ", pid: " + pid + ", thread: " + thread.asBinder());
5207             handleAppDiedLocked(app, false, true);
5208
5209             if (doOomAdj) {
5210                 updateOomAdjLocked();
5211             }
5212             if (doLowMem) {
5213                 doLowMemReportIfNeededLocked(app);
5214             }
5215         } else if (app.pid != pid) {
5216             // A new process has already been started.
5217             Slog.i(TAG, "Process " + app.processName + " (pid " + pid
5218                     + ") has died and restarted (pid " + app.pid + ").");
5219             EventLog.writeEvent(EventLogTags.AM_PROC_DIED, app.userId, app.pid, app.processName);
5220         } else if (DEBUG_PROCESSES) {
5221             Slog.d(TAG_PROCESSES, "Received spurious death notification for thread "
5222                     + thread.asBinder());
5223         }
5224     }
5225
5226     /**
5227      * If a stack trace dump file is configured, dump process stack traces.
5228      * @param clearTraces causes the dump file to be erased prior to the new
5229      *    traces being written, if true; when false, the new traces will be
5230      *    appended to any existing file content.
5231      * @param firstPids of dalvik VM processes to dump stack traces for first
5232      * @param lastPids of dalvik VM processes to dump stack traces for last
5233      * @param nativeProcs optional list of native process names to dump stack crawls
5234      * @return file containing stack traces, or null if no dump file is configured
5235      */
5236     public static File dumpStackTraces(boolean clearTraces, ArrayList<Integer> firstPids,
5237             ProcessCpuTracker processCpuTracker, SparseArray<Boolean> lastPids, String[] nativeProcs) {
5238         String tracesPath = SystemProperties.get("dalvik.vm.stack-trace-file", null);
5239         if (tracesPath == null || tracesPath.length() == 0) {
5240             return null;
5241         }
5242
5243         File tracesFile = new File(tracesPath);
5244         try {
5245             if (clearTraces && tracesFile.exists()) tracesFile.delete();
5246             tracesFile.createNewFile();
5247             FileUtils.setPermissions(tracesFile.getPath(), 0666, -1, -1); // -rw-rw-rw-
5248         } catch (IOException e) {
5249             Slog.w(TAG, "Unable to prepare ANR traces file: " + tracesPath, e);
5250             return null;
5251         }
5252
5253         dumpStackTraces(tracesPath, firstPids, processCpuTracker, lastPids, nativeProcs);
5254         return tracesFile;
5255     }
5256
5257     private static void dumpStackTraces(String tracesPath, ArrayList<Integer> firstPids,
5258             ProcessCpuTracker processCpuTracker, SparseArray<Boolean> lastPids, String[] nativeProcs) {
5259         // Use a FileObserver to detect when traces finish writing.
5260         // The order of traces is considered important to maintain for legibility.
5261         FileObserver observer = new FileObserver(tracesPath, FileObserver.CLOSE_WRITE) {
5262             @Override
5263             public synchronized void onEvent(int event, String path) { notify(); }
5264         };
5265
5266         try {
5267             observer.startWatching();
5268
5269             // First collect all of the stacks of the most important pids.
5270             if (firstPids != null) {
5271                 try {
5272                     int num = firstPids.size();
5273                     for (int i = 0; i < num; i++) {
5274                         synchronized (observer) {
5275                             if (DEBUG_ANR) Slog.d(TAG, "Collecting stacks for pid "
5276                                     + firstPids.get(i));
5277                             final long sime = SystemClock.elapsedRealtime();
5278                             Process.sendSignal(firstPids.get(i), Process.SIGNAL_QUIT);
5279                             observer.wait(1000);  // Wait for write-close, give up after 1 sec
5280                             if (DEBUG_ANR) Slog.d(TAG, "Done with pid " + firstPids.get(i)
5281                                     + " in " + (SystemClock.elapsedRealtime()-sime) + "ms");
5282                         }
5283                     }
5284                 } catch (InterruptedException e) {
5285                     Slog.wtf(TAG, e);
5286                 }
5287             }
5288
5289             // Next collect the stacks of the native pids
5290             if (nativeProcs != null) {
5291                 int[] pids = Process.getPidsForCommands(nativeProcs);
5292                 if (pids != null) {
5293                     for (int pid : pids) {
5294                         if (DEBUG_ANR) Slog.d(TAG, "Collecting stacks for native pid " + pid);
5295                         final long sime = SystemClock.elapsedRealtime();
5296                         Debug.dumpNativeBacktraceToFile(pid, tracesPath);
5297                         if (DEBUG_ANR) Slog.d(TAG, "Done with native pid " + pid
5298                                 + " in " + (SystemClock.elapsedRealtime()-sime) + "ms");
5299                     }
5300                 }
5301             }
5302
5303             // Lastly, measure CPU usage.
5304             if (processCpuTracker != null) {
5305                 processCpuTracker.init();
5306                 System.gc();
5307                 processCpuTracker.update();
5308                 try {
5309                     synchronized (processCpuTracker) {
5310                         processCpuTracker.wait(500); // measure over 1/2 second.
5311                     }
5312                 } catch (InterruptedException e) {
5313                 }
5314                 processCpuTracker.update();
5315
5316                 // We'll take the stack crawls of just the top apps using CPU.
5317                 final int N = processCpuTracker.countWorkingStats();
5318                 int numProcs = 0;
5319                 for (int i=0; i<N && numProcs<5; i++) {
5320                     ProcessCpuTracker.Stats stats = processCpuTracker.getWorkingStats(i);
5321                     if (lastPids.indexOfKey(stats.pid) >= 0) {
5322                         numProcs++;
5323                         try {
5324                             synchronized (observer) {
5325                                 if (DEBUG_ANR) Slog.d(TAG, "Collecting stacks for extra pid "
5326                                         + stats.pid);
5327                                 final long stime = SystemClock.elapsedRealtime();
5328                                 Process.sendSignal(stats.pid, Process.SIGNAL_QUIT);
5329                                 observer.wait(1000);  // Wait for write-close, give up after 1 sec
5330                                 if (DEBUG_ANR) Slog.d(TAG, "Done with extra pid " + stats.pid
5331                                         + " in " + (SystemClock.elapsedRealtime()-stime) + "ms");
5332                             }
5333                         } catch (InterruptedException e) {
5334                             Slog.wtf(TAG, e);
5335                         }
5336                     } else if (DEBUG_ANR) {
5337                         Slog.d(TAG, "Skipping next CPU consuming process, not a java proc: "
5338                                 + stats.pid);
5339                     }
5340                 }
5341             }
5342         } finally {
5343             observer.stopWatching();
5344         }
5345     }
5346
5347     final void logAppTooSlow(ProcessRecord app, long startTime, String msg) {
5348         if (true || IS_USER_BUILD) {
5349             return;
5350         }
5351         String tracesPath = SystemProperties.get("dalvik.vm.stack-trace-file", null);
5352         if (tracesPath == null || tracesPath.length() == 0) {
5353             return;
5354         }
5355
5356         StrictMode.ThreadPolicy oldPolicy = StrictMode.allowThreadDiskReads();
5357         StrictMode.allowThreadDiskWrites();
5358         try {
5359             final File tracesFile = new File(tracesPath);
5360             final File tracesDir = tracesFile.getParentFile();
5361             final File tracesTmp = new File(tracesDir, "__tmp__");
5362             try {
5363                 if (tracesFile.exists()) {
5364                     tracesTmp.delete();
5365                     tracesFile.renameTo(tracesTmp);
5366                 }
5367                 StringBuilder sb = new StringBuilder();
5368                 Time tobj = new Time();
5369                 tobj.set(System.currentTimeMillis());
5370                 sb.append(tobj.format("%Y-%m-%d %H:%M:%S"));
5371                 sb.append(": ");
5372                 TimeUtils.formatDuration(SystemClock.uptimeMillis()-startTime, sb);
5373                 sb.append(" since ");
5374                 sb.append(msg);
5375                 FileOutputStream fos = new FileOutputStream(tracesFile);
5376                 fos.write(sb.toString().getBytes());
5377                 if (app == null) {
5378                     fos.write("\n*** No application process!".getBytes());
5379                 }
5380                 fos.close();
5381                 FileUtils.setPermissions(tracesFile.getPath(), 0666, -1, -1); // -rw-rw-rw-
5382             } catch (IOException e) {
5383                 Slog.w(TAG, "Unable to prepare slow app traces file: " + tracesPath, e);
5384                 return;
5385             }
5386
5387             if (app != null) {
5388                 ArrayList<Integer> firstPids = new ArrayList<Integer>();
5389                 firstPids.add(app.pid);
5390                 dumpStackTraces(tracesPath, firstPids, null, null, null);
5391             }
5392
5393             File lastTracesFile = null;
5394             File curTracesFile = null;
5395             for (int i=9; i>=0; i--) {
5396                 String name = String.format(Locale.US, "slow%02d.txt", i);
5397                 curTracesFile = new File(tracesDir, name);
5398                 if (curTracesFile.exists()) {
5399                     if (lastTracesFile != null) {
5400                         curTracesFile.renameTo(lastTracesFile);
5401                     } else {
5402                         curTracesFile.delete();
5403                     }
5404                 }
5405                 lastTracesFile = curTracesFile;
5406             }
5407             tracesFile.renameTo(curTracesFile);
5408             if (tracesTmp.exists()) {
5409                 tracesTmp.renameTo(tracesFile);
5410             }
5411         } finally {
5412             StrictMode.setThreadPolicy(oldPolicy);
5413         }
5414     }
5415
5416     final void showLaunchWarningLocked(final ActivityRecord cur, final ActivityRecord next) {
5417         if (!mLaunchWarningShown) {
5418             mLaunchWarningShown = true;
5419             mUiHandler.post(new Runnable() {
5420                 @Override
5421                 public void run() {
5422                     synchronized (ActivityManagerService.this) {
5423                         final Dialog d = new LaunchWarningWindow(mContext, cur, next);
5424                         d.show();
5425                         mUiHandler.postDelayed(new Runnable() {
5426                             @Override
5427                             public void run() {
5428                                 synchronized (ActivityManagerService.this) {
5429                                     d.dismiss();
5430                                     mLaunchWarningShown = false;
5431                                 }
5432                             }
5433                         }, 4000);
5434                     }
5435                 }
5436             });
5437         }
5438     }
5439
5440     @Override
5441     public boolean clearApplicationUserData(final String packageName,
5442             final IPackageDataObserver observer, int userId) {
5443         enforceNotIsolatedCaller("clearApplicationUserData");
5444         int uid = Binder.getCallingUid();
5445         int pid = Binder.getCallingPid();
5446         userId = mUserController.handleIncomingUser(pid, uid, userId, false,
5447                 ALLOW_FULL_ONLY, "clearApplicationUserData", null);
5448
5449
5450         long callingId = Binder.clearCallingIdentity();
5451         try {
5452             IPackageManager pm = AppGlobals.getPackageManager();
5453             int pkgUid = -1;
5454             synchronized(this) {
5455                 if (getPackageManagerInternalLocked().canPackageBeWiped(
5456                         userId, packageName)) {
5457                     throw new SecurityException(
5458                             "Cannot clear data for a device owner or a profile owner");
5459                 }
5460
5461                 try {
5462                     pkgUid = pm.getPackageUid(packageName, MATCH_UNINSTALLED_PACKAGES, userId);
5463                 } catch (RemoteException e) {
5464                 }
5465                 if (pkgUid == -1) {
5466                     Slog.w(TAG, "Invalid packageName: " + packageName);
5467                     if (observer != null) {
5468                         try {
5469                             observer.onRemoveCompleted(packageName, false);
5470                         } catch (RemoteException e) {
5471                             Slog.i(TAG, "Observer no longer exists.");
5472                         }
5473                     }
5474                     return false;
5475                 }
5476                 if (uid == pkgUid || checkComponentPermission(
5477                         android.Manifest.permission.CLEAR_APP_USER_DATA,
5478                         pid, uid, -1, true)
5479                         == PackageManager.PERMISSION_GRANTED) {
5480                     forceStopPackageLocked(packageName, pkgUid, "clear data");
5481                 } else {
5482                     throw new SecurityException("PID " + pid + " does not have permission "
5483                             + android.Manifest.permission.CLEAR_APP_USER_DATA + " to clear data"
5484                                     + " of package " + packageName);
5485                 }
5486
5487                 // Remove all tasks match the cleared application package and user
5488                 for (int i = mRecentTasks.size() - 1; i >= 0; i--) {
5489                     final TaskRecord tr = mRecentTasks.get(i);
5490                     final String taskPackageName =
5491                             tr.getBaseIntent().getComponent().getPackageName();
5492                     if (tr.userId != userId) continue;
5493                     if (!taskPackageName.equals(packageName)) continue;
5494                     removeTaskByIdLocked(tr.taskId, false, REMOVE_FROM_RECENTS);
5495                 }
5496             }
5497
5498             final int pkgUidF = pkgUid;
5499             final int userIdF = userId;
5500             final IPackageDataObserver localObserver = new IPackageDataObserver.Stub() {
5501                 @Override
5502                 public void onRemoveCompleted(String packageName, boolean succeeded)
5503                         throws RemoteException {
5504                     synchronized (ActivityManagerService.this) {
5505                         finishForceStopPackageLocked(packageName, pkgUidF);
5506                     }
5507
5508                     final Intent intent = new Intent(Intent.ACTION_PACKAGE_DATA_CLEARED,
5509                             Uri.fromParts("package", packageName, null));
5510                     intent.putExtra(Intent.EXTRA_UID, pkgUidF);
5511                     intent.putExtra(Intent.EXTRA_USER_HANDLE, UserHandle.getUserId(pkgUidF));
5512                     broadcastIntentInPackage("android", Process.SYSTEM_UID, intent,
5513                             null, null, 0, null, null, null, null, false, false, userIdF);
5514
5515                     if (observer != null) {
5516                         observer.onRemoveCompleted(packageName, succeeded);
5517                     }
5518                 }
5519             };
5520
5521             try {
5522                 // Clear application user data
5523                 pm.clearApplicationUserData(packageName, localObserver, userId);
5524
5525                 synchronized(this) {
5526                     // Remove all permissions granted from/to this package
5527                     removeUriPermissionsForPackageLocked(packageName, userId, true);
5528                 }
5529
5530                 // Remove all zen rules created by this package; revoke it's zen access.
5531                 INotificationManager inm = NotificationManager.getService();
5532                 inm.removeAutomaticZenRules(packageName);
5533                 inm.setNotificationPolicyAccessGranted(packageName, false);
5534
5535             } catch (RemoteException e) {
5536             }
5537         } finally {
5538             Binder.restoreCallingIdentity(callingId);
5539         }
5540         return true;
5541     }
5542
5543     @Override
5544     public void killBackgroundProcesses(final String packageName, int userId) {
5545         if (checkCallingPermission(android.Manifest.permission.KILL_BACKGROUND_PROCESSES)
5546                 != PackageManager.PERMISSION_GRANTED &&
5547                 checkCallingPermission(android.Manifest.permission.RESTART_PACKAGES)
5548                         != PackageManager.PERMISSION_GRANTED) {
5549             String msg = "Permission Denial: killBackgroundProcesses() from pid="
5550                     + Binder.getCallingPid()
5551                     + ", uid=" + Binder.getCallingUid()
5552                     + " requires " + android.Manifest.permission.KILL_BACKGROUND_PROCESSES;
5553             Slog.w(TAG, msg);
5554             throw new SecurityException(msg);
5555         }
5556
5557         userId = mUserController.handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(),
5558                 userId, true, ALLOW_FULL_ONLY, "killBackgroundProcesses", null);
5559         long callingId = Binder.clearCallingIdentity();
5560         try {
5561             IPackageManager pm = AppGlobals.getPackageManager();
5562             synchronized(this) {
5563                 int appId = -1;
5564                 try {
5565                     appId = UserHandle.getAppId(
5566                             pm.getPackageUid(packageName, MATCH_DEBUG_TRIAGED_MISSING, userId));
5567                 } catch (RemoteException e) {
5568                 }
5569                 if (appId == -1) {
5570                     Slog.w(TAG, "Invalid packageName: " + packageName);
5571                     return;
5572                 }
5573                 killPackageProcessesLocked(packageName, appId, userId,
5574                         ProcessList.SERVICE_ADJ, false, true, true, false, "kill background");
5575             }
5576         } finally {
5577             Binder.restoreCallingIdentity(callingId);
5578         }
5579     }
5580
5581     @Override
5582     public void killAllBackgroundProcesses() {
5583         if (checkCallingPermission(android.Manifest.permission.KILL_BACKGROUND_PROCESSES)
5584                 != PackageManager.PERMISSION_GRANTED) {
5585             final String msg = "Permission Denial: killAllBackgroundProcesses() from pid="
5586                     + Binder.getCallingPid() + ", uid=" + Binder.getCallingUid()
5587                     + " requires " + android.Manifest.permission.KILL_BACKGROUND_PROCESSES;
5588             Slog.w(TAG, msg);
5589             throw new SecurityException(msg);
5590         }
5591
5592         final long callingId = Binder.clearCallingIdentity();
5593         try {
5594             synchronized (this) {
5595                 final ArrayList<ProcessRecord> procs = new ArrayList<>();
5596                 final int NP = mProcessNames.getMap().size();
5597                 for (int ip = 0; ip < NP; ip++) {
5598                     final SparseArray<ProcessRecord> apps = mProcessNames.getMap().valueAt(ip);
5599                     final int NA = apps.size();
5600                     for (int ia = 0; ia < NA; ia++) {
5601                         final ProcessRecord app = apps.valueAt(ia);
5602                         if (app.persistent) {
5603                             // We don't kill persistent processes.
5604                             continue;
5605                         }
5606                         if (app.removed) {
5607                             procs.add(app);
5608                         } else if (app.setAdj >= ProcessList.CACHED_APP_MIN_ADJ) {
5609                             app.removed = true;
5610                             procs.add(app);
5611                         }
5612                     }
5613                 }
5614
5615                 final int N = procs.size();
5616                 for (int i = 0; i < N; i++) {
5617                     removeProcessLocked(procs.get(i), false, true, "kill all background");
5618                 }
5619
5620                 mAllowLowerMemLevel = true;
5621
5622                 updateOomAdjLocked();
5623                 doLowMemReportIfNeededLocked(null);
5624             }
5625         } finally {
5626             Binder.restoreCallingIdentity(callingId);
5627         }
5628     }
5629
5630     /**
5631      * Kills all background processes, except those matching any of the
5632      * specified properties.
5633      *
5634      * @param minTargetSdk the target SDK version at or above which to preserve
5635      *                     processes, or {@code -1} to ignore the target SDK
5636      * @param maxProcState the process state at or below which to preserve
5637      *                     processes, or {@code -1} to ignore the process state
5638      */
5639     private void killAllBackgroundProcessesExcept(int minTargetSdk, int maxProcState) {
5640         if (checkCallingPermission(android.Manifest.permission.KILL_BACKGROUND_PROCESSES)
5641                 != PackageManager.PERMISSION_GRANTED) {
5642             final String msg = "Permission Denial: killAllBackgroundProcessesExcept() from pid="
5643                     + Binder.getCallingPid() + ", uid=" + Binder.getCallingUid()
5644                     + " requires " + android.Manifest.permission.KILL_BACKGROUND_PROCESSES;
5645             Slog.w(TAG, msg);
5646             throw new SecurityException(msg);
5647         }
5648
5649         final long callingId = Binder.clearCallingIdentity();
5650         try {
5651             synchronized (this) {
5652                 final ArrayList<ProcessRecord> procs = new ArrayList<>();
5653                 final int NP = mProcessNames.getMap().size();
5654                 for (int ip = 0; ip < NP; ip++) {
5655                     final SparseArray<ProcessRecord> apps = mProcessNames.getMap().valueAt(ip);
5656                     final int NA = apps.size();
5657                     for (int ia = 0; ia < NA; ia++) {
5658                         final ProcessRecord app = apps.valueAt(ia);
5659                         if (app.removed) {
5660                             procs.add(app);
5661                         } else if ((minTargetSdk < 0 || app.info.targetSdkVersion < minTargetSdk)
5662                                 && (maxProcState < 0 || app.setProcState > maxProcState)) {
5663                             app.removed = true;
5664                             procs.add(app);
5665                         }
5666                     }
5667                 }
5668
5669                 final int N = procs.size();
5670                 for (int i = 0; i < N; i++) {
5671                     removeProcessLocked(procs.get(i), false, true, "kill all background except");
5672                 }
5673             }
5674         } finally {
5675             Binder.restoreCallingIdentity(callingId);
5676         }
5677     }
5678
5679     @Override
5680     public void forceStopPackage(final String packageName, int userId) {
5681         if (checkCallingPermission(android.Manifest.permission.FORCE_STOP_PACKAGES)
5682                 != PackageManager.PERMISSION_GRANTED) {
5683             String msg = "Permission Denial: forceStopPackage() from pid="
5684                     + Binder.getCallingPid()
5685                     + ", uid=" + Binder.getCallingUid()
5686                     + " requires " + android.Manifest.permission.FORCE_STOP_PACKAGES;
5687             Slog.w(TAG, msg);
5688             throw new SecurityException(msg);
5689         }
5690         final int callingPid = Binder.getCallingPid();
5691         userId = mUserController.handleIncomingUser(callingPid, Binder.getCallingUid(),
5692                 userId, true, ALLOW_FULL_ONLY, "forceStopPackage", null);
5693         long callingId = Binder.clearCallingIdentity();
5694         try {
5695             IPackageManager pm = AppGlobals.getPackageManager();
5696             synchronized(this) {
5697                 int[] users = userId == UserHandle.USER_ALL
5698                         ? mUserController.getUsers() : new int[] { userId };
5699                 for (int user : users) {
5700                     int pkgUid = -1;
5701                     try {
5702                         pkgUid = pm.getPackageUid(packageName, MATCH_DEBUG_TRIAGED_MISSING,
5703                                 user);
5704                     } catch (RemoteException e) {
5705                     }
5706                     if (pkgUid == -1) {
5707                         Slog.w(TAG, "Invalid packageName: " + packageName);
5708                         continue;
5709                     }
5710                     try {
5711                         pm.setPackageStoppedState(packageName, true, user);
5712                     } catch (RemoteException e) {
5713                     } catch (IllegalArgumentException e) {
5714                         Slog.w(TAG, "Failed trying to unstop package "
5715                                 + packageName + ": " + e);
5716                     }
5717                     if (mUserController.isUserRunningLocked(user, 0)) {
5718                         forceStopPackageLocked(packageName, pkgUid, "from pid " + callingPid);
5719                         finishForceStopPackageLocked(packageName, pkgUid);
5720                     }
5721                 }
5722             }
5723         } finally {
5724             Binder.restoreCallingIdentity(callingId);
5725         }
5726     }
5727
5728     @Override
5729     public void addPackageDependency(String packageName) {
5730         synchronized (this) {
5731             int callingPid = Binder.getCallingPid();
5732             if (callingPid == Process.myPid()) {
5733                 //  Yeah, um, no.
5734                 return;
5735             }
5736             ProcessRecord proc;
5737             synchronized (mPidsSelfLocked) {
5738                 proc = mPidsSelfLocked.get(Binder.getCallingPid());
5739             }
5740             if (proc != null) {
5741                 if (proc.pkgDeps == null) {
5742                     proc.pkgDeps = new ArraySet<String>(1);
5743                 }
5744                 proc.pkgDeps.add(packageName);
5745             }
5746         }
5747     }
5748
5749     /*
5750      * The pkg name and app id have to be specified.
5751      */
5752     @Override
5753     public void killApplication(String pkg, int appId, int userId, String reason) {
5754         if (pkg == null) {
5755             return;
5756         }
5757         // Make sure the uid is valid.
5758         if (appId < 0) {
5759             Slog.w(TAG, "Invalid appid specified for pkg : " + pkg);
5760             return;
5761         }
5762         int callerUid = Binder.getCallingUid();
5763         // Only the system server can kill an application
5764         if (UserHandle.getAppId(callerUid) == Process.SYSTEM_UID) {
5765             // Post an aysnc message to kill the application
5766             Message msg = mHandler.obtainMessage(KILL_APPLICATION_MSG);
5767             msg.arg1 = appId;
5768             msg.arg2 = userId;
5769             Bundle bundle = new Bundle();
5770             bundle.putString("pkg", pkg);
5771             bundle.putString("reason", reason);
5772             msg.obj = bundle;
5773             mHandler.sendMessage(msg);
5774         } else {
5775             throw new SecurityException(callerUid + " cannot kill pkg: " +
5776                     pkg);
5777         }
5778     }
5779
5780     @Override
5781     public void closeSystemDialogs(String reason) {
5782         enforceNotIsolatedCaller("closeSystemDialogs");
5783
5784         final int pid = Binder.getCallingPid();
5785         final int uid = Binder.getCallingUid();
5786         final long origId = Binder.clearCallingIdentity();
5787         try {
5788             synchronized (this) {
5789                 // Only allow this from foreground processes, so that background
5790                 // applications can't abuse it to prevent system UI from being shown.
5791                 if (uid >= Process.FIRST_APPLICATION_UID) {
5792                     ProcessRecord proc;
5793                     synchronized (mPidsSelfLocked) {
5794                         proc = mPidsSelfLocked.get(pid);
5795                     }
5796                     if (proc.curRawAdj > ProcessList.PERCEPTIBLE_APP_ADJ) {
5797                         Slog.w(TAG, "Ignoring closeSystemDialogs " + reason
5798                                 + " from background process " + proc);
5799                         return;
5800                     }
5801                 }
5802                 closeSystemDialogsLocked(reason);
5803             }
5804         } finally {
5805             Binder.restoreCallingIdentity(origId);
5806         }
5807     }
5808
5809     void closeSystemDialogsLocked(String reason) {
5810         Intent intent = new Intent(Intent.ACTION_CLOSE_SYSTEM_DIALOGS);
5811         intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY
5812                 | Intent.FLAG_RECEIVER_FOREGROUND);
5813         if (reason != null) {
5814             intent.putExtra("reason", reason);
5815         }
5816         mWindowManager.closeSystemDialogs(reason);
5817
5818         mStackSupervisor.closeSystemDialogsLocked();
5819
5820         broadcastIntentLocked(null, null, intent, null, null, 0, null, null, null,
5821                 AppOpsManager.OP_NONE, null, false, false,
5822                 -1, Process.SYSTEM_UID, UserHandle.USER_ALL);
5823     }
5824
5825     @Override
5826     public Debug.MemoryInfo[] getProcessMemoryInfo(int[] pids) {
5827         enforceNotIsolatedCaller("getProcessMemoryInfo");
5828         Debug.MemoryInfo[] infos = new Debug.MemoryInfo[pids.length];
5829         for (int i=pids.length-1; i>=0; i--) {
5830             ProcessRecord proc;
5831             int oomAdj;
5832             synchronized (this) {
5833                 synchronized (mPidsSelfLocked) {
5834                     proc = mPidsSelfLocked.get(pids[i]);
5835                     oomAdj = proc != null ? proc.setAdj : 0;
5836                 }
5837             }
5838             infos[i] = new Debug.MemoryInfo();
5839             Debug.getMemoryInfo(pids[i], infos[i]);
5840             if (proc != null) {
5841                 synchronized (this) {
5842                     if (proc.thread != null && proc.setAdj == oomAdj) {
5843                         // Record this for posterity if the process has been stable.
5844                         proc.baseProcessTracker.addPss(infos[i].getTotalPss(),
5845                                 infos[i].getTotalUss(), false, proc.pkgList);
5846                     }
5847                 }
5848             }
5849         }
5850         return infos;
5851     }
5852
5853     @Override
5854     public long[] getProcessPss(int[] pids) {
5855         enforceNotIsolatedCaller("getProcessPss");
5856         long[] pss = new long[pids.length];
5857         for (int i=pids.length-1; i>=0; i--) {
5858             ProcessRecord proc;
5859             int oomAdj;
5860             synchronized (this) {
5861                 synchronized (mPidsSelfLocked) {
5862                     proc = mPidsSelfLocked.get(pids[i]);
5863                     oomAdj = proc != null ? proc.setAdj : 0;
5864                 }
5865             }
5866             long[] tmpUss = new long[1];
5867             pss[i] = Debug.getPss(pids[i], tmpUss, null);
5868             if (proc != null) {
5869                 synchronized (this) {
5870                     if (proc.thread != null && proc.setAdj == oomAdj) {
5871                         // Record this for posterity if the process has been stable.
5872                         proc.baseProcessTracker.addPss(pss[i], tmpUss[0], false, proc.pkgList);
5873                     }
5874                 }
5875             }
5876         }
5877         return pss;
5878     }
5879
5880     @Override
5881     public void killApplicationProcess(String processName, int uid) {
5882         if (processName == null) {
5883             return;
5884         }
5885
5886         int callerUid = Binder.getCallingUid();
5887         // Only the system server can kill an application
5888         if (callerUid == Process.SYSTEM_UID) {
5889             synchronized (this) {
5890                 ProcessRecord app = getProcessRecordLocked(processName, uid, true);
5891                 if (app != null && app.thread != null) {
5892                     try {
5893                         app.thread.scheduleSuicide();
5894                     } catch (RemoteException e) {
5895                         // If the other end already died, then our work here is done.
5896                     }
5897                 } else {
5898                     Slog.w(TAG, "Process/uid not found attempting kill of "
5899                             + processName + " / " + uid);
5900                 }
5901             }
5902         } else {
5903             throw new SecurityException(callerUid + " cannot kill app process: " +
5904                     processName);
5905         }
5906     }
5907
5908     private void forceStopPackageLocked(final String packageName, int uid, String reason) {
5909         forceStopPackageLocked(packageName, UserHandle.getAppId(uid), false,
5910                 false, true, false, false, UserHandle.getUserId(uid), reason);
5911     }
5912
5913     private void finishForceStopPackageLocked(final String packageName, int uid) {
5914         Intent intent = new Intent(Intent.ACTION_PACKAGE_RESTARTED,
5915                 Uri.fromParts("package", packageName, null));
5916         if (!mProcessesReady) {
5917             intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY
5918                     | Intent.FLAG_RECEIVER_FOREGROUND);
5919         }
5920         intent.putExtra(Intent.EXTRA_UID, uid);
5921         intent.putExtra(Intent.EXTRA_USER_HANDLE, UserHandle.getUserId(uid));
5922         broadcastIntentLocked(null, null, intent,
5923                 null, null, 0, null, null, null, AppOpsManager.OP_NONE,
5924                 null, false, false, MY_PID, Process.SYSTEM_UID, UserHandle.getUserId(uid));
5925     }
5926
5927
5928     private final boolean killPackageProcessesLocked(String packageName, int appId,
5929             int userId, int minOomAdj, boolean callerWillRestart, boolean allowRestart,
5930             boolean doit, boolean evenPersistent, String reason) {
5931         ArrayList<ProcessRecord> procs = new ArrayList<>();
5932
5933         // Remove all processes this package may have touched: all with the
5934         // same UID (except for the system or root user), and all whose name
5935         // matches the package name.
5936         final int NP = mProcessNames.getMap().size();
5937         for (int ip=0; ip<NP; ip++) {
5938             SparseArray<ProcessRecord> apps = mProcessNames.getMap().valueAt(ip);
5939             final int NA = apps.size();
5940             for (int ia=0; ia<NA; ia++) {
5941                 ProcessRecord app = apps.valueAt(ia);
5942                 if (app.persistent && !evenPersistent) {
5943                     // we don't kill persistent processes
5944                     continue;
5945                 }
5946                 if (app.removed) {
5947                     if (doit) {
5948                         procs.add(app);
5949                     }
5950                     continue;
5951                 }
5952
5953                 // Skip process if it doesn't meet our oom adj requirement.
5954                 if (app.setAdj < minOomAdj) {
5955                     continue;
5956                 }
5957
5958                 // If no package is specified, we call all processes under the
5959                 // give user id.
5960                 if (packageName == null) {
5961                     if (userId != UserHandle.USER_ALL && app.userId != userId) {
5962                         continue;
5963                     }
5964                     if (appId >= 0 && UserHandle.getAppId(app.uid) != appId) {
5965                         continue;
5966                     }
5967                 // Package has been specified, we want to hit all processes
5968                 // that match it.  We need to qualify this by the processes
5969                 // that are running under the specified app and user ID.
5970                 } else {
5971                     final boolean isDep = app.pkgDeps != null
5972                             && app.pkgDeps.contains(packageName);
5973                     if (!isDep && UserHandle.getAppId(app.uid) != appId) {
5974                         continue;
5975                     }
5976                     if (userId != UserHandle.USER_ALL && app.userId != userId) {
5977                         continue;
5978                     }
5979                     if (!app.pkgList.containsKey(packageName) && !isDep) {
5980                         continue;
5981                     }
5982                 }
5983
5984                 // Process has passed all conditions, kill it!
5985                 if (!doit) {
5986                     return true;
5987                 }
5988                 app.removed = true;
5989                 procs.add(app);
5990             }
5991         }
5992
5993         int N = procs.size();
5994         for (int i=0; i<N; i++) {
5995             removeProcessLocked(procs.get(i), callerWillRestart, allowRestart, reason);
5996         }
5997         updateOomAdjLocked();
5998         return N > 0;
5999     }
6000
6001     private void cleanupDisabledPackageComponentsLocked(
6002             String packageName, int userId, boolean killProcess, String[] changedClasses) {
6003
6004         Set<String> disabledClasses = null;
6005         boolean packageDisabled = false;
6006         IPackageManager pm = AppGlobals.getPackageManager();
6007
6008         if (changedClasses == null) {
6009             // Nothing changed...
6010             return;
6011         }
6012
6013         // Determine enable/disable state of the package and its components.
6014         int enabled = PackageManager.COMPONENT_ENABLED_STATE_DEFAULT;
6015         for (int i = changedClasses.length - 1; i >= 0; i--) {
6016             final String changedClass = changedClasses[i];
6017
6018             if (changedClass.equals(packageName)) {
6019                 try {
6020                     // Entire package setting changed
6021                     enabled = pm.getApplicationEnabledSetting(packageName,
6022                             (userId != UserHandle.USER_ALL) ? userId : UserHandle.USER_SYSTEM);
6023                 } catch (Exception e) {
6024                     // No such package/component; probably racing with uninstall.  In any
6025                     // event it means we have nothing further to do here.
6026                     return;
6027                 }
6028                 packageDisabled = enabled != PackageManager.COMPONENT_ENABLED_STATE_ENABLED
6029                         && enabled != PackageManager.COMPONENT_ENABLED_STATE_DEFAULT;
6030                 if (packageDisabled) {
6031                     // Entire package is disabled.
6032                     // No need to continue to check component states.
6033                     disabledClasses = null;
6034                     break;
6035                 }
6036             } else {
6037                 try {
6038                     enabled = pm.getComponentEnabledSetting(
6039                             new ComponentName(packageName, changedClass),
6040                             (userId != UserHandle.USER_ALL) ? userId : UserHandle.USER_SYSTEM);
6041                 } catch (Exception e) {
6042                     // As above, probably racing with uninstall.
6043                     return;
6044                 }
6045                 if (enabled != PackageManager.COMPONENT_ENABLED_STATE_ENABLED
6046                         && enabled != PackageManager.COMPONENT_ENABLED_STATE_DEFAULT) {
6047                     if (disabledClasses == null) {
6048                         disabledClasses = new ArraySet<>(changedClasses.length);
6049                     }
6050                     disabledClasses.add(changedClass);
6051                 }
6052             }
6053         }
6054
6055         if (!packageDisabled && disabledClasses == null) {
6056             // Nothing to do here...
6057             return;
6058         }
6059
6060         // Clean-up disabled activities.
6061         if (mStackSupervisor.finishDisabledPackageActivitiesLocked(
6062                 packageName, disabledClasses, true, false, userId) && mBooted) {
6063             mStackSupervisor.resumeFocusedStackTopActivityLocked();
6064             mStackSupervisor.scheduleIdleLocked();
6065         }
6066
6067         // Clean-up disabled tasks
6068         cleanupDisabledPackageTasksLocked(packageName, disabledClasses, userId);
6069
6070         // Clean-up disabled services.
6071         mServices.bringDownDisabledPackageServicesLocked(
6072                 packageName, disabledClasses, userId, false, killProcess, true);
6073
6074         // Clean-up disabled providers.
6075         ArrayList<ContentProviderRecord> providers = new ArrayList<>();
6076         mProviderMap.collectPackageProvidersLocked(
6077                 packageName, disabledClasses, true, false, userId, providers);
6078         for (int i = providers.size() - 1; i >= 0; i--) {
6079             removeDyingProviderLocked(null, providers.get(i), true);
6080         }
6081
6082         // Clean-up disabled broadcast receivers.
6083         for (int i = mBroadcastQueues.length - 1; i >= 0; i--) {
6084             mBroadcastQueues[i].cleanupDisabledPackageReceiversLocked(
6085                     packageName, disabledClasses, userId, true);
6086         }
6087
6088     }
6089
6090     final boolean clearBroadcastQueueForUserLocked(int userId) {
6091         boolean didSomething = false;
6092         for (int i = mBroadcastQueues.length - 1; i >= 0; i--) {
6093             didSomething |= mBroadcastQueues[i].cleanupDisabledPackageReceiversLocked(
6094                     null, null, userId, true);
6095         }
6096         return didSomething;
6097     }
6098
6099     final boolean forceStopPackageLocked(String packageName, int appId,
6100             boolean callerWillRestart, boolean purgeCache, boolean doit,
6101             boolean evenPersistent, boolean uninstalling, int userId, String reason) {
6102         int i;
6103
6104         if (userId == UserHandle.USER_ALL && packageName == null) {
6105             Slog.w(TAG, "Can't force stop all processes of all users, that is insane!");
6106         }
6107
6108         if (appId < 0 && packageName != null) {
6109             try {
6110                 appId = UserHandle.getAppId(AppGlobals.getPackageManager()
6111                         .getPackageUid(packageName, MATCH_DEBUG_TRIAGED_MISSING, 0));
6112             } catch (RemoteException e) {
6113             }
6114         }
6115
6116         if (doit) {
6117             if (packageName != null) {
6118                 Slog.i(TAG, "Force stopping " + packageName + " appid=" + appId
6119                         + " user=" + userId + ": " + reason);
6120             } else {
6121                 Slog.i(TAG, "Force stopping u" + userId + ": " + reason);
6122             }
6123
6124             mAppErrors.resetProcessCrashTimeLocked(packageName == null, appId, userId);
6125         }
6126
6127         boolean didSomething = killPackageProcessesLocked(packageName, appId, userId,
6128                 ProcessList.INVALID_ADJ, callerWillRestart, true, doit, evenPersistent,
6129                 packageName == null ? ("stop user " + userId) : ("stop " + packageName));
6130
6131         if (mStackSupervisor.finishDisabledPackageActivitiesLocked(
6132                 packageName, null, doit, evenPersistent, userId)) {
6133             if (!doit) {
6134                 return true;
6135             }
6136             didSomething = true;
6137         }
6138
6139         if (mServices.bringDownDisabledPackageServicesLocked(
6140                 packageName, null, userId, evenPersistent, true, doit)) {
6141             if (!doit) {
6142                 return true;
6143             }
6144             didSomething = true;
6145         }
6146
6147         if (packageName == null) {
6148             // Remove all sticky broadcasts from this user.
6149             mStickyBroadcasts.remove(userId);
6150         }
6151
6152         ArrayList<ContentProviderRecord> providers = new ArrayList<>();
6153         if (mProviderMap.collectPackageProvidersLocked(packageName, null, doit, evenPersistent,
6154                 userId, providers)) {
6155             if (!doit) {
6156                 return true;
6157             }
6158             didSomething = true;
6159         }
6160         for (i = providers.size() - 1; i >= 0; i--) {
6161             removeDyingProviderLocked(null, providers.get(i), true);
6162         }
6163
6164         // Remove transient permissions granted from/to this package/user
6165         removeUriPermissionsForPackageLocked(packageName, userId, false);
6166
6167         if (doit) {
6168             for (i = mBroadcastQueues.length - 1; i >= 0; i--) {
6169                 didSomething |= mBroadcastQueues[i].cleanupDisabledPackageReceiversLocked(
6170                         packageName, null, userId, doit);
6171             }
6172         }
6173
6174         if (packageName == null || uninstalling) {
6175             // Remove pending intents.  For now we only do this when force
6176             // stopping users, because we have some problems when doing this
6177             // for packages -- app widgets are not currently cleaned up for
6178             // such packages, so they can be left with bad pending intents.
6179             if (mIntentSenderRecords.size() > 0) {
6180                 Iterator<WeakReference<PendingIntentRecord>> it
6181                         = mIntentSenderRecords.values().iterator();
6182                 while (it.hasNext()) {
6183                     WeakReference<PendingIntentRecord> wpir = it.next();
6184                     if (wpir == null) {
6185                         it.remove();
6186                         continue;
6187                     }
6188                     PendingIntentRecord pir = wpir.get();
6189                     if (pir == null) {
6190                         it.remove();
6191                         continue;
6192                     }
6193                     if (packageName == null) {
6194                         // Stopping user, remove all objects for the user.
6195                         if (pir.key.userId != userId) {
6196                             // Not the same user, skip it.
6197                             continue;
6198                         }
6199                     } else {
6200                         if (UserHandle.getAppId(pir.uid) != appId) {
6201                             // Different app id, skip it.
6202                             continue;
6203                         }
6204                         if (userId != UserHandle.USER_ALL && pir.key.userId != userId) {
6205                             // Different user, skip it.
6206                             continue;
6207                         }
6208                         if (!pir.key.packageName.equals(packageName)) {
6209                             // Different package, skip it.
6210                             continue;
6211                         }
6212                     }
6213                     if (!doit) {
6214                         return true;
6215                     }
6216                     didSomething = true;
6217                     it.remove();
6218                     pir.canceled = true;
6219                     if (pir.key.activity != null && pir.key.activity.pendingResults != null) {
6220                         pir.key.activity.pendingResults.remove(pir.ref);
6221                     }
6222                 }
6223             }
6224         }
6225
6226         if (doit) {
6227             if (purgeCache && packageName != null) {
6228                 AttributeCache ac = AttributeCache.instance();
6229                 if (ac != null) {
6230                     ac.removePackage(packageName);
6231                 }
6232             }
6233             if (mBooted) {
6234                 mStackSupervisor.resumeFocusedStackTopActivityLocked();
6235                 mStackSupervisor.scheduleIdleLocked();
6236             }
6237         }
6238
6239         return didSomething;
6240     }
6241
6242     private final ProcessRecord removeProcessNameLocked(final String name, final int uid) {
6243         ProcessRecord old = mProcessNames.remove(name, uid);
6244         if (old != null) {
6245             old.uidRecord.numProcs--;
6246             if (old.uidRecord.numProcs == 0) {
6247                 // No more processes using this uid, tell clients it is gone.
6248                 if (DEBUG_UID_OBSERVERS) Slog.i(TAG_UID_OBSERVERS,
6249                         "No more processes in " + old.uidRecord);
6250                 enqueueUidChangeLocked(old.uidRecord, -1, UidRecord.CHANGE_GONE);
6251                 mActiveUids.remove(uid);
6252                 noteUidProcessState(uid, ActivityManager.PROCESS_STATE_NONEXISTENT);
6253             }
6254             old.uidRecord = null;
6255         }
6256         mIsolatedProcesses.remove(uid);
6257         return old;
6258     }
6259
6260     private final void addProcessNameLocked(ProcessRecord proc) {
6261         // We shouldn't already have a process under this name, but just in case we
6262         // need to clean up whatever may be there now.
6263         ProcessRecord old = removeProcessNameLocked(proc.processName, proc.uid);
6264         if (old == proc && proc.persistent) {
6265             // We are re-adding a persistent process.  Whatevs!  Just leave it there.
6266             Slog.w(TAG, "Re-adding persistent process " + proc);
6267         } else if (old != null) {
6268             Slog.wtf(TAG, "Already have existing proc " + old + " when adding " + proc);
6269         }
6270         UidRecord uidRec = mActiveUids.get(proc.uid);
6271         if (uidRec == null) {
6272             uidRec = new UidRecord(proc.uid);
6273             // This is the first appearance of the uid, report it now!
6274             if (DEBUG_UID_OBSERVERS) Slog.i(TAG_UID_OBSERVERS,
6275                     "Creating new process uid: " + uidRec);
6276             mActiveUids.put(proc.uid, uidRec);
6277             noteUidProcessState(uidRec.uid, uidRec.curProcState);
6278             enqueueUidChangeLocked(uidRec, -1, UidRecord.CHANGE_ACTIVE);
6279         }
6280         proc.uidRecord = uidRec;
6281         uidRec.numProcs++;
6282         mProcessNames.put(proc.processName, proc.uid, proc);
6283         if (proc.isolated) {
6284             mIsolatedProcesses.put(proc.uid, proc);
6285         }
6286     }
6287
6288     boolean removeProcessLocked(ProcessRecord app,
6289             boolean callerWillRestart, boolean allowRestart, String reason) {
6290         final String name = app.processName;
6291         final int uid = app.uid;
6292         if (DEBUG_PROCESSES) Slog.d(TAG_PROCESSES,
6293             "Force removing proc " + app.toShortString() + " (" + name + "/" + uid + ")");
6294
6295         ProcessRecord old = mProcessNames.get(name, uid);
6296         if (old != app) {
6297             // This process is no longer active, so nothing to do.
6298             Slog.w(TAG, "Ignoring remove of inactive process: " + app);
6299             return false;
6300         }
6301         removeProcessNameLocked(name, uid);
6302         if (mHeavyWeightProcess == app) {
6303             mHandler.sendMessage(mHandler.obtainMessage(CANCEL_HEAVY_NOTIFICATION_MSG,
6304                     mHeavyWeightProcess.userId, 0));
6305             mHeavyWeightProcess = null;
6306         }
6307         boolean needRestart = false;
6308         if (app.pid > 0 && app.pid != MY_PID) {
6309             int pid = app.pid;
6310             synchronized (mPidsSelfLocked) {
6311                 mPidsSelfLocked.remove(pid);
6312                 mHandler.removeMessages(PROC_START_TIMEOUT_MSG, app);
6313             }
6314             mBatteryStatsService.noteProcessFinish(app.processName, app.info.uid);
6315             if (app.isolated) {
6316                 mBatteryStatsService.removeIsolatedUid(app.uid, app.info.uid);
6317             }
6318             boolean willRestart = false;
6319             if (app.persistent && !app.isolated) {
6320                 if (!callerWillRestart) {
6321                     willRestart = true;
6322                 } else {
6323                     needRestart = true;
6324                 }
6325             }
6326             app.kill(reason, true);
6327             handleAppDiedLocked(app, willRestart, allowRestart);
6328             if (willRestart) {
6329                 removeLruProcessLocked(app);
6330                 addAppLocked(app.info, false, null /* ABI override */);
6331             }
6332         } else {
6333             mRemovedProcesses.add(app);
6334         }
6335
6336         return needRestart;
6337     }
6338
6339     private final void processContentProviderPublishTimedOutLocked(ProcessRecord app) {
6340         cleanupAppInLaunchingProvidersLocked(app, true);
6341         removeProcessLocked(app, false, true, "timeout publishing content providers");
6342     }
6343
6344     private final void processStartTimedOutLocked(ProcessRecord app) {
6345         final int pid = app.pid;
6346         boolean gone = false;
6347         synchronized (mPidsSelfLocked) {
6348             ProcessRecord knownApp = mPidsSelfLocked.get(pid);
6349             if (knownApp != null && knownApp.thread == null) {
6350                 mPidsSelfLocked.remove(pid);
6351                 gone = true;
6352             }
6353         }
6354
6355         if (gone) {
6356             Slog.w(TAG, "Process " + app + " failed to attach");
6357             EventLog.writeEvent(EventLogTags.AM_PROCESS_START_TIMEOUT, app.userId,
6358                     pid, app.uid, app.processName);
6359             removeProcessNameLocked(app.processName, app.uid);
6360             if (mHeavyWeightProcess == app) {
6361                 mHandler.sendMessage(mHandler.obtainMessage(CANCEL_HEAVY_NOTIFICATION_MSG,
6362                         mHeavyWeightProcess.userId, 0));
6363                 mHeavyWeightProcess = null;
6364             }
6365             mBatteryStatsService.noteProcessFinish(app.processName, app.info.uid);
6366             if (app.isolated) {
6367                 mBatteryStatsService.removeIsolatedUid(app.uid, app.info.uid);
6368             }
6369             // Take care of any launching providers waiting for this process.
6370             cleanupAppInLaunchingProvidersLocked(app, true);
6371             // Take care of any services that are waiting for the process.
6372             mServices.processStartTimedOutLocked(app);
6373             app.kill("start timeout", true);
6374             removeLruProcessLocked(app);
6375             if (mBackupTarget != null && mBackupTarget.app.pid == pid) {
6376                 Slog.w(TAG, "Unattached app died before backup, skipping");
6377                 try {
6378                     IBackupManager bm = IBackupManager.Stub.asInterface(
6379                             ServiceManager.getService(Context.BACKUP_SERVICE));
6380                     bm.agentDisconnected(app.info.packageName);
6381                 } catch (RemoteException e) {
6382                     // Can't happen; the backup manager is local
6383                 }
6384             }
6385             if (isPendingBroadcastProcessLocked(pid)) {
6386                 Slog.w(TAG, "Unattached app died before broadcast acknowledged, skipping");
6387                 skipPendingBroadcastLocked(pid);
6388             }
6389         } else {
6390             Slog.w(TAG, "Spurious process start timeout - pid not known for " + app);
6391         }
6392     }
6393
6394     private final boolean attachApplicationLocked(IApplicationThread thread,
6395             int pid) {
6396
6397         // Find the application record that is being attached...  either via
6398         // the pid if we are running in multiple processes, or just pull the
6399         // next app record if we are emulating process with anonymous threads.
6400         ProcessRecord app;
6401         if (pid != MY_PID && pid >= 0) {
6402             synchronized (mPidsSelfLocked) {
6403                 app = mPidsSelfLocked.get(pid);
6404             }
6405         } else {
6406             app = null;
6407         }
6408
6409         if (app == null) {
6410             Slog.w(TAG, "No pending application record for pid " + pid
6411                     + " (IApplicationThread " + thread + "); dropping process");
6412             EventLog.writeEvent(EventLogTags.AM_DROP_PROCESS, pid);
6413             if (pid > 0 && pid != MY_PID) {
6414                 Process.killProcessQuiet(pid);
6415                 //TODO: killProcessGroup(app.info.uid, pid);
6416             } else {
6417                 try {
6418                     thread.scheduleExit();
6419                 } catch (Exception e) {
6420                     // Ignore exceptions.
6421                 }
6422             }
6423             return false;
6424         }
6425
6426         // If this application record is still attached to a previous
6427         // process, clean it up now.
6428         if (app.thread != null) {
6429             handleAppDiedLocked(app, true, true);
6430         }
6431
6432         // Tell the process all about itself.
6433
6434         if (DEBUG_ALL) Slog.v(
6435                 TAG, "Binding process pid " + pid + " to record " + app);
6436
6437         final String processName = app.processName;
6438         try {
6439             AppDeathRecipient adr = new AppDeathRecipient(
6440                     app, pid, thread);
6441             thread.asBinder().linkToDeath(adr, 0);
6442             app.deathRecipient = adr;
6443         } catch (RemoteException e) {
6444             app.resetPackageList(mProcessStats);
6445             startProcessLocked(app, "link fail", processName);
6446             return false;
6447         }
6448
6449         EventLog.writeEvent(EventLogTags.AM_PROC_BOUND, app.userId, app.pid, app.processName);
6450
6451         app.makeActive(thread, mProcessStats);
6452         app.curAdj = app.setAdj = app.verifiedAdj = ProcessList.INVALID_ADJ;
6453         app.curSchedGroup = app.setSchedGroup = ProcessList.SCHED_GROUP_DEFAULT;
6454         app.forcingToForeground = null;
6455         updateProcessForegroundLocked(app, false, false);
6456         app.hasShownUi = false;
6457         app.debugging = false;
6458         app.cached = false;
6459         app.killedByAm = false;
6460
6461         // We carefully use the same state that PackageManager uses for
6462         // filtering, since we use this flag to decide if we need to install
6463         // providers when user is unlocked later
6464         app.unlocked = StorageManager.isUserKeyUnlocked(app.userId);
6465
6466         mHandler.removeMessages(PROC_START_TIMEOUT_MSG, app);
6467
6468         boolean normalMode = mProcessesReady || isAllowedWhileBooting(app.info);
6469         List<ProviderInfo> providers = normalMode ? generateApplicationProvidersLocked(app) : null;
6470
6471         if (providers != null && checkAppInLaunchingProvidersLocked(app)) {
6472             Message msg = mHandler.obtainMessage(CONTENT_PROVIDER_PUBLISH_TIMEOUT_MSG);
6473             msg.obj = app;
6474             mHandler.sendMessageDelayed(msg, CONTENT_PROVIDER_PUBLISH_TIMEOUT);
6475         }
6476
6477         if (!normalMode) {
6478             Slog.i(TAG, "Launching preboot mode app: " + app);
6479         }
6480
6481         if (DEBUG_ALL) Slog.v(
6482             TAG, "New app record " + app
6483             + " thread=" + thread.asBinder() + " pid=" + pid);
6484         try {
6485             int testMode = IApplicationThread.DEBUG_OFF;
6486             if (mDebugApp != null && mDebugApp.equals(processName)) {
6487                 testMode = mWaitForDebugger
6488                     ? IApplicationThread.DEBUG_WAIT
6489                     : IApplicationThread.DEBUG_ON;
6490                 app.debugging = true;
6491                 if (mDebugTransient) {
6492                     mDebugApp = mOrigDebugApp;
6493                     mWaitForDebugger = mOrigWaitForDebugger;
6494                 }
6495             }
6496             String profileFile = app.instrumentationProfileFile;
6497             ParcelFileDescriptor profileFd = null;
6498             int samplingInterval = 0;
6499             boolean profileAutoStop = false;
6500             if (mProfileApp != null && mProfileApp.equals(processName)) {
6501                 mProfileProc = app;
6502                 profileFile = mProfileFile;
6503                 profileFd = mProfileFd;
6504                 samplingInterval = mSamplingInterval;
6505                 profileAutoStop = mAutoStopProfiler;
6506             }
6507             boolean enableTrackAllocation = false;
6508             if (mTrackAllocationApp != null && mTrackAllocationApp.equals(processName)) {
6509                 enableTrackAllocation = true;
6510                 mTrackAllocationApp = null;
6511             }
6512
6513             // If the app is being launched for restore or full backup, set it up specially
6514             boolean isRestrictedBackupMode = false;
6515             if (mBackupTarget != null && mBackupAppName.equals(processName)) {
6516                 isRestrictedBackupMode = mBackupTarget.appInfo.uid >= Process.FIRST_APPLICATION_UID
6517                         && ((mBackupTarget.backupMode == BackupRecord.RESTORE)
6518                                 || (mBackupTarget.backupMode == BackupRecord.RESTORE_FULL)
6519                                 || (mBackupTarget.backupMode == BackupRecord.BACKUP_FULL));
6520             }
6521
6522             if (app.instrumentationClass != null) {
6523                 notifyPackageUse(app.instrumentationClass.getPackageName(),
6524                                  PackageManager.NOTIFY_PACKAGE_USE_INSTRUMENTATION);
6525             }
6526             if (DEBUG_CONFIGURATION) Slog.v(TAG_CONFIGURATION, "Binding proc "
6527                     + processName + " with config " + mConfiguration);
6528             ApplicationInfo appInfo = app.instrumentationInfo != null
6529                     ? app.instrumentationInfo : app.info;
6530             app.compat = compatibilityInfoForPackageLocked(appInfo);
6531             if (profileFd != null) {
6532                 profileFd = profileFd.dup();
6533             }
6534             ProfilerInfo profilerInfo = profileFile == null ? null
6535                     : new ProfilerInfo(profileFile, profileFd, samplingInterval, profileAutoStop);
6536             thread.bindApplication(processName, appInfo, providers, app.instrumentationClass,
6537                     profilerInfo, app.instrumentationArguments, app.instrumentationWatcher,
6538                     app.instrumentationUiAutomationConnection, testMode,
6539                     mBinderTransactionTrackingEnabled, enableTrackAllocation,
6540                     isRestrictedBackupMode || !normalMode, app.persistent,
6541                     new Configuration(mConfiguration), app.compat,
6542                     getCommonServicesLocked(app.isolated),
6543                     mCoreSettingsObserver.getCoreSettingsLocked());
6544             updateLruProcessLocked(app, false, null);
6545             app.lastRequestedGc = app.lastLowMemory = SystemClock.uptimeMillis();
6546         } catch (Exception e) {
6547             // todo: Yikes!  What should we do?  For now we will try to
6548             // start another process, but that could easily get us in
6549             // an infinite loop of restarting processes...
6550             Slog.wtf(TAG, "Exception thrown during bind of " + app, e);
6551
6552             app.resetPackageList(mProcessStats);
6553             app.unlinkDeathRecipient();
6554             startProcessLocked(app, "bind fail", processName);
6555             return false;
6556         }
6557
6558         // Remove this record from the list of starting applications.
6559         mPersistentStartingProcesses.remove(app);
6560         if (DEBUG_PROCESSES && mProcessesOnHold.contains(app)) Slog.v(TAG_PROCESSES,
6561                 "Attach application locked removing on hold: " + app);
6562         mProcessesOnHold.remove(app);
6563
6564         boolean badApp = false;
6565         boolean didSomething = false;
6566
6567         // See if the top visible activity is waiting to run in this process...
6568         if (normalMode) {
6569             try {
6570                 if (mStackSupervisor.attachApplicationLocked(app)) {
6571                     didSomething = true;
6572                 }
6573             } catch (Exception e) {
6574                 Slog.wtf(TAG, "Exception thrown launching activities in " + app, e);
6575                 badApp = true;
6576             }
6577         }
6578
6579         // Find any services that should be running in this process...
6580         if (!badApp) {
6581             try {
6582                 didSomething |= mServices.attachApplicationLocked(app, processName);
6583             } catch (Exception e) {
6584                 Slog.wtf(TAG, "Exception thrown starting services in " + app, e);
6585                 badApp = true;
6586             }
6587         }
6588
6589         // Check if a next-broadcast receiver is in this process...
6590         if (!badApp && isPendingBroadcastProcessLocked(pid)) {
6591             try {
6592                 didSomething |= sendPendingBroadcastsLocked(app);
6593             } catch (Exception e) {
6594                 // If the app died trying to launch the receiver we declare it 'bad'
6595                 Slog.wtf(TAG, "Exception thrown dispatching broadcasts in " + app, e);
6596                 badApp = true;
6597             }
6598         }
6599
6600         // Check whether the next backup agent is in this process...
6601         if (!badApp && mBackupTarget != null && mBackupTarget.appInfo.uid == app.uid) {
6602             if (DEBUG_BACKUP) Slog.v(TAG_BACKUP,
6603                     "New app is backup target, launching agent for " + app);
6604             notifyPackageUse(mBackupTarget.appInfo.packageName,
6605                              PackageManager.NOTIFY_PACKAGE_USE_BACKUP);
6606             try {
6607                 thread.scheduleCreateBackupAgent(mBackupTarget.appInfo,
6608                         compatibilityInfoForPackageLocked(mBackupTarget.appInfo),
6609                         mBackupTarget.backupMode);
6610             } catch (Exception e) {
6611                 Slog.wtf(TAG, "Exception thrown creating backup agent in " + app, e);
6612                 badApp = true;
6613             }
6614         }
6615
6616         if (badApp) {
6617             app.kill("error during init", true);
6618             handleAppDiedLocked(app, false, true);
6619             return false;
6620         }
6621
6622         if (!didSomething) {
6623             updateOomAdjLocked();
6624         }
6625
6626         return true;
6627     }
6628
6629     @Override
6630     public final void attachApplication(IApplicationThread thread) {
6631         synchronized (this) {
6632             int callingPid = Binder.getCallingPid();
6633             final long origId = Binder.clearCallingIdentity();
6634             attachApplicationLocked(thread, callingPid);
6635             Binder.restoreCallingIdentity(origId);
6636         }
6637     }
6638
6639     @Override
6640     public final void activityIdle(IBinder token, Configuration config, boolean stopProfiling) {
6641         final long origId = Binder.clearCallingIdentity();
6642         synchronized (this) {
6643             ActivityStack stack = ActivityRecord.getStackLocked(token);
6644             if (stack != null) {
6645                 ActivityRecord r =
6646                         mStackSupervisor.activityIdleInternalLocked(token, false, config);
6647                 if (stopProfiling) {
6648                     if ((mProfileProc == r.app) && (mProfileFd != null)) {
6649                         try {
6650                             mProfileFd.close();
6651                         } catch (IOException e) {
6652                         }
6653                         clearProfilerLocked();
6654                     }
6655                 }
6656             }
6657         }
6658         Binder.restoreCallingIdentity(origId);
6659     }
6660
6661     void postFinishBooting(boolean finishBooting, boolean enableScreen) {
6662         mHandler.sendMessage(mHandler.obtainMessage(FINISH_BOOTING_MSG,
6663                 finishBooting ? 1 : 0, enableScreen ? 1 : 0));
6664     }
6665
6666     void enableScreenAfterBoot() {
6667         EventLog.writeEvent(EventLogTags.BOOT_PROGRESS_ENABLE_SCREEN,
6668                 SystemClock.uptimeMillis());
6669         mWindowManager.enableScreenAfterBoot();
6670
6671         synchronized (this) {
6672             updateEventDispatchingLocked();
6673         }
6674     }
6675
6676     @Override
6677     public void showBootMessage(final CharSequence msg, final boolean always) {
6678         if (Binder.getCallingUid() != Process.myUid()) {
6679             // These days only the core system can call this, so apps can't get in
6680             // the way of what we show about running them.
6681         }
6682         mWindowManager.showBootMessage(msg, always);
6683     }
6684
6685     @Override
6686     public void keyguardWaitingForActivityDrawn() {
6687         enforceNotIsolatedCaller("keyguardWaitingForActivityDrawn");
6688         final long token = Binder.clearCallingIdentity();
6689         try {
6690             synchronized (this) {
6691                 if (DEBUG_LOCKSCREEN) logLockScreen("");
6692                 mWindowManager.keyguardWaitingForActivityDrawn();
6693                 if (mLockScreenShown == LOCK_SCREEN_SHOWN) {
6694                     mLockScreenShown = LOCK_SCREEN_LEAVING;
6695                     updateSleepIfNeededLocked();
6696                 }
6697             }
6698         } finally {
6699             Binder.restoreCallingIdentity(token);
6700         }
6701     }
6702
6703     @Override
6704     public void keyguardGoingAway(int flags) {
6705         enforceNotIsolatedCaller("keyguardGoingAway");
6706         final long token = Binder.clearCallingIdentity();
6707         try {
6708             synchronized (this) {
6709                 if (DEBUG_LOCKSCREEN) logLockScreen("");
6710                 mWindowManager.keyguardGoingAway(flags);
6711                 if (mLockScreenShown == LOCK_SCREEN_SHOWN) {
6712                     mLockScreenShown = LOCK_SCREEN_HIDDEN;
6713                     updateSleepIfNeededLocked();
6714
6715                     // Some stack visibility might change (e.g. docked stack)
6716                     mStackSupervisor.ensureActivitiesVisibleLocked(null, 0, !PRESERVE_WINDOWS);
6717                     applyVrModeIfNeededLocked(mFocusedActivity, true);
6718                 }
6719             }
6720         } finally {
6721             Binder.restoreCallingIdentity(token);
6722         }
6723     }
6724
6725     final void finishBooting() {
6726         synchronized (this) {
6727             if (!mBootAnimationComplete) {
6728                 mCallFinishBooting = true;
6729                 return;
6730             }
6731             mCallFinishBooting = false;
6732         }
6733
6734         ArraySet<String> completedIsas = new ArraySet<String>();
6735         for (String abi : Build.SUPPORTED_ABIS) {
6736             Process.establishZygoteConnectionForAbi(abi);
6737             final String instructionSet = VMRuntime.getInstructionSet(abi);
6738             if (!completedIsas.contains(instructionSet)) {
6739                 try {
6740                     mInstaller.markBootComplete(VMRuntime.getInstructionSet(abi));
6741                 } catch (InstallerException e) {
6742                     Slog.w(TAG, "Unable to mark boot complete for abi: " + abi + " (" +
6743                             e.getMessage() +")");
6744                 }
6745                 completedIsas.add(instructionSet);
6746             }
6747         }
6748
6749         IntentFilter pkgFilter = new IntentFilter();
6750         pkgFilter.addAction(Intent.ACTION_QUERY_PACKAGE_RESTART);
6751         pkgFilter.addDataScheme("package");
6752         mContext.registerReceiver(new BroadcastReceiver() {
6753             @Override
6754             public void onReceive(Context context, Intent intent) {
6755                 String[] pkgs = intent.getStringArrayExtra(Intent.EXTRA_PACKAGES);
6756                 if (pkgs != null) {
6757                     for (String pkg : pkgs) {
6758                         synchronized (ActivityManagerService.this) {
6759                             if (forceStopPackageLocked(pkg, -1, false, false, false, false, false,
6760                                     0, "query restart")) {
6761                                 setResultCode(Activity.RESULT_OK);
6762                                 return;
6763                             }
6764                         }
6765                     }
6766                 }
6767             }
6768         }, pkgFilter);
6769
6770         IntentFilter dumpheapFilter = new IntentFilter();
6771         dumpheapFilter.addAction(DumpHeapActivity.ACTION_DELETE_DUMPHEAP);
6772         mContext.registerReceiver(new BroadcastReceiver() {
6773             @Override
6774             public void onReceive(Context context, Intent intent) {
6775                 if (intent.getBooleanExtra(DumpHeapActivity.EXTRA_DELAY_DELETE, false)) {
6776                     mHandler.sendEmptyMessageDelayed(POST_DUMP_HEAP_NOTIFICATION_MSG, 5*60*1000);
6777                 } else {
6778                     mHandler.sendEmptyMessage(POST_DUMP_HEAP_NOTIFICATION_MSG);
6779                 }
6780             }
6781         }, dumpheapFilter);
6782
6783         // Let system services know.
6784         mSystemServiceManager.startBootPhase(SystemService.PHASE_BOOT_COMPLETED);
6785
6786         synchronized (this) {
6787             // Ensure that any processes we had put on hold are now started
6788             // up.
6789             final int NP = mProcessesOnHold.size();
6790             if (NP > 0) {
6791                 ArrayList<ProcessRecord> procs =
6792                     new ArrayList<ProcessRecord>(mProcessesOnHold);
6793                 for (int ip=0; ip<NP; ip++) {
6794                     if (DEBUG_PROCESSES) Slog.v(TAG_PROCESSES, "Starting process on hold: "
6795                             + procs.get(ip));
6796                     startProcessLocked(procs.get(ip), "on-hold", null);
6797                 }
6798             }
6799
6800             if (mFactoryTest != FactoryTest.FACTORY_TEST_LOW_LEVEL) {
6801                 // Start looking for apps that are abusing wake locks.
6802                 Message nmsg = mHandler.obtainMessage(CHECK_EXCESSIVE_WAKE_LOCKS_MSG);
6803                 mHandler.sendMessageDelayed(nmsg, POWER_CHECK_DELAY);
6804                 // Tell anyone interested that we are done booting!
6805                 SystemProperties.set("sys.boot_completed", "1");
6806
6807                 // And trigger dev.bootcomplete if we are not showing encryption progress
6808                 if (!"trigger_restart_min_framework".equals(SystemProperties.get("vold.decrypt"))
6809                     || "".equals(SystemProperties.get("vold.encrypt_progress"))) {
6810                     SystemProperties.set("dev.bootcomplete", "1");
6811                 }
6812                 mUserController.sendBootCompletedLocked(
6813                         new IIntentReceiver.Stub() {
6814                             @Override
6815                             public void performReceive(Intent intent, int resultCode,
6816                                     String data, Bundle extras, boolean ordered,
6817                                     boolean sticky, int sendingUser) {
6818                                 synchronized (ActivityManagerService.this) {
6819                                     requestPssAllProcsLocked(SystemClock.uptimeMillis(),
6820                                             true, false);
6821                                 }
6822                             }
6823                         });
6824                 scheduleStartProfilesLocked();
6825             }
6826         }
6827     }
6828
6829     @Override
6830     public void bootAnimationComplete() {
6831         final boolean callFinishBooting;
6832         synchronized (this) {
6833             callFinishBooting = mCallFinishBooting;
6834             mBootAnimationComplete = true;
6835         }
6836         if (callFinishBooting) {
6837             Trace.traceBegin(Trace.TRACE_TAG_ACTIVITY_MANAGER, "FinishBooting");
6838             finishBooting();
6839             Trace.traceEnd(Trace.TRACE_TAG_ACTIVITY_MANAGER);
6840         }
6841     }
6842
6843     final void ensureBootCompleted() {
6844         boolean booting;
6845         boolean enableScreen;
6846         synchronized (this) {
6847             booting = mBooting;
6848             mBooting = false;
6849             enableScreen = !mBooted;
6850             mBooted = true;
6851         }
6852
6853         if (booting) {
6854             Trace.traceBegin(Trace.TRACE_TAG_ACTIVITY_MANAGER, "FinishBooting");
6855             finishBooting();
6856             Trace.traceEnd(Trace.TRACE_TAG_ACTIVITY_MANAGER);
6857         }
6858
6859         if (enableScreen) {
6860             enableScreenAfterBoot();
6861         }
6862     }
6863
6864     @Override
6865     public final void activityResumed(IBinder token) {
6866         final long origId = Binder.clearCallingIdentity();
6867         synchronized(this) {
6868             ActivityStack stack = ActivityRecord.getStackLocked(token);
6869             if (stack != null) {
6870                 stack.activityResumedLocked(token);
6871             }
6872         }
6873         Binder.restoreCallingIdentity(origId);
6874     }
6875
6876     @Override
6877     public final void activityPaused(IBinder token) {
6878         final long origId = Binder.clearCallingIdentity();
6879         synchronized(this) {
6880             ActivityStack stack = ActivityRecord.getStackLocked(token);
6881             if (stack != null) {
6882                 stack.activityPausedLocked(token, false);
6883             }
6884         }
6885         Binder.restoreCallingIdentity(origId);
6886     }
6887
6888     @Override
6889     public final void activityStopped(IBinder token, Bundle icicle,
6890             PersistableBundle persistentState, CharSequence description) {
6891         if (DEBUG_ALL) Slog.v(TAG, "Activity stopped: token=" + token);
6892
6893         // Refuse possible leaked file descriptors
6894         if (icicle != null && icicle.hasFileDescriptors()) {
6895             throw new IllegalArgumentException("File descriptors passed in Bundle");
6896         }
6897
6898         final long origId = Binder.clearCallingIdentity();
6899
6900         synchronized (this) {
6901             ActivityRecord r = ActivityRecord.isInStackLocked(token);
6902             if (r != null) {
6903                 r.task.stack.activityStoppedLocked(r, icicle, persistentState, description);
6904             }
6905         }
6906
6907         trimApplications();
6908
6909         Binder.restoreCallingIdentity(origId);
6910     }
6911
6912     @Override
6913     public final void activityDestroyed(IBinder token) {
6914         if (DEBUG_SWITCH) Slog.v(TAG_SWITCH, "ACTIVITY DESTROYED: " + token);
6915         synchronized (this) {
6916             ActivityStack stack = ActivityRecord.getStackLocked(token);
6917             if (stack != null) {
6918                 stack.activityDestroyedLocked(token, "activityDestroyed");
6919             }
6920         }
6921     }
6922
6923     @Override
6924     public final void activityRelaunched(IBinder token) {
6925         final long origId = Binder.clearCallingIdentity();
6926         synchronized (this) {
6927             mStackSupervisor.activityRelaunchedLocked(token);
6928         }
6929         Binder.restoreCallingIdentity(origId);
6930     }
6931
6932     @Override
6933     public void reportSizeConfigurations(IBinder token, int[] horizontalSizeConfiguration,
6934             int[] verticalSizeConfigurations, int[] smallestSizeConfigurations) {
6935         if (DEBUG_CONFIGURATION) Slog.v(TAG, "Report configuration: " + token + " "
6936                 + horizontalSizeConfiguration + " " + verticalSizeConfigurations);
6937         synchronized (this) {
6938             ActivityRecord record = ActivityRecord.isInStackLocked(token);
6939             if (record == null) {
6940                 throw new IllegalArgumentException("reportSizeConfigurations: ActivityRecord not "
6941                         + "found for: " + token);
6942             }
6943             record.setSizeConfigurations(horizontalSizeConfiguration,
6944                     verticalSizeConfigurations, smallestSizeConfigurations);
6945         }
6946     }
6947
6948     @Override
6949     public final void backgroundResourcesReleased(IBinder token) {
6950         final long origId = Binder.clearCallingIdentity();
6951         try {
6952             synchronized (this) {
6953                 ActivityStack stack = ActivityRecord.getStackLocked(token);
6954                 if (stack != null) {
6955                     stack.backgroundResourcesReleased();
6956                 }
6957             }
6958         } finally {
6959             Binder.restoreCallingIdentity(origId);
6960         }
6961     }
6962
6963     @Override
6964     public final void notifyLaunchTaskBehindComplete(IBinder token) {
6965         mStackSupervisor.scheduleLaunchTaskBehindComplete(token);
6966     }
6967
6968     @Override
6969     public final void notifyEnterAnimationComplete(IBinder token) {
6970         mHandler.sendMessage(mHandler.obtainMessage(ENTER_ANIMATION_COMPLETE_MSG, token));
6971     }
6972
6973     @Override
6974     public String getCallingPackage(IBinder token) {
6975         synchronized (this) {
6976             ActivityRecord r = getCallingRecordLocked(token);
6977             return r != null ? r.info.packageName : null;
6978         }
6979     }
6980
6981     @Override
6982     public ComponentName getCallingActivity(IBinder token) {
6983         synchronized (this) {
6984             ActivityRecord r = getCallingRecordLocked(token);
6985             return r != null ? r.intent.getComponent() : null;
6986         }
6987     }
6988
6989     private ActivityRecord getCallingRecordLocked(IBinder token) {
6990         ActivityRecord r = ActivityRecord.isInStackLocked(token);
6991         if (r == null) {
6992             return null;
6993         }
6994         return r.resultTo;
6995     }
6996
6997     @Override
6998     public ComponentName getActivityClassForToken(IBinder token) {
6999         synchronized(this) {
7000             ActivityRecord r = ActivityRecord.isInStackLocked(token);
7001             if (r == null) {
7002                 return null;
7003             }
7004             return r.intent.getComponent();
7005         }
7006     }
7007
7008     @Override
7009     public String getPackageForToken(IBinder token) {
7010         synchronized(this) {
7011             ActivityRecord r = ActivityRecord.isInStackLocked(token);
7012             if (r == null) {
7013                 return null;
7014             }
7015             return r.packageName;
7016         }
7017     }
7018
7019     @Override
7020     public boolean isRootVoiceInteraction(IBinder token) {
7021         synchronized(this) {
7022             ActivityRecord r = ActivityRecord.isInStackLocked(token);
7023             if (r == null) {
7024                 return false;
7025             }
7026             return r.rootVoiceInteraction;
7027         }
7028     }
7029
7030     @Override
7031     public IIntentSender getIntentSender(int type,
7032             String packageName, IBinder token, String resultWho,
7033             int requestCode, Intent[] intents, String[] resolvedTypes,
7034             int flags, Bundle bOptions, int userId) {
7035         enforceNotIsolatedCaller("getIntentSender");
7036         // Refuse possible leaked file descriptors
7037         if (intents != null) {
7038             if (intents.length < 1) {
7039                 throw new IllegalArgumentException("Intents array length must be >= 1");
7040             }
7041             for (int i=0; i<intents.length; i++) {
7042                 Intent intent = intents[i];
7043                 if (intent != null) {
7044                     if (intent.hasFileDescriptors()) {
7045                         throw new IllegalArgumentException("File descriptors passed in Intent");
7046                     }
7047                     if (type == ActivityManager.INTENT_SENDER_BROADCAST &&
7048                             (intent.getFlags()&Intent.FLAG_RECEIVER_BOOT_UPGRADE) != 0) {
7049                         throw new IllegalArgumentException(
7050                                 "Can't use FLAG_RECEIVER_BOOT_UPGRADE here");
7051                     }
7052                     intents[i] = new Intent(intent);
7053                 }
7054             }
7055             if (resolvedTypes != null && resolvedTypes.length != intents.length) {
7056                 throw new IllegalArgumentException(
7057                         "Intent array length does not match resolvedTypes length");
7058             }
7059         }
7060         if (bOptions != null) {
7061             if (bOptions.hasFileDescriptors()) {
7062                 throw new IllegalArgumentException("File descriptors passed in options");
7063             }
7064         }
7065
7066         synchronized(this) {
7067             int callingUid = Binder.getCallingUid();
7068             int origUserId = userId;
7069             userId = mUserController.handleIncomingUser(Binder.getCallingPid(), callingUid, userId,
7070                     type == ActivityManager.INTENT_SENDER_BROADCAST,
7071                     ALLOW_NON_FULL, "getIntentSender", null);
7072             if (origUserId == UserHandle.USER_CURRENT) {
7073                 // We don't want to evaluate this until the pending intent is
7074                 // actually executed.  However, we do want to always do the
7075                 // security checking for it above.
7076                 userId = UserHandle.USER_CURRENT;
7077             }
7078             try {
7079                 if (callingUid != 0 && callingUid != Process.SYSTEM_UID) {
7080                     final int uid = AppGlobals.getPackageManager().getPackageUid(packageName,
7081                             MATCH_DEBUG_TRIAGED_MISSING, UserHandle.getUserId(callingUid));
7082                     if (!UserHandle.isSameApp(callingUid, uid)) {
7083                         String msg = "Permission Denial: getIntentSender() from pid="
7084                             + Binder.getCallingPid()
7085                             + ", uid=" + Binder.getCallingUid()
7086                             + ", (need uid=" + uid + ")"
7087                             + " is not allowed to send as package " + packageName;
7088                         Slog.w(TAG, msg);
7089                         throw new SecurityException(msg);
7090                     }
7091                 }
7092
7093                 return getIntentSenderLocked(type, packageName, callingUid, userId,
7094                         token, resultWho, requestCode, intents, resolvedTypes, flags, bOptions);
7095
7096             } catch (RemoteException e) {
7097                 throw new SecurityException(e);
7098             }
7099         }
7100     }
7101
7102     IIntentSender getIntentSenderLocked(int type, String packageName,
7103             int callingUid, int userId, IBinder token, String resultWho,
7104             int requestCode, Intent[] intents, String[] resolvedTypes, int flags,
7105             Bundle bOptions) {
7106         if (DEBUG_MU) Slog.v(TAG_MU, "getIntentSenderLocked(): uid=" + callingUid);
7107         ActivityRecord activity = null;
7108         if (type == ActivityManager.INTENT_SENDER_ACTIVITY_RESULT) {
7109             activity = ActivityRecord.isInStackLocked(token);
7110             if (activity == null) {
7111                 Slog.w(TAG, "Failed createPendingResult: activity " + token + " not in any stack");
7112                 return null;
7113             }
7114             if (activity.finishing) {
7115                 Slog.w(TAG, "Failed createPendingResult: activity " + activity + " is finishing");
7116                 return null;
7117             }
7118         }
7119
7120         // We're going to be splicing together extras before sending, so we're
7121         // okay poking into any contained extras.
7122         if (intents != null) {
7123             for (int i = 0; i < intents.length; i++) {
7124                 intents[i].setDefusable(true);
7125             }
7126         }
7127         Bundle.setDefusable(bOptions, true);
7128
7129         final boolean noCreate = (flags&PendingIntent.FLAG_NO_CREATE) != 0;
7130         final boolean cancelCurrent = (flags&PendingIntent.FLAG_CANCEL_CURRENT) != 0;
7131         final boolean updateCurrent = (flags&PendingIntent.FLAG_UPDATE_CURRENT) != 0;
7132         flags &= ~(PendingIntent.FLAG_NO_CREATE|PendingIntent.FLAG_CANCEL_CURRENT
7133                 |PendingIntent.FLAG_UPDATE_CURRENT);
7134
7135         PendingIntentRecord.Key key = new PendingIntentRecord.Key(
7136                 type, packageName, activity, resultWho,
7137                 requestCode, intents, resolvedTypes, flags, bOptions, userId);
7138         WeakReference<PendingIntentRecord> ref;
7139         ref = mIntentSenderRecords.get(key);
7140         PendingIntentRecord rec = ref != null ? ref.get() : null;
7141         if (rec != null) {
7142             if (!cancelCurrent) {
7143                 if (updateCurrent) {
7144                     if (rec.key.requestIntent != null) {
7145                         rec.key.requestIntent.replaceExtras(intents != null ?
7146                                 intents[intents.length - 1] : null);
7147                     }
7148                     if (intents != null) {
7149                         intents[intents.length-1] = rec.key.requestIntent;
7150                         rec.key.allIntents = intents;
7151                         rec.key.allResolvedTypes = resolvedTypes;
7152                     } else {
7153                         rec.key.allIntents = null;
7154                         rec.key.allResolvedTypes = null;
7155                     }
7156                 }
7157                 return rec;
7158             }
7159             rec.canceled = true;
7160             mIntentSenderRecords.remove(key);
7161         }
7162         if (noCreate) {
7163             return rec;
7164         }
7165         rec = new PendingIntentRecord(this, key, callingUid);
7166         mIntentSenderRecords.put(key, rec.ref);
7167         if (type == ActivityManager.INTENT_SENDER_ACTIVITY_RESULT) {
7168             if (activity.pendingResults == null) {
7169                 activity.pendingResults
7170                         = new HashSet<WeakReference<PendingIntentRecord>>();
7171             }
7172             activity.pendingResults.add(rec.ref);
7173         }
7174         return rec;
7175     }
7176
7177     @Override
7178     public int sendIntentSender(IIntentSender target, int code, Intent intent, String resolvedType,
7179             IIntentReceiver finishedReceiver, String requiredPermission, Bundle options) {
7180         if (target instanceof PendingIntentRecord) {
7181             return ((PendingIntentRecord)target).sendWithResult(code, intent, resolvedType,
7182                     finishedReceiver, requiredPermission, options);
7183         } else {
7184             if (intent == null) {
7185                 // Weird case: someone has given us their own custom IIntentSender, and now
7186                 // they have someone else trying to send to it but of course this isn't
7187                 // really a PendingIntent, so there is no base Intent, and the caller isn't
7188                 // supplying an Intent... but we never want to dispatch a null Intent to
7189                 // a receiver, so um...  let's make something up.
7190                 Slog.wtf(TAG, "Can't use null intent with direct IIntentSender call");
7191                 intent = new Intent(Intent.ACTION_MAIN);
7192             }
7193             try {
7194                 target.send(code, intent, resolvedType, null, requiredPermission, options);
7195             } catch (RemoteException e) {
7196             }
7197             // Platform code can rely on getting a result back when the send is done, but if
7198             // this intent sender is from outside of the system we can't rely on it doing that.
7199             // So instead we don't give it the result receiver, and instead just directly
7200             // report the finish immediately.
7201             if (finishedReceiver != null) {
7202                 try {
7203                     finishedReceiver.performReceive(intent, 0,
7204                             null, null, false, false, UserHandle.getCallingUserId());
7205                 } catch (RemoteException e) {
7206                 }
7207             }
7208             return 0;
7209         }
7210     }
7211
7212     /**
7213      * Whitelists {@code targetUid} to temporarily bypass Power Save mode.
7214      *
7215      * <p>{@code callerUid} must be allowed to request such whitelist by calling
7216      * {@link #addTempPowerSaveWhitelistGrantorUid(int)}.
7217      */
7218     void tempWhitelistAppForPowerSave(int callerPid, int callerUid, int targetUid, long duration) {
7219         if (DEBUG_WHITELISTS) {
7220             Slog.d(TAG, "tempWhitelistAppForPowerSave(" + callerPid + ", " + callerUid + ", "
7221                     + targetUid + ", " + duration + ")");
7222         }
7223         synchronized (mPidsSelfLocked) {
7224             final ProcessRecord pr = mPidsSelfLocked.get(callerPid);
7225             if (pr == null) {
7226                 Slog.w(TAG, "tempWhitelistAppForPowerSave() no ProcessRecord for pid " + callerPid);
7227                 return;
7228             }
7229             if (!pr.whitelistManager) {
7230                 if (DEBUG_WHITELISTS) {
7231                     Slog.d(TAG, "tempWhitelistAppForPowerSave() for target " + targetUid + ": pid "
7232                             + callerPid + " is not allowed");
7233                 }
7234                 return;
7235             }
7236         }
7237
7238         final long token = Binder.clearCallingIdentity();
7239         try {
7240             mLocalDeviceIdleController.addPowerSaveTempWhitelistAppDirect(targetUid, duration,
7241                     true, "pe from uid:" + callerUid);
7242         } finally {
7243             Binder.restoreCallingIdentity(token);
7244         }
7245     }
7246
7247     @Override
7248     public void cancelIntentSender(IIntentSender sender) {
7249         if (!(sender instanceof PendingIntentRecord)) {
7250             return;
7251         }
7252         synchronized(this) {
7253             PendingIntentRecord rec = (PendingIntentRecord)sender;
7254             try {
7255                 final int uid = AppGlobals.getPackageManager().getPackageUid(rec.key.packageName,
7256                         MATCH_DEBUG_TRIAGED_MISSING, UserHandle.getCallingUserId());
7257                 if (!UserHandle.isSameApp(uid, Binder.getCallingUid())) {
7258                     String msg = "Permission Denial: cancelIntentSender() from pid="
7259                         + Binder.getCallingPid()
7260                         + ", uid=" + Binder.getCallingUid()
7261                         + " is not allowed to cancel packges "
7262                         + rec.key.packageName;
7263                     Slog.w(TAG, msg);
7264                     throw new SecurityException(msg);
7265                 }
7266             } catch (RemoteException e) {
7267                 throw new SecurityException(e);
7268             }
7269             cancelIntentSenderLocked(rec, true);
7270         }
7271     }
7272
7273     void cancelIntentSenderLocked(PendingIntentRecord rec, boolean cleanActivity) {
7274         rec.canceled = true;
7275         mIntentSenderRecords.remove(rec.key);
7276         if (cleanActivity && rec.key.activity != null) {
7277             rec.key.activity.pendingResults.remove(rec.ref);
7278         }
7279     }
7280
7281     @Override
7282     public String getPackageForIntentSender(IIntentSender pendingResult) {
7283         if (!(pendingResult instanceof PendingIntentRecord)) {
7284             return null;
7285         }
7286         try {
7287             PendingIntentRecord res = (PendingIntentRecord)pendingResult;
7288             return res.key.packageName;
7289         } catch (ClassCastException e) {
7290         }
7291         return null;
7292     }
7293
7294     @Override
7295     public int getUidForIntentSender(IIntentSender sender) {
7296         if (sender instanceof PendingIntentRecord) {
7297             try {
7298                 PendingIntentRecord res = (PendingIntentRecord)sender;
7299                 return res.uid;
7300             } catch (ClassCastException e) {
7301             }
7302         }
7303         return -1;
7304     }
7305
7306     @Override
7307     public boolean isIntentSenderTargetedToPackage(IIntentSender pendingResult) {
7308         if (!(pendingResult instanceof PendingIntentRecord)) {
7309             return false;
7310         }
7311         try {
7312             PendingIntentRecord res = (PendingIntentRecord)pendingResult;
7313             if (res.key.allIntents == null) {
7314                 return false;
7315             }
7316             for (int i=0; i<res.key.allIntents.length; i++) {
7317                 Intent intent = res.key.allIntents[i];
7318                 if (intent.getPackage() != null && intent.getComponent() != null) {
7319                     return false;
7320                 }
7321             }
7322             return true;
7323         } catch (ClassCastException e) {
7324         }
7325         return false;
7326     }
7327
7328     @Override
7329     public boolean isIntentSenderAnActivity(IIntentSender pendingResult) {
7330         if (!(pendingResult instanceof PendingIntentRecord)) {
7331             return false;
7332         }
7333         try {
7334             PendingIntentRecord res = (PendingIntentRecord)pendingResult;
7335             if (res.key.type == ActivityManager.INTENT_SENDER_ACTIVITY) {
7336                 return true;
7337             }
7338             return false;
7339         } catch (ClassCastException e) {
7340         }
7341         return false;
7342     }
7343
7344     @Override
7345     public Intent getIntentForIntentSender(IIntentSender pendingResult) {
7346         enforceCallingPermission(Manifest.permission.GET_INTENT_SENDER_INTENT,
7347                 "getIntentForIntentSender()");
7348         if (!(pendingResult instanceof PendingIntentRecord)) {
7349             return null;
7350         }
7351         try {
7352             PendingIntentRecord res = (PendingIntentRecord)pendingResult;
7353             return res.key.requestIntent != null ? new Intent(res.key.requestIntent) : null;
7354         } catch (ClassCastException e) {
7355         }
7356         return null;
7357     }
7358
7359     @Override
7360     public String getTagForIntentSender(IIntentSender pendingResult, String prefix) {
7361         if (!(pendingResult instanceof PendingIntentRecord)) {
7362             return null;
7363         }
7364         try {
7365             PendingIntentRecord res = (PendingIntentRecord)pendingResult;
7366             synchronized (this) {
7367                 return getTagForIntentSenderLocked(res, prefix);
7368             }
7369         } catch (ClassCastException e) {
7370         }
7371         return null;
7372     }
7373
7374     String getTagForIntentSenderLocked(PendingIntentRecord res, String prefix) {
7375         final Intent intent = res.key.requestIntent;
7376         if (intent != null) {
7377             if (res.lastTag != null && res.lastTagPrefix == prefix && (res.lastTagPrefix == null
7378                     || res.lastTagPrefix.equals(prefix))) {
7379                 return res.lastTag;
7380             }
7381             res.lastTagPrefix = prefix;
7382             final StringBuilder sb = new StringBuilder(128);
7383             if (prefix != null) {
7384                 sb.append(prefix);
7385             }
7386             if (intent.getAction() != null) {
7387                 sb.append(intent.getAction());
7388             } else if (intent.getComponent() != null) {
7389                 intent.getComponent().appendShortString(sb);
7390             } else {
7391                 sb.append("?");
7392             }
7393             return res.lastTag = sb.toString();
7394         }
7395         return null;
7396     }
7397
7398     @Override
7399     public void setProcessLimit(int max) {
7400         enforceCallingPermission(android.Manifest.permission.SET_PROCESS_LIMIT,
7401                 "setProcessLimit()");
7402         synchronized (this) {
7403             mProcessLimit = max < 0 ? ProcessList.MAX_CACHED_APPS : max;
7404             mProcessLimitOverride = max;
7405         }
7406         trimApplications();
7407     }
7408
7409     @Override
7410     public int getProcessLimit() {
7411         synchronized (this) {
7412             return mProcessLimitOverride;
7413         }
7414     }
7415
7416     void foregroundTokenDied(ForegroundToken token) {
7417         synchronized (ActivityManagerService.this) {
7418             synchronized (mPidsSelfLocked) {
7419                 ForegroundToken cur
7420                     = mForegroundProcesses.get(token.pid);
7421                 if (cur != token) {
7422                     return;
7423                 }
7424                 mForegroundProcesses.remove(token.pid);
7425                 ProcessRecord pr = mPidsSelfLocked.get(token.pid);
7426                 if (pr == null) {
7427                     return;
7428                 }
7429                 pr.forcingToForeground = null;
7430                 updateProcessForegroundLocked(pr, false, false);
7431             }
7432             updateOomAdjLocked();
7433         }
7434     }
7435
7436     @Override
7437     public void setProcessForeground(IBinder token, int pid, boolean isForeground) {
7438         enforceCallingPermission(android.Manifest.permission.SET_PROCESS_LIMIT,
7439                 "setProcessForeground()");
7440         synchronized(this) {
7441             boolean changed = false;
7442
7443             synchronized (mPidsSelfLocked) {
7444                 ProcessRecord pr = mPidsSelfLocked.get(pid);
7445                 if (pr == null && isForeground) {
7446                     Slog.w(TAG, "setProcessForeground called on unknown pid: " + pid);
7447                     return;
7448                 }
7449                 ForegroundToken oldToken = mForegroundProcesses.get(pid);
7450                 if (oldToken != null) {
7451                     oldToken.token.unlinkToDeath(oldToken, 0);
7452                     mForegroundProcesses.remove(pid);
7453                     if (pr != null) {
7454                         pr.forcingToForeground = null;
7455                     }
7456                     changed = true;
7457                 }
7458                 if (isForeground && token != null) {
7459                     ForegroundToken newToken = new ForegroundToken() {
7460                         @Override
7461                         public void binderDied() {
7462                             foregroundTokenDied(this);
7463                         }
7464                     };
7465                     newToken.pid = pid;
7466                     newToken.token = token;
7467                     try {
7468                         token.linkToDeath(newToken, 0);
7469                         mForegroundProcesses.put(pid, newToken);
7470                         pr.forcingToForeground = token;
7471                         changed = true;
7472                     } catch (RemoteException e) {
7473                         // If the process died while doing this, we will later
7474                         // do the cleanup with the process death link.
7475                     }
7476                 }
7477             }
7478
7479             if (changed) {
7480                 updateOomAdjLocked();
7481             }
7482         }
7483     }
7484
7485     @Override
7486     public boolean isAppForeground(int uid) throws RemoteException {
7487         synchronized (this) {
7488             UidRecord uidRec = mActiveUids.get(uid);
7489             if (uidRec == null || uidRec.idle) {
7490                 return false;
7491             }
7492             return uidRec.curProcState <= ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND;
7493         }
7494     }
7495
7496     // NOTE: this is an internal method used by the OnShellCommand implementation only and should
7497     // be guarded by permission checking.
7498     int getUidState(int uid) {
7499         synchronized (this) {
7500             UidRecord uidRec = mActiveUids.get(uid);
7501             return uidRec == null ? ActivityManager.PROCESS_STATE_NONEXISTENT : uidRec.curProcState;
7502         }
7503     }
7504
7505     @Override
7506     public boolean isInMultiWindowMode(IBinder token) {
7507         final long origId = Binder.clearCallingIdentity();
7508         try {
7509             synchronized(this) {
7510                 final ActivityRecord r = ActivityRecord.isInStackLocked(token);
7511                 if (r == null) {
7512                     return false;
7513                 }
7514                 // An activity is consider to be in multi-window mode if its task isn't fullscreen.
7515                 return !r.task.mFullscreen;
7516             }
7517         } finally {
7518             Binder.restoreCallingIdentity(origId);
7519         }
7520     }
7521
7522     @Override
7523     public boolean isInPictureInPictureMode(IBinder token) {
7524         final long origId = Binder.clearCallingIdentity();
7525         try {
7526             synchronized(this) {
7527                 final ActivityStack stack = ActivityRecord.getStackLocked(token);
7528                 if (stack == null) {
7529                     return false;
7530                 }
7531                 return stack.mStackId == PINNED_STACK_ID;
7532             }
7533         } finally {
7534             Binder.restoreCallingIdentity(origId);
7535         }
7536     }
7537
7538     @Override
7539     public void enterPictureInPictureMode(IBinder token) {
7540         final long origId = Binder.clearCallingIdentity();
7541         try {
7542             synchronized(this) {
7543                 if (!mSupportsPictureInPicture) {
7544                     throw new IllegalStateException("enterPictureInPictureMode: "
7545                             + "Device doesn't support picture-in-picture mode.");
7546                 }
7547
7548                 final ActivityRecord r = ActivityRecord.forTokenLocked(token);
7549
7550                 if (r == null) {
7551                     throw new IllegalStateException("enterPictureInPictureMode: "
7552                             + "Can't find activity for token=" + token);
7553                 }
7554
7555                 if (!r.supportsPictureInPicture()) {
7556                     throw new IllegalArgumentException("enterPictureInPictureMode: "
7557                             + "Picture-In-Picture not supported for r=" + r);
7558                 }
7559
7560                 // Use the default launch bounds for pinned stack if it doesn't exist yet or use the
7561                 // current bounds.
7562                 final ActivityStack pinnedStack = mStackSupervisor.getStack(PINNED_STACK_ID);
7563                 final Rect bounds = (pinnedStack != null)
7564                         ? pinnedStack.mBounds : mDefaultPinnedStackBounds;
7565
7566                 mStackSupervisor.moveActivityToPinnedStackLocked(
7567                         r, "enterPictureInPictureMode", bounds);
7568             }
7569         } finally {
7570             Binder.restoreCallingIdentity(origId);
7571         }
7572     }
7573
7574     // =========================================================
7575     // PROCESS INFO
7576     // =========================================================
7577
7578     static class ProcessInfoService extends IProcessInfoService.Stub {
7579         final ActivityManagerService mActivityManagerService;
7580         ProcessInfoService(ActivityManagerService activityManagerService) {
7581             mActivityManagerService = activityManagerService;
7582         }
7583
7584         @Override
7585         public void getProcessStatesFromPids(/*in*/ int[] pids, /*out*/ int[] states) {
7586             mActivityManagerService.getProcessStatesAndOomScoresForPIDs(
7587                     /*in*/ pids, /*out*/ states, null);
7588         }
7589
7590         @Override
7591         public void getProcessStatesAndOomScoresFromPids(
7592                 /*in*/ int[] pids, /*out*/ int[] states, /*out*/ int[] scores) {
7593             mActivityManagerService.getProcessStatesAndOomScoresForPIDs(
7594                     /*in*/ pids, /*out*/ states, /*out*/ scores);
7595         }
7596     }
7597
7598     /**
7599      * For each PID in the given input array, write the current process state
7600      * for that process into the states array, or -1 to indicate that no
7601      * process with the given PID exists. If scores array is provided, write
7602      * the oom score for the process into the scores array, with INVALID_ADJ
7603      * indicating the PID doesn't exist.
7604      */
7605     public void getProcessStatesAndOomScoresForPIDs(
7606             /*in*/ int[] pids, /*out*/ int[] states, /*out*/ int[] scores) {
7607         if (scores != null) {
7608             enforceCallingPermission(android.Manifest.permission.GET_PROCESS_STATE_AND_OOM_SCORE,
7609                     "getProcessStatesAndOomScoresForPIDs()");
7610         }
7611
7612         if (pids == null) {
7613             throw new NullPointerException("pids");
7614         } else if (states == null) {
7615             throw new NullPointerException("states");
7616         } else if (pids.length != states.length) {
7617             throw new IllegalArgumentException("pids and states arrays have different lengths!");
7618         } else if (scores != null && pids.length != scores.length) {
7619             throw new IllegalArgumentException("pids and scores arrays have different lengths!");
7620         }
7621
7622         synchronized (mPidsSelfLocked) {
7623             for (int i = 0; i < pids.length; i++) {
7624                 ProcessRecord pr = mPidsSelfLocked.get(pids[i]);
7625                 states[i] = (pr == null) ? ActivityManager.PROCESS_STATE_NONEXISTENT :
7626                         pr.curProcState;
7627                 if (scores != null) {
7628                     scores[i] = (pr == null) ? ProcessList.INVALID_ADJ : pr.curAdj;
7629                 }
7630             }
7631         }
7632     }
7633
7634     // =========================================================
7635     // PERMISSIONS
7636     // =========================================================
7637
7638     static class PermissionController extends IPermissionController.Stub {
7639         ActivityManagerService mActivityManagerService;
7640         PermissionController(ActivityManagerService activityManagerService) {
7641             mActivityManagerService = activityManagerService;
7642         }
7643
7644         @Override
7645         public boolean checkPermission(String permission, int pid, int uid) {
7646             return mActivityManagerService.checkPermission(permission, pid,
7647                     uid) == PackageManager.PERMISSION_GRANTED;
7648         }
7649
7650         @Override
7651         public String[] getPackagesForUid(int uid) {
7652             return mActivityManagerService.mContext.getPackageManager()
7653                     .getPackagesForUid(uid);
7654         }
7655
7656         @Override
7657         public boolean isRuntimePermission(String permission) {
7658             try {
7659                 PermissionInfo info = mActivityManagerService.mContext.getPackageManager()
7660                         .getPermissionInfo(permission, 0);
7661                 return info.protectionLevel == PermissionInfo.PROTECTION_DANGEROUS;
7662             } catch (NameNotFoundException nnfe) {
7663                 Slog.e(TAG, "No such permission: "+ permission, nnfe);
7664             }
7665             return false;
7666         }
7667     }
7668
7669     class IntentFirewallInterface implements IntentFirewall.AMSInterface {
7670         @Override
7671         public int checkComponentPermission(String permission, int pid, int uid,
7672                 int owningUid, boolean exported) {
7673             return ActivityManagerService.this.checkComponentPermission(permission, pid, uid,
7674                     owningUid, exported);
7675         }
7676
7677         @Override
7678         public Object getAMSLock() {
7679             return ActivityManagerService.this;
7680         }
7681     }
7682
7683     /**
7684      * This can be called with or without the global lock held.
7685      */
7686     int checkComponentPermission(String permission, int pid, int uid,
7687             int owningUid, boolean exported) {
7688         if (pid == MY_PID) {
7689             return PackageManager.PERMISSION_GRANTED;
7690         }
7691         return ActivityManager.checkComponentPermission(permission, uid,
7692                 owningUid, exported);
7693     }
7694
7695     /**
7696      * As the only public entry point for permissions checking, this method
7697      * can enforce the semantic that requesting a check on a null global
7698      * permission is automatically denied.  (Internally a null permission
7699      * string is used when calling {@link #checkComponentPermission} in cases
7700      * when only uid-based security is needed.)
7701      *
7702      * This can be called with or without the global lock held.
7703      */
7704     @Override
7705     public int checkPermission(String permission, int pid, int uid) {
7706         if (permission == null) {
7707             return PackageManager.PERMISSION_DENIED;
7708         }
7709         return checkComponentPermission(permission, pid, uid, -1, true);
7710     }
7711
7712     @Override
7713     public int checkPermissionWithToken(String permission, int pid, int uid, IBinder callerToken) {
7714         if (permission == null) {
7715             return PackageManager.PERMISSION_DENIED;
7716         }
7717
7718         // We might be performing an operation on behalf of an indirect binder
7719         // invocation, e.g. via {@link #openContentUri}.  Check and adjust the
7720         // client identity accordingly before proceeding.
7721         Identity tlsIdentity = sCallerIdentity.get();
7722         if (tlsIdentity != null && tlsIdentity.token == callerToken) {
7723             Slog.d(TAG, "checkComponentPermission() adjusting {pid,uid} to {"
7724                     + tlsIdentity.pid + "," + tlsIdentity.uid + "}");
7725             uid = tlsIdentity.uid;
7726             pid = tlsIdentity.pid;
7727         }
7728
7729         return checkComponentPermission(permission, pid, uid, -1, true);
7730     }
7731
7732     /**
7733      * Binder IPC calls go through the public entry point.
7734      * This can be called with or without the global lock held.
7735      */
7736     int checkCallingPermission(String permission) {
7737         return checkPermission(permission,
7738                 Binder.getCallingPid(),
7739                 UserHandle.getAppId(Binder.getCallingUid()));
7740     }
7741
7742     /**
7743      * This can be called with or without the global lock held.
7744      */
7745     void enforceCallingPermission(String permission, String func) {
7746         if (checkCallingPermission(permission)
7747                 == PackageManager.PERMISSION_GRANTED) {
7748             return;
7749         }
7750
7751         String msg = "Permission Denial: " + func + " from pid="
7752                 + Binder.getCallingPid()
7753                 + ", uid=" + Binder.getCallingUid()
7754                 + " requires " + permission;
7755         Slog.w(TAG, msg);
7756         throw new SecurityException(msg);
7757     }
7758
7759     /**
7760      * Determine if UID is holding permissions required to access {@link Uri} in
7761      * the given {@link ProviderInfo}. Final permission checking is always done
7762      * in {@link ContentProvider}.
7763      */
7764     private final boolean checkHoldingPermissionsLocked(
7765             IPackageManager pm, ProviderInfo pi, GrantUri grantUri, int uid, final int modeFlags) {
7766         if (DEBUG_URI_PERMISSION) Slog.v(TAG_URI_PERMISSION,
7767                 "checkHoldingPermissionsLocked: uri=" + grantUri + " uid=" + uid);
7768         if (UserHandle.getUserId(uid) != grantUri.sourceUserId) {
7769             if (ActivityManager.checkComponentPermission(INTERACT_ACROSS_USERS, uid, -1, true)
7770                     != PERMISSION_GRANTED) {
7771                 return false;
7772             }
7773         }
7774         return checkHoldingPermissionsInternalLocked(pm, pi, grantUri, uid, modeFlags, true);
7775     }
7776
7777     private final boolean checkHoldingPermissionsInternalLocked(IPackageManager pm, ProviderInfo pi,
7778             GrantUri grantUri, int uid, final int modeFlags, boolean considerUidPermissions) {
7779         if (pi.applicationInfo.uid == uid) {
7780             return true;
7781         } else if (!pi.exported) {
7782             return false;
7783         }
7784
7785         boolean readMet = (modeFlags & Intent.FLAG_GRANT_READ_URI_PERMISSION) == 0;
7786         boolean writeMet = (modeFlags & Intent.FLAG_GRANT_WRITE_URI_PERMISSION) == 0;
7787         try {
7788             // check if target holds top-level <provider> permissions
7789             if (!readMet && pi.readPermission != null && considerUidPermissions
7790                     && (pm.checkUidPermission(pi.readPermission, uid) == PERMISSION_GRANTED)) {
7791                 readMet = true;
7792             }
7793             if (!writeMet && pi.writePermission != null && considerUidPermissions
7794                     && (pm.checkUidPermission(pi.writePermission, uid) == PERMISSION_GRANTED)) {
7795                 writeMet = true;
7796             }
7797
7798             // track if unprotected read/write is allowed; any denied
7799             // <path-permission> below removes this ability
7800             boolean allowDefaultRead = pi.readPermission == null;
7801             boolean allowDefaultWrite = pi.writePermission == null;
7802
7803             // check if target holds any <path-permission> that match uri
7804             final PathPermission[] pps = pi.pathPermissions;
7805             if (pps != null) {
7806                 final String path = grantUri.uri.getPath();
7807                 int i = pps.length;
7808                 while (i > 0 && (!readMet || !writeMet)) {
7809                     i--;
7810                     PathPermission pp = pps[i];
7811                     if (pp.match(path)) {
7812                         if (!readMet) {
7813                             final String pprperm = pp.getReadPermission();
7814                             if (DEBUG_URI_PERMISSION) Slog.v(TAG_URI_PERMISSION,
7815                                     "Checking read perm for " + pprperm + " for " + pp.getPath()
7816                                     + ": match=" + pp.match(path)
7817                                     + " check=" + pm.checkUidPermission(pprperm, uid));
7818                             if (pprperm != null) {
7819                                 if (considerUidPermissions && pm.checkUidPermission(pprperm, uid)
7820                                         == PERMISSION_GRANTED) {
7821                                     readMet = true;
7822                                 } else {
7823                                     allowDefaultRead = false;
7824                                 }
7825                             }
7826                         }
7827                         if (!writeMet) {
7828                             final String ppwperm = pp.getWritePermission();
7829                             if (DEBUG_URI_PERMISSION) Slog.v(TAG_URI_PERMISSION,
7830                                     "Checking write perm " + ppwperm + " for " + pp.getPath()
7831                                     + ": match=" + pp.match(path)
7832                                     + " check=" + pm.checkUidPermission(ppwperm, uid));
7833                             if (ppwperm != null) {
7834                                 if (considerUidPermissions && pm.checkUidPermission(ppwperm, uid)
7835                                         == PERMISSION_GRANTED) {
7836                                     writeMet = true;
7837                                 } else {
7838                                     allowDefaultWrite = false;
7839                                 }
7840                             }
7841                         }
7842                     }
7843                 }
7844             }
7845
7846             // grant unprotected <provider> read/write, if not blocked by
7847             // <path-permission> above
7848             if (allowDefaultRead) readMet = true;
7849             if (allowDefaultWrite) writeMet = true;
7850
7851         } catch (RemoteException e) {
7852             return false;
7853         }
7854
7855         return readMet && writeMet;
7856     }
7857
7858     public int getAppStartMode(int uid, String packageName) {
7859         synchronized (this) {
7860             return checkAllowBackgroundLocked(uid, packageName, -1, true);
7861         }
7862     }
7863
7864     int checkAllowBackgroundLocked(int uid, String packageName, int callingPid,
7865             boolean allowWhenForeground) {
7866         UidRecord uidRec = mActiveUids.get(uid);
7867         if (!mLenientBackgroundCheck) {
7868             if (!allowWhenForeground || uidRec == null
7869                     || uidRec.curProcState >= ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND) {
7870                 if (mAppOpsService.noteOperation(AppOpsManager.OP_RUN_IN_BACKGROUND, uid,
7871                         packageName) != AppOpsManager.MODE_ALLOWED) {
7872                     return ActivityManager.APP_START_MODE_DELAYED;
7873                 }
7874             }
7875
7876         } else if (uidRec == null || uidRec.idle) {
7877             if (callingPid >= 0) {
7878                 ProcessRecord proc;
7879                 synchronized (mPidsSelfLocked) {
7880                     proc = mPidsSelfLocked.get(callingPid);
7881                 }
7882                 if (proc != null && proc.curProcState < ActivityManager.PROCESS_STATE_RECEIVER) {
7883                     // Whoever is instigating this is in the foreground, so we will allow it
7884                     // to go through.
7885                     return ActivityManager.APP_START_MODE_NORMAL;
7886                 }
7887             }
7888             if (mAppOpsService.noteOperation(AppOpsManager.OP_RUN_IN_BACKGROUND, uid, packageName)
7889                     != AppOpsManager.MODE_ALLOWED) {
7890                 return ActivityManager.APP_START_MODE_DELAYED;
7891             }
7892         }
7893         return ActivityManager.APP_START_MODE_NORMAL;
7894     }
7895
7896     private ProviderInfo getProviderInfoLocked(String authority, int userHandle, int pmFlags) {
7897         ProviderInfo pi = null;
7898         ContentProviderRecord cpr = mProviderMap.getProviderByName(authority, userHandle);
7899         if (cpr != null) {
7900             pi = cpr.info;
7901         } else {
7902             try {
7903                 pi = AppGlobals.getPackageManager().resolveContentProvider(
7904                         authority, PackageManager.GET_URI_PERMISSION_PATTERNS | pmFlags,
7905                         userHandle);
7906             } catch (RemoteException ex) {
7907             }
7908         }
7909         return pi;
7910     }
7911
7912     private UriPermission findUriPermissionLocked(int targetUid, GrantUri grantUri) {
7913         final ArrayMap<GrantUri, UriPermission> targetUris = mGrantedUriPermissions.get(targetUid);
7914         if (targetUris != null) {
7915             return targetUris.get(grantUri);
7916         }
7917         return null;
7918     }
7919
7920     private UriPermission findOrCreateUriPermissionLocked(String sourcePkg,
7921             String targetPkg, int targetUid, GrantUri grantUri) {
7922         ArrayMap<GrantUri, UriPermission> targetUris = mGrantedUriPermissions.get(targetUid);
7923         if (targetUris == null) {
7924             targetUris = Maps.newArrayMap();
7925             mGrantedUriPermissions.put(targetUid, targetUris);
7926         }
7927
7928         UriPermission perm = targetUris.get(grantUri);
7929         if (perm == null) {
7930             perm = new UriPermission(sourcePkg, targetPkg, targetUid, grantUri);
7931             targetUris.put(grantUri, perm);
7932         }
7933
7934         return perm;
7935     }
7936
7937     private final boolean checkUriPermissionLocked(GrantUri grantUri, int uid,
7938             final int modeFlags) {
7939         final boolean persistable = (modeFlags & Intent.FLAG_GRANT_PERSISTABLE_URI_PERMISSION) != 0;
7940         final int minStrength = persistable ? UriPermission.STRENGTH_PERSISTABLE
7941                 : UriPermission.STRENGTH_OWNED;
7942
7943         // Root gets to do everything.
7944         if (uid == 0) {
7945             return true;
7946         }
7947
7948         final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.get(uid);
7949         if (perms == null) return false;
7950
7951         // First look for exact match
7952         final UriPermission exactPerm = perms.get(grantUri);
7953         if (exactPerm != null && exactPerm.getStrength(modeFlags) >= minStrength) {
7954             return true;
7955         }
7956
7957         // No exact match, look for prefixes
7958         final int N = perms.size();
7959         for (int i = 0; i < N; i++) {
7960             final UriPermission perm = perms.valueAt(i);
7961             if (perm.uri.prefix && grantUri.uri.isPathPrefixMatch(perm.uri.uri)
7962                     && perm.getStrength(modeFlags) >= minStrength) {
7963                 return true;
7964             }
7965         }
7966
7967         return false;
7968     }
7969
7970     /**
7971      * @param uri This uri must NOT contain an embedded userId.
7972      * @param userId The userId in which the uri is to be resolved.
7973      */
7974     @Override
7975     public int checkUriPermission(Uri uri, int pid, int uid,
7976             final int modeFlags, int userId, IBinder callerToken) {
7977         enforceNotIsolatedCaller("checkUriPermission");
7978
7979         // Another redirected-binder-call permissions check as in
7980         // {@link checkPermissionWithToken}.
7981         Identity tlsIdentity = sCallerIdentity.get();
7982         if (tlsIdentity != null && tlsIdentity.token == callerToken) {
7983             uid = tlsIdentity.uid;
7984             pid = tlsIdentity.pid;
7985         }
7986
7987         // Our own process gets to do everything.
7988         if (pid == MY_PID) {
7989             return PackageManager.PERMISSION_GRANTED;
7990         }
7991         synchronized (this) {
7992             return checkUriPermissionLocked(new GrantUri(userId, uri, false), uid, modeFlags)
7993                     ? PackageManager.PERMISSION_GRANTED
7994                     : PackageManager.PERMISSION_DENIED;
7995         }
7996     }
7997
7998     /**
7999      * Check if the targetPkg can be granted permission to access uri by
8000      * the callingUid using the given modeFlags.  Throws a security exception
8001      * if callingUid is not allowed to do this.  Returns the uid of the target
8002      * if the URI permission grant should be performed; returns -1 if it is not
8003      * needed (for example targetPkg already has permission to access the URI).
8004      * If you already know the uid of the target, you can supply it in
8005      * lastTargetUid else set that to -1.
8006      */
8007     int checkGrantUriPermissionLocked(int callingUid, String targetPkg, GrantUri grantUri,
8008             final int modeFlags, int lastTargetUid) {
8009         if (!Intent.isAccessUriMode(modeFlags)) {
8010             return -1;
8011         }
8012
8013         if (targetPkg != null) {
8014             if (DEBUG_URI_PERMISSION) Slog.v(TAG_URI_PERMISSION,
8015                     "Checking grant " + targetPkg + " permission to " + grantUri);
8016         }
8017
8018         final IPackageManager pm = AppGlobals.getPackageManager();
8019
8020         // If this is not a content: uri, we can't do anything with it.
8021         if (!ContentResolver.SCHEME_CONTENT.equals(grantUri.uri.getScheme())) {
8022             if (DEBUG_URI_PERMISSION) Slog.v(TAG_URI_PERMISSION,
8023                     "Can't grant URI permission for non-content URI: " + grantUri);
8024             return -1;
8025         }
8026
8027         final String authority = grantUri.uri.getAuthority();
8028         final ProviderInfo pi = getProviderInfoLocked(authority, grantUri.sourceUserId,
8029                 MATCH_DEBUG_TRIAGED_MISSING);
8030         if (pi == null) {
8031             Slog.w(TAG, "No content provider found for permission check: " +
8032                     grantUri.uri.toSafeString());
8033             return -1;
8034         }
8035
8036         int targetUid = lastTargetUid;
8037         if (targetUid < 0 && targetPkg != null) {
8038             try {
8039                 targetUid = pm.getPackageUid(targetPkg, MATCH_DEBUG_TRIAGED_MISSING,
8040                         UserHandle.getUserId(callingUid));
8041                 if (targetUid < 0) {
8042                     if (DEBUG_URI_PERMISSION) Slog.v(TAG_URI_PERMISSION,
8043                             "Can't grant URI permission no uid for: " + targetPkg);
8044                     return -1;
8045                 }
8046             } catch (RemoteException ex) {
8047                 return -1;
8048             }
8049         }
8050
8051         if (targetUid >= 0) {
8052             // First...  does the target actually need this permission?
8053             if (checkHoldingPermissionsLocked(pm, pi, grantUri, targetUid, modeFlags)) {
8054                 // No need to grant the target this permission.
8055                 if (DEBUG_URI_PERMISSION) Slog.v(TAG_URI_PERMISSION,
8056                         "Target " + targetPkg + " already has full permission to " + grantUri);
8057                 return -1;
8058             }
8059         } else {
8060             // First...  there is no target package, so can anyone access it?
8061             boolean allowed = pi.exported;
8062             if ((modeFlags&Intent.FLAG_GRANT_READ_URI_PERMISSION) != 0) {
8063                 if (pi.readPermission != null) {
8064                     allowed = false;
8065                 }
8066             }
8067             if ((modeFlags&Intent.FLAG_GRANT_WRITE_URI_PERMISSION) != 0) {
8068                 if (pi.writePermission != null) {
8069                     allowed = false;
8070                 }
8071             }
8072             if (allowed) {
8073                 return -1;
8074             }
8075         }
8076
8077         /* There is a special cross user grant if:
8078          * - The target is on another user.
8079          * - Apps on the current user can access the uri without any uid permissions.
8080          * In this case, we grant a uri permission, even if the ContentProvider does not normally
8081          * grant uri permissions.
8082          */
8083         boolean specialCrossUserGrant = UserHandle.getUserId(targetUid) != grantUri.sourceUserId
8084                 && checkHoldingPermissionsInternalLocked(pm, pi, grantUri, callingUid,
8085                 modeFlags, false /*without considering the uid permissions*/);
8086
8087         // Second...  is the provider allowing granting of URI permissions?
8088         if (!specialCrossUserGrant) {
8089             if (!pi.grantUriPermissions) {
8090                 throw new SecurityException("Provider " + pi.packageName
8091                         + "/" + pi.name
8092                         + " does not allow granting of Uri permissions (uri "
8093                         + grantUri + ")");
8094             }
8095             if (pi.uriPermissionPatterns != null) {
8096                 final int N = pi.uriPermissionPatterns.length;
8097                 boolean allowed = false;
8098                 for (int i=0; i<N; i++) {
8099                     if (pi.uriPermissionPatterns[i] != null
8100                             && pi.uriPermissionPatterns[i].match(grantUri.uri.getPath())) {
8101                         allowed = true;
8102                         break;
8103                     }
8104                 }
8105                 if (!allowed) {
8106                     throw new SecurityException("Provider " + pi.packageName
8107                             + "/" + pi.name
8108                             + " does not allow granting of permission to path of Uri "
8109                             + grantUri);
8110                 }
8111             }
8112         }
8113
8114         // Third...  does the caller itself have permission to access
8115         // this uri?
8116         final int callingAppId = UserHandle.getAppId(callingUid);
8117         if ((callingAppId == Process.SYSTEM_UID) || (callingAppId == Process.ROOT_UID)) {
8118             Slog.w(TAG, "For security reasons, the system cannot issue a Uri permission"
8119                     + " grant to " + grantUri + "; use startActivityAsCaller() instead");
8120             return -1;
8121         } else {
8122             if (!checkHoldingPermissionsLocked(pm, pi, grantUri, callingUid, modeFlags)) {
8123                 // Require they hold a strong enough Uri permission
8124                 if (!checkUriPermissionLocked(grantUri, callingUid, modeFlags)) {
8125                     throw new SecurityException("Uid " + callingUid
8126                             + " does not have permission to uri " + grantUri);
8127                 }
8128             }
8129         }
8130         return targetUid;
8131     }
8132
8133     /**
8134      * @param uri This uri must NOT contain an embedded userId.
8135      * @param userId The userId in which the uri is to be resolved.
8136      */
8137     @Override
8138     public int checkGrantUriPermission(int callingUid, String targetPkg, Uri uri,
8139             final int modeFlags, int userId) {
8140         enforceNotIsolatedCaller("checkGrantUriPermission");
8141         synchronized(this) {
8142             return checkGrantUriPermissionLocked(callingUid, targetPkg,
8143                     new GrantUri(userId, uri, false), modeFlags, -1);
8144         }
8145     }
8146
8147     void grantUriPermissionUncheckedLocked(int targetUid, String targetPkg, GrantUri grantUri,
8148             final int modeFlags, UriPermissionOwner owner) {
8149         if (!Intent.isAccessUriMode(modeFlags)) {
8150             return;
8151         }
8152
8153         // So here we are: the caller has the assumed permission
8154         // to the uri, and the target doesn't.  Let's now give this to
8155         // the target.
8156
8157         if (DEBUG_URI_PERMISSION) Slog.v(TAG_URI_PERMISSION,
8158                 "Granting " + targetPkg + "/" + targetUid + " permission to " + grantUri);
8159
8160         final String authority = grantUri.uri.getAuthority();
8161         final ProviderInfo pi = getProviderInfoLocked(authority, grantUri.sourceUserId,
8162                 MATCH_DEBUG_TRIAGED_MISSING);
8163         if (pi == null) {
8164             Slog.w(TAG, "No content provider found for grant: " + grantUri.toSafeString());
8165             return;
8166         }
8167
8168         if ((modeFlags & Intent.FLAG_GRANT_PREFIX_URI_PERMISSION) != 0) {
8169             grantUri.prefix = true;
8170         }
8171         final UriPermission perm = findOrCreateUriPermissionLocked(
8172                 pi.packageName, targetPkg, targetUid, grantUri);
8173         perm.grantModes(modeFlags, owner);
8174     }
8175
8176     void grantUriPermissionLocked(int callingUid, String targetPkg, GrantUri grantUri,
8177             final int modeFlags, UriPermissionOwner owner, int targetUserId) {
8178         if (targetPkg == null) {
8179             throw new NullPointerException("targetPkg");
8180         }
8181         int targetUid;
8182         final IPackageManager pm = AppGlobals.getPackageManager();
8183         try {
8184             targetUid = pm.getPackageUid(targetPkg, MATCH_DEBUG_TRIAGED_MISSING, targetUserId);
8185         } catch (RemoteException ex) {
8186             return;
8187         }
8188
8189         targetUid = checkGrantUriPermissionLocked(callingUid, targetPkg, grantUri, modeFlags,
8190                 targetUid);
8191         if (targetUid < 0) {
8192             return;
8193         }
8194
8195         grantUriPermissionUncheckedLocked(targetUid, targetPkg, grantUri, modeFlags,
8196                 owner);
8197     }
8198
8199     static class NeededUriGrants extends ArrayList<GrantUri> {
8200         final String targetPkg;
8201         final int targetUid;
8202         final int flags;
8203
8204         NeededUriGrants(String targetPkg, int targetUid, int flags) {
8205             this.targetPkg = targetPkg;
8206             this.targetUid = targetUid;
8207             this.flags = flags;
8208         }
8209     }
8210
8211     /**
8212      * Like checkGrantUriPermissionLocked, but takes an Intent.
8213      */
8214     NeededUriGrants checkGrantUriPermissionFromIntentLocked(int callingUid,
8215             String targetPkg, Intent intent, int mode, NeededUriGrants needed, int targetUserId) {
8216         if (DEBUG_URI_PERMISSION) Slog.v(TAG_URI_PERMISSION,
8217                 "Checking URI perm to data=" + (intent != null ? intent.getData() : null)
8218                 + " clip=" + (intent != null ? intent.getClipData() : null)
8219                 + " from " + intent + "; flags=0x"
8220                 + Integer.toHexString(intent != null ? intent.getFlags() : 0));
8221
8222         if (targetPkg == null) {
8223             throw new NullPointerException("targetPkg");
8224         }
8225
8226         if (intent == null) {
8227             return null;
8228         }
8229         Uri data = intent.getData();
8230         ClipData clip = intent.getClipData();
8231         if (data == null && clip == null) {
8232             return null;
8233         }
8234         // Default userId for uris in the intent (if they don't specify it themselves)
8235         int contentUserHint = intent.getContentUserHint();
8236         if (contentUserHint == UserHandle.USER_CURRENT) {
8237             contentUserHint = UserHandle.getUserId(callingUid);
8238         }
8239         final IPackageManager pm = AppGlobals.getPackageManager();
8240         int targetUid;
8241         if (needed != null) {
8242             targetUid = needed.targetUid;
8243         } else {
8244             try {
8245                 targetUid = pm.getPackageUid(targetPkg, MATCH_DEBUG_TRIAGED_MISSING,
8246                         targetUserId);
8247             } catch (RemoteException ex) {
8248                 return null;
8249             }
8250             if (targetUid < 0) {
8251                 if (DEBUG_URI_PERMISSION) Slog.v(TAG_URI_PERMISSION,
8252                         "Can't grant URI permission no uid for: " + targetPkg
8253                         + " on user " + targetUserId);
8254                 return null;
8255             }
8256         }
8257         if (data != null) {
8258             GrantUri grantUri = GrantUri.resolve(contentUserHint, data);
8259             targetUid = checkGrantUriPermissionLocked(callingUid, targetPkg, grantUri, mode,
8260                     targetUid);
8261             if (targetUid > 0) {
8262                 if (needed == null) {
8263                     needed = new NeededUriGrants(targetPkg, targetUid, mode);
8264                 }
8265                 needed.add(grantUri);
8266             }
8267         }
8268         if (clip != null) {
8269             for (int i=0; i<clip.getItemCount(); i++) {
8270                 Uri uri = clip.getItemAt(i).getUri();
8271                 if (uri != null) {
8272                     GrantUri grantUri = GrantUri.resolve(contentUserHint, uri);
8273                     targetUid = checkGrantUriPermissionLocked(callingUid, targetPkg, grantUri, mode,
8274                             targetUid);
8275                     if (targetUid > 0) {
8276                         if (needed == null) {
8277                             needed = new NeededUriGrants(targetPkg, targetUid, mode);
8278                         }
8279                         needed.add(grantUri);
8280                     }
8281                 } else {
8282                     Intent clipIntent = clip.getItemAt(i).getIntent();
8283                     if (clipIntent != null) {
8284                         NeededUriGrants newNeeded = checkGrantUriPermissionFromIntentLocked(
8285                                 callingUid, targetPkg, clipIntent, mode, needed, targetUserId);
8286                         if (newNeeded != null) {
8287                             needed = newNeeded;
8288                         }
8289                     }
8290                 }
8291             }
8292         }
8293
8294         return needed;
8295     }
8296
8297     /**
8298      * Like grantUriPermissionUncheckedLocked, but takes an Intent.
8299      */
8300     void grantUriPermissionUncheckedFromIntentLocked(NeededUriGrants needed,
8301             UriPermissionOwner owner) {
8302         if (needed != null) {
8303             for (int i=0; i<needed.size(); i++) {
8304                 GrantUri grantUri = needed.get(i);
8305                 grantUriPermissionUncheckedLocked(needed.targetUid, needed.targetPkg,
8306                         grantUri, needed.flags, owner);
8307             }
8308         }
8309     }
8310
8311     void grantUriPermissionFromIntentLocked(int callingUid,
8312             String targetPkg, Intent intent, UriPermissionOwner owner, int targetUserId) {
8313         NeededUriGrants needed = checkGrantUriPermissionFromIntentLocked(callingUid, targetPkg,
8314                 intent, intent != null ? intent.getFlags() : 0, null, targetUserId);
8315         if (needed == null) {
8316             return;
8317         }
8318
8319         grantUriPermissionUncheckedFromIntentLocked(needed, owner);
8320     }
8321
8322     /**
8323      * @param uri This uri must NOT contain an embedded userId.
8324      * @param userId The userId in which the uri is to be resolved.
8325      */
8326     @Override
8327     public void grantUriPermission(IApplicationThread caller, String targetPkg, Uri uri,
8328             final int modeFlags, int userId) {
8329         enforceNotIsolatedCaller("grantUriPermission");
8330         GrantUri grantUri = new GrantUri(userId, uri, false);
8331         synchronized(this) {
8332             final ProcessRecord r = getRecordForAppLocked(caller);
8333             if (r == null) {
8334                 throw new SecurityException("Unable to find app for caller "
8335                         + caller
8336                         + " when granting permission to uri " + grantUri);
8337             }
8338             if (targetPkg == null) {
8339                 throw new IllegalArgumentException("null target");
8340             }
8341             if (grantUri == null) {
8342                 throw new IllegalArgumentException("null uri");
8343             }
8344
8345             Preconditions.checkFlagsArgument(modeFlags, Intent.FLAG_GRANT_READ_URI_PERMISSION
8346                     | Intent.FLAG_GRANT_WRITE_URI_PERMISSION
8347                     | Intent.FLAG_GRANT_PERSISTABLE_URI_PERMISSION
8348                     | Intent.FLAG_GRANT_PREFIX_URI_PERMISSION);
8349
8350             grantUriPermissionLocked(r.uid, targetPkg, grantUri, modeFlags, null,
8351                     UserHandle.getUserId(r.uid));
8352         }
8353     }
8354
8355     void removeUriPermissionIfNeededLocked(UriPermission perm) {
8356         if (perm.modeFlags == 0) {
8357             final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.get(
8358                     perm.targetUid);
8359             if (perms != null) {
8360                 if (DEBUG_URI_PERMISSION) Slog.v(TAG_URI_PERMISSION,
8361                         "Removing " + perm.targetUid + " permission to " + perm.uri);
8362
8363                 perms.remove(perm.uri);
8364                 if (perms.isEmpty()) {
8365                     mGrantedUriPermissions.remove(perm.targetUid);
8366                 }
8367             }
8368         }
8369     }
8370
8371     private void revokeUriPermissionLocked(int callingUid, GrantUri grantUri, final int modeFlags) {
8372         if (DEBUG_URI_PERMISSION) Slog.v(TAG_URI_PERMISSION,
8373                 "Revoking all granted permissions to " + grantUri);
8374
8375         final IPackageManager pm = AppGlobals.getPackageManager();
8376         final String authority = grantUri.uri.getAuthority();
8377         final ProviderInfo pi = getProviderInfoLocked(authority, grantUri.sourceUserId,
8378                 MATCH_DIRECT_BOOT_AWARE | MATCH_DIRECT_BOOT_UNAWARE);
8379         if (pi == null) {
8380             Slog.w(TAG, "No content provider found for permission revoke: "
8381                     + grantUri.toSafeString());
8382             return;
8383         }
8384
8385         // Does the caller have this permission on the URI?
8386         if (!checkHoldingPermissionsLocked(pm, pi, grantUri, callingUid, modeFlags)) {
8387             // If they don't have direct access to the URI, then revoke any
8388             // ownerless URI permissions that have been granted to them.
8389             final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.get(callingUid);
8390             if (perms != null) {
8391                 boolean persistChanged = false;
8392                 for (Iterator<UriPermission> it = perms.values().iterator(); it.hasNext();) {
8393                     final UriPermission perm = it.next();
8394                     if (perm.uri.sourceUserId == grantUri.sourceUserId
8395                             && perm.uri.uri.isPathPrefixMatch(grantUri.uri)) {
8396                         if (DEBUG_URI_PERMISSION) Slog.v(TAG_URI_PERMISSION,
8397                                 "Revoking non-owned " + perm.targetUid
8398                                 + " permission to " + perm.uri);
8399                         persistChanged |= perm.revokeModes(
8400                                 modeFlags | Intent.FLAG_GRANT_PERSISTABLE_URI_PERMISSION, false);
8401                         if (perm.modeFlags == 0) {
8402                             it.remove();
8403                         }
8404                     }
8405                 }
8406                 if (perms.isEmpty()) {
8407                     mGrantedUriPermissions.remove(callingUid);
8408                 }
8409                 if (persistChanged) {
8410                     schedulePersistUriGrants();
8411                 }
8412             }
8413             return;
8414         }
8415
8416         boolean persistChanged = false;
8417
8418         // Go through all of the permissions and remove any that match.
8419         int N = mGrantedUriPermissions.size();
8420         for (int i = 0; i < N; i++) {
8421             final int targetUid = mGrantedUriPermissions.keyAt(i);
8422             final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.valueAt(i);
8423
8424             for (Iterator<UriPermission> it = perms.values().iterator(); it.hasNext();) {
8425                 final UriPermission perm = it.next();
8426                 if (perm.uri.sourceUserId == grantUri.sourceUserId
8427                         && perm.uri.uri.isPathPrefixMatch(grantUri.uri)) {
8428                     if (DEBUG_URI_PERMISSION) Slog.v(TAG_URI_PERMISSION,
8429                                 "Revoking " + perm.targetUid + " permission to " + perm.uri);
8430                     persistChanged |= perm.revokeModes(
8431                             modeFlags | Intent.FLAG_GRANT_PERSISTABLE_URI_PERMISSION, true);
8432                     if (perm.modeFlags == 0) {
8433                         it.remove();
8434                     }
8435                 }
8436             }
8437
8438             if (perms.isEmpty()) {
8439                 mGrantedUriPermissions.remove(targetUid);
8440                 N--;
8441                 i--;
8442             }
8443         }
8444
8445         if (persistChanged) {
8446             schedulePersistUriGrants();
8447         }
8448     }
8449
8450     /**
8451      * @param uri This uri must NOT contain an embedded userId.
8452      * @param userId The userId in which the uri is to be resolved.
8453      */
8454     @Override
8455     public void revokeUriPermission(IApplicationThread caller, Uri uri, final int modeFlags,
8456             int userId) {
8457         enforceNotIsolatedCaller("revokeUriPermission");
8458         synchronized(this) {
8459             final ProcessRecord r = getRecordForAppLocked(caller);
8460             if (r == null) {
8461                 throw new SecurityException("Unable to find app for caller "
8462                         + caller
8463                         + " when revoking permission to uri " + uri);
8464             }
8465             if (uri == null) {
8466                 Slog.w(TAG, "revokeUriPermission: null uri");
8467                 return;
8468             }
8469
8470             if (!Intent.isAccessUriMode(modeFlags)) {
8471                 return;
8472             }
8473
8474             final String authority = uri.getAuthority();
8475             final ProviderInfo pi = getProviderInfoLocked(authority, userId,
8476                     MATCH_DIRECT_BOOT_AWARE | MATCH_DIRECT_BOOT_UNAWARE);
8477             if (pi == null) {
8478                 Slog.w(TAG, "No content provider found for permission revoke: "
8479                         + uri.toSafeString());
8480                 return;
8481             }
8482
8483             revokeUriPermissionLocked(r.uid, new GrantUri(userId, uri, false), modeFlags);
8484         }
8485     }
8486
8487     /**
8488      * Remove any {@link UriPermission} granted <em>from</em> or <em>to</em> the
8489      * given package.
8490      *
8491      * @param packageName Package name to match, or {@code null} to apply to all
8492      *            packages.
8493      * @param userHandle User to match, or {@link UserHandle#USER_ALL} to apply
8494      *            to all users.
8495      * @param persistable If persistable grants should be removed.
8496      */
8497     private void removeUriPermissionsForPackageLocked(
8498             String packageName, int userHandle, boolean persistable) {
8499         if (userHandle == UserHandle.USER_ALL && packageName == null) {
8500             throw new IllegalArgumentException("Must narrow by either package or user");
8501         }
8502
8503         boolean persistChanged = false;
8504
8505         int N = mGrantedUriPermissions.size();
8506         for (int i = 0; i < N; i++) {
8507             final int targetUid = mGrantedUriPermissions.keyAt(i);
8508             final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.valueAt(i);
8509
8510             // Only inspect grants matching user
8511             if (userHandle == UserHandle.USER_ALL
8512                     || userHandle == UserHandle.getUserId(targetUid)) {
8513                 for (Iterator<UriPermission> it = perms.values().iterator(); it.hasNext();) {
8514                     final UriPermission perm = it.next();
8515
8516                     // Only inspect grants matching package
8517                     if (packageName == null || perm.sourcePkg.equals(packageName)
8518                             || perm.targetPkg.equals(packageName)) {
8519                         // Hacky solution as part of fixing a security bug; ignore
8520                         // grants associated with DownloadManager so we don't have
8521                         // to immediately launch it to regrant the permissions
8522                         if (Downloads.Impl.AUTHORITY.equals(perm.uri.uri.getAuthority())
8523                                 && !persistable) continue;
8524
8525                         persistChanged |= perm.revokeModes(persistable
8526                                 ? ~0 : ~Intent.FLAG_GRANT_PERSISTABLE_URI_PERMISSION, true);
8527
8528                         // Only remove when no modes remain; any persisted grants
8529                         // will keep this alive.
8530                         if (perm.modeFlags == 0) {
8531                             it.remove();
8532                         }
8533                     }
8534                 }
8535
8536                 if (perms.isEmpty()) {
8537                     mGrantedUriPermissions.remove(targetUid);
8538                     N--;
8539                     i--;
8540                 }
8541             }
8542         }
8543
8544         if (persistChanged) {
8545             schedulePersistUriGrants();
8546         }
8547     }
8548
8549     @Override
8550     public IBinder newUriPermissionOwner(String name) {
8551         enforceNotIsolatedCaller("newUriPermissionOwner");
8552         synchronized(this) {
8553             UriPermissionOwner owner = new UriPermissionOwner(this, name);
8554             return owner.getExternalTokenLocked();
8555         }
8556     }
8557
8558     @Override
8559     public IBinder getUriPermissionOwnerForActivity(IBinder activityToken) {
8560         enforceNotIsolatedCaller("getUriPermissionOwnerForActivity");
8561         synchronized(this) {
8562             ActivityRecord r = ActivityRecord.isInStackLocked(activityToken);
8563             if (r == null) {
8564                 throw new IllegalArgumentException("Activity does not exist; token="
8565                         + activityToken);
8566             }
8567             return r.getUriPermissionsLocked().getExternalTokenLocked();
8568         }
8569     }
8570     /**
8571      * @param uri This uri must NOT contain an embedded userId.
8572      * @param sourceUserId The userId in which the uri is to be resolved.
8573      * @param targetUserId The userId of the app that receives the grant.
8574      */
8575     @Override
8576     public void grantUriPermissionFromOwner(IBinder token, int fromUid, String targetPkg, Uri uri,
8577             final int modeFlags, int sourceUserId, int targetUserId) {
8578         targetUserId = mUserController.handleIncomingUser(Binder.getCallingPid(),
8579                 Binder.getCallingUid(), targetUserId, false, ALLOW_FULL_ONLY,
8580                 "grantUriPermissionFromOwner", null);
8581         synchronized(this) {
8582             UriPermissionOwner owner = UriPermissionOwner.fromExternalToken(token);
8583             if (owner == null) {
8584                 throw new IllegalArgumentException("Unknown owner: " + token);
8585             }
8586             if (fromUid != Binder.getCallingUid()) {
8587                 if (Binder.getCallingUid() != Process.myUid()) {
8588                     // Only system code can grant URI permissions on behalf
8589                     // of other users.
8590                     throw new SecurityException("nice try");
8591                 }
8592             }
8593             if (targetPkg == null) {
8594                 throw new IllegalArgumentException("null target");
8595             }
8596             if (uri == null) {
8597                 throw new IllegalArgumentException("null uri");
8598             }
8599
8600             grantUriPermissionLocked(fromUid, targetPkg, new GrantUri(sourceUserId, uri, false),
8601                     modeFlags, owner, targetUserId);
8602         }
8603     }
8604
8605     /**
8606      * @param uri This uri must NOT contain an embedded userId.
8607      * @param userId The userId in which the uri is to be resolved.
8608      */
8609     @Override
8610     public void revokeUriPermissionFromOwner(IBinder token, Uri uri, int mode, int userId) {
8611         synchronized(this) {
8612             UriPermissionOwner owner = UriPermissionOwner.fromExternalToken(token);
8613             if (owner == null) {
8614                 throw new IllegalArgumentException("Unknown owner: " + token);
8615             }
8616
8617             if (uri == null) {
8618                 owner.removeUriPermissionsLocked(mode);
8619             } else {
8620                 owner.removeUriPermissionLocked(new GrantUri(userId, uri, false), mode);
8621             }
8622         }
8623     }
8624
8625     private void schedulePersistUriGrants() {
8626         if (!mHandler.hasMessages(PERSIST_URI_GRANTS_MSG)) {
8627             mHandler.sendMessageDelayed(mHandler.obtainMessage(PERSIST_URI_GRANTS_MSG),
8628                     10 * DateUtils.SECOND_IN_MILLIS);
8629         }
8630     }
8631
8632     private void writeGrantedUriPermissions() {
8633         if (DEBUG_URI_PERMISSION) Slog.v(TAG_URI_PERMISSION, "writeGrantedUriPermissions()");
8634
8635         // Snapshot permissions so we can persist without lock
8636         ArrayList<UriPermission.Snapshot> persist = Lists.newArrayList();
8637         synchronized (this) {
8638             final int size = mGrantedUriPermissions.size();
8639             for (int i = 0; i < size; i++) {
8640                 final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.valueAt(i);
8641                 for (UriPermission perm : perms.values()) {
8642                     if (perm.persistedModeFlags != 0) {
8643                         persist.add(perm.snapshot());
8644                     }
8645                 }
8646             }
8647         }
8648
8649         FileOutputStream fos = null;
8650         try {
8651             fos = mGrantFile.startWrite();
8652
8653             XmlSerializer out = new FastXmlSerializer();
8654             out.setOutput(fos, StandardCharsets.UTF_8.name());
8655             out.startDocument(null, true);
8656             out.startTag(null, TAG_URI_GRANTS);
8657             for (UriPermission.Snapshot perm : persist) {
8658                 out.startTag(null, TAG_URI_GRANT);
8659                 writeIntAttribute(out, ATTR_SOURCE_USER_ID, perm.uri.sourceUserId);
8660                 writeIntAttribute(out, ATTR_TARGET_USER_ID, perm.targetUserId);
8661                 out.attribute(null, ATTR_SOURCE_PKG, perm.sourcePkg);
8662                 out.attribute(null, ATTR_TARGET_PKG, perm.targetPkg);
8663                 out.attribute(null, ATTR_URI, String.valueOf(perm.uri.uri));
8664                 writeBooleanAttribute(out, ATTR_PREFIX, perm.uri.prefix);
8665                 writeIntAttribute(out, ATTR_MODE_FLAGS, perm.persistedModeFlags);
8666                 writeLongAttribute(out, ATTR_CREATED_TIME, perm.persistedCreateTime);
8667                 out.endTag(null, TAG_URI_GRANT);
8668             }
8669             out.endTag(null, TAG_URI_GRANTS);
8670             out.endDocument();
8671
8672             mGrantFile.finishWrite(fos);
8673         } catch (IOException e) {
8674             if (fos != null) {
8675                 mGrantFile.failWrite(fos);
8676             }
8677         }
8678     }
8679
8680     private void readGrantedUriPermissionsLocked() {
8681         if (DEBUG_URI_PERMISSION) Slog.v(TAG_URI_PERMISSION, "readGrantedUriPermissions()");
8682
8683         final long now = System.currentTimeMillis();
8684
8685         FileInputStream fis = null;
8686         try {
8687             fis = mGrantFile.openRead();
8688             final XmlPullParser in = Xml.newPullParser();
8689             in.setInput(fis, StandardCharsets.UTF_8.name());
8690
8691             int type;
8692             while ((type = in.next()) != END_DOCUMENT) {
8693                 final String tag = in.getName();
8694                 if (type == START_TAG) {
8695                     if (TAG_URI_GRANT.equals(tag)) {
8696                         final int sourceUserId;
8697                         final int targetUserId;
8698                         final int userHandle = readIntAttribute(in,
8699                                 ATTR_USER_HANDLE, UserHandle.USER_NULL);
8700                         if (userHandle != UserHandle.USER_NULL) {
8701                             // For backwards compatibility.
8702                             sourceUserId = userHandle;
8703                             targetUserId = userHandle;
8704                         } else {
8705                             sourceUserId = readIntAttribute(in, ATTR_SOURCE_USER_ID);
8706                             targetUserId = readIntAttribute(in, ATTR_TARGET_USER_ID);
8707                         }
8708                         final String sourcePkg = in.getAttributeValue(null, ATTR_SOURCE_PKG);
8709                         final String targetPkg = in.getAttributeValue(null, ATTR_TARGET_PKG);
8710                         final Uri uri = Uri.parse(in.getAttributeValue(null, ATTR_URI));
8711                         final boolean prefix = readBooleanAttribute(in, ATTR_PREFIX);
8712                         final int modeFlags = readIntAttribute(in, ATTR_MODE_FLAGS);
8713                         final long createdTime = readLongAttribute(in, ATTR_CREATED_TIME, now);
8714
8715                         // Sanity check that provider still belongs to source package
8716                         // Both direct boot aware and unaware packages are fine as we
8717                         // will do filtering at query time to avoid multiple parsing.
8718                         final ProviderInfo pi = getProviderInfoLocked(
8719                                 uri.getAuthority(), sourceUserId, MATCH_DIRECT_BOOT_AWARE
8720                                         | MATCH_DIRECT_BOOT_UNAWARE);
8721                         if (pi != null && sourcePkg.equals(pi.packageName)) {
8722                             int targetUid = -1;
8723                             try {
8724                                 targetUid = AppGlobals.getPackageManager().getPackageUid(
8725                                         targetPkg, MATCH_UNINSTALLED_PACKAGES, targetUserId);
8726                             } catch (RemoteException e) {
8727                             }
8728                             if (targetUid != -1) {
8729                                 final UriPermission perm = findOrCreateUriPermissionLocked(
8730                                         sourcePkg, targetPkg, targetUid,
8731                                         new GrantUri(sourceUserId, uri, prefix));
8732                                 perm.initPersistedModes(modeFlags, createdTime);
8733                             }
8734                         } else {
8735                             Slog.w(TAG, "Persisted grant for " + uri + " had source " + sourcePkg
8736                                     + " but instead found " + pi);
8737                         }
8738                     }
8739                 }
8740             }
8741         } catch (FileNotFoundException e) {
8742             // Missing grants is okay
8743         } catch (IOException e) {
8744             Slog.wtf(TAG, "Failed reading Uri grants", e);
8745         } catch (XmlPullParserException e) {
8746             Slog.wtf(TAG, "Failed reading Uri grants", e);
8747         } finally {
8748             IoUtils.closeQuietly(fis);
8749         }
8750     }
8751
8752     /**
8753      * @param uri This uri must NOT contain an embedded userId.
8754      * @param userId The userId in which the uri is to be resolved.
8755      */
8756     @Override
8757     public void takePersistableUriPermission(Uri uri, final int modeFlags, int userId) {
8758         enforceNotIsolatedCaller("takePersistableUriPermission");
8759
8760         Preconditions.checkFlagsArgument(modeFlags,
8761                 Intent.FLAG_GRANT_READ_URI_PERMISSION | Intent.FLAG_GRANT_WRITE_URI_PERMISSION);
8762
8763         synchronized (this) {
8764             final int callingUid = Binder.getCallingUid();
8765             boolean persistChanged = false;
8766             GrantUri grantUri = new GrantUri(userId, uri, false);
8767
8768             UriPermission exactPerm = findUriPermissionLocked(callingUid,
8769                     new GrantUri(userId, uri, false));
8770             UriPermission prefixPerm = findUriPermissionLocked(callingUid,
8771                     new GrantUri(userId, uri, true));
8772
8773             final boolean exactValid = (exactPerm != null)
8774                     && ((modeFlags & exactPerm.persistableModeFlags) == modeFlags);
8775             final boolean prefixValid = (prefixPerm != null)
8776                     && ((modeFlags & prefixPerm.persistableModeFlags) == modeFlags);
8777
8778             if (!(exactValid || prefixValid)) {
8779                 throw new SecurityException("No persistable permission grants found for UID "
8780                         + callingUid + " and Uri " + grantUri.toSafeString());
8781             }
8782
8783             if (exactValid) {
8784                 persistChanged |= exactPerm.takePersistableModes(modeFlags);
8785             }
8786             if (prefixValid) {
8787                 persistChanged |= prefixPerm.takePersistableModes(modeFlags);
8788             }
8789
8790             persistChanged |= maybePrunePersistedUriGrantsLocked(callingUid);
8791
8792             if (persistChanged) {
8793                 schedulePersistUriGrants();
8794             }
8795         }
8796     }
8797
8798     /**
8799      * @param uri This uri must NOT contain an embedded userId.
8800      * @param userId The userId in which the uri is to be resolved.
8801      */
8802     @Override
8803     public void releasePersistableUriPermission(Uri uri, final int modeFlags, int userId) {
8804         enforceNotIsolatedCaller("releasePersistableUriPermission");
8805
8806         Preconditions.checkFlagsArgument(modeFlags,
8807                 Intent.FLAG_GRANT_READ_URI_PERMISSION | Intent.FLAG_GRANT_WRITE_URI_PERMISSION);
8808
8809         synchronized (this) {
8810             final int callingUid = Binder.getCallingUid();
8811             boolean persistChanged = false;
8812
8813             UriPermission exactPerm = findUriPermissionLocked(callingUid,
8814                     new GrantUri(userId, uri, false));
8815             UriPermission prefixPerm = findUriPermissionLocked(callingUid,
8816                     new GrantUri(userId, uri, true));
8817             if (exactPerm == null && prefixPerm == null) {
8818                 throw new SecurityException("No permission grants found for UID " + callingUid
8819                         + " and Uri " + uri.toSafeString());
8820             }
8821
8822             if (exactPerm != null) {
8823                 persistChanged |= exactPerm.releasePersistableModes(modeFlags);
8824                 removeUriPermissionIfNeededLocked(exactPerm);
8825             }
8826             if (prefixPerm != null) {
8827                 persistChanged |= prefixPerm.releasePersistableModes(modeFlags);
8828                 removeUriPermissionIfNeededLocked(prefixPerm);
8829             }
8830
8831             if (persistChanged) {
8832                 schedulePersistUriGrants();
8833             }
8834         }
8835     }
8836
8837     /**
8838      * Prune any older {@link UriPermission} for the given UID until outstanding
8839      * persisted grants are below {@link #MAX_PERSISTED_URI_GRANTS}.
8840      *
8841      * @return if any mutations occured that require persisting.
8842      */
8843     private boolean maybePrunePersistedUriGrantsLocked(int uid) {
8844         final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.get(uid);
8845         if (perms == null) return false;
8846         if (perms.size() < MAX_PERSISTED_URI_GRANTS) return false;
8847
8848         final ArrayList<UriPermission> persisted = Lists.newArrayList();
8849         for (UriPermission perm : perms.values()) {
8850             if (perm.persistedModeFlags != 0) {
8851                 persisted.add(perm);
8852             }
8853         }
8854
8855         final int trimCount = persisted.size() - MAX_PERSISTED_URI_GRANTS;
8856         if (trimCount <= 0) return false;
8857
8858         Collections.sort(persisted, new UriPermission.PersistedTimeComparator());
8859         for (int i = 0; i < trimCount; i++) {
8860             final UriPermission perm = persisted.get(i);
8861
8862             if (DEBUG_URI_PERMISSION) Slog.v(TAG_URI_PERMISSION,
8863                     "Trimming grant created at " + perm.persistedCreateTime);
8864
8865             perm.releasePersistableModes(~0);
8866             removeUriPermissionIfNeededLocked(perm);
8867         }
8868
8869         return true;
8870     }
8871
8872     @Override
8873     public ParceledListSlice<android.content.UriPermission> getPersistedUriPermissions(
8874             String packageName, boolean incoming) {
8875         enforceNotIsolatedCaller("getPersistedUriPermissions");
8876         Preconditions.checkNotNull(packageName, "packageName");
8877
8878         final int callingUid = Binder.getCallingUid();
8879         final int callingUserId = UserHandle.getUserId(callingUid);
8880         final IPackageManager pm = AppGlobals.getPackageManager();
8881         try {
8882             final int packageUid = pm.getPackageUid(packageName,
8883                     MATCH_DIRECT_BOOT_AWARE | MATCH_DIRECT_BOOT_UNAWARE, callingUserId);
8884             if (packageUid != callingUid) {
8885                 throw new SecurityException(
8886                         "Package " + packageName + " does not belong to calling UID " + callingUid);
8887             }
8888         } catch (RemoteException e) {
8889             throw new SecurityException("Failed to verify package name ownership");
8890         }
8891
8892         final ArrayList<android.content.UriPermission> result = Lists.newArrayList();
8893         synchronized (this) {
8894             if (incoming) {
8895                 final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.get(
8896                         callingUid);
8897                 if (perms == null) {
8898                     Slog.w(TAG, "No permission grants found for " + packageName);
8899                 } else {
8900                     for (UriPermission perm : perms.values()) {
8901                         if (packageName.equals(perm.targetPkg) && perm.persistedModeFlags != 0) {
8902                             result.add(perm.buildPersistedPublicApiObject());
8903                         }
8904                     }
8905                 }
8906             } else {
8907                 final int size = mGrantedUriPermissions.size();
8908                 for (int i = 0; i < size; i++) {
8909                     final ArrayMap<GrantUri, UriPermission> perms =
8910                             mGrantedUriPermissions.valueAt(i);
8911                     for (UriPermission perm : perms.values()) {
8912                         if (packageName.equals(perm.sourcePkg) && perm.persistedModeFlags != 0) {
8913                             result.add(perm.buildPersistedPublicApiObject());
8914                         }
8915                     }
8916                 }
8917             }
8918         }
8919         return new ParceledListSlice<android.content.UriPermission>(result);
8920     }
8921
8922     @Override
8923     public ParceledListSlice<android.content.UriPermission> getGrantedUriPermissions(
8924             String packageName, int userId) {
8925         enforceCallingPermission(android.Manifest.permission.GET_APP_GRANTED_URI_PERMISSIONS,
8926                 "getGrantedUriPermissions");
8927
8928         final ArrayList<android.content.UriPermission> result = Lists.newArrayList();
8929         synchronized (this) {
8930             final int size = mGrantedUriPermissions.size();
8931             for (int i = 0; i < size; i++) {
8932                 final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.valueAt(i);
8933                 for (UriPermission perm : perms.values()) {
8934                     if (packageName.equals(perm.targetPkg) && perm.targetUserId == userId
8935                             && perm.persistedModeFlags != 0) {
8936                         result.add(perm.buildPersistedPublicApiObject());
8937                     }
8938                 }
8939             }
8940         }
8941         return new ParceledListSlice<android.content.UriPermission>(result);
8942     }
8943
8944     @Override
8945     public void clearGrantedUriPermissions(String packageName, int userId) {
8946         enforceCallingPermission(android.Manifest.permission.CLEAR_APP_GRANTED_URI_PERMISSIONS,
8947                 "clearGrantedUriPermissions");
8948         removeUriPermissionsForPackageLocked(packageName, userId, true);
8949     }
8950
8951     @Override
8952     public void showWaitingForDebugger(IApplicationThread who, boolean waiting) {
8953         synchronized (this) {
8954             ProcessRecord app =
8955                 who != null ? getRecordForAppLocked(who) : null;
8956             if (app == null) return;
8957
8958             Message msg = Message.obtain();
8959             msg.what = WAIT_FOR_DEBUGGER_UI_MSG;
8960             msg.obj = app;
8961             msg.arg1 = waiting ? 1 : 0;
8962             mUiHandler.sendMessage(msg);
8963         }
8964     }
8965
8966     @Override
8967     public void getMemoryInfo(ActivityManager.MemoryInfo outInfo) {
8968         final long homeAppMem = mProcessList.getMemLevel(ProcessList.HOME_APP_ADJ);
8969         final long cachedAppMem = mProcessList.getMemLevel(ProcessList.CACHED_APP_MIN_ADJ);
8970         outInfo.availMem = Process.getFreeMemory();
8971         outInfo.totalMem = Process.getTotalMemory();
8972         outInfo.threshold = homeAppMem;
8973         outInfo.lowMemory = outInfo.availMem < (homeAppMem + ((cachedAppMem-homeAppMem)/2));
8974         outInfo.hiddenAppThreshold = cachedAppMem;
8975         outInfo.secondaryServerThreshold = mProcessList.getMemLevel(
8976                 ProcessList.SERVICE_ADJ);
8977         outInfo.visibleAppThreshold = mProcessList.getMemLevel(
8978                 ProcessList.VISIBLE_APP_ADJ);
8979         outInfo.foregroundAppThreshold = mProcessList.getMemLevel(
8980                 ProcessList.FOREGROUND_APP_ADJ);
8981     }
8982
8983     // =========================================================
8984     // TASK MANAGEMENT
8985     // =========================================================
8986
8987     @Override
8988     public List<IAppTask> getAppTasks(String callingPackage) {
8989         int callingUid = Binder.getCallingUid();
8990         long ident = Binder.clearCallingIdentity();
8991
8992         synchronized(this) {
8993             ArrayList<IAppTask> list = new ArrayList<IAppTask>();
8994             try {
8995                 if (DEBUG_ALL) Slog.v(TAG, "getAppTasks");
8996
8997                 final int N = mRecentTasks.size();
8998                 for (int i = 0; i < N; i++) {
8999                     TaskRecord tr = mRecentTasks.get(i);
9000                     // Skip tasks that do not match the caller.  We don't need to verify
9001                     // callingPackage, because we are also limiting to callingUid and know
9002                     // that will limit to the correct security sandbox.
9003                     if (tr.effectiveUid != callingUid) {
9004                         continue;
9005                     }
9006                     Intent intent = tr.getBaseIntent();
9007                     if (intent == null ||
9008                             !callingPackage.equals(intent.getComponent().getPackageName())) {
9009                         continue;
9010                     }
9011                     ActivityManager.RecentTaskInfo taskInfo =
9012                             createRecentTaskInfoFromTaskRecord(tr);
9013                     AppTaskImpl taskImpl = new AppTaskImpl(taskInfo.persistentId, callingUid);
9014                     list.add(taskImpl);
9015                 }
9016             } finally {
9017                 Binder.restoreCallingIdentity(ident);
9018             }
9019             return list;
9020         }
9021     }
9022
9023     @Override
9024     public List<RunningTaskInfo> getTasks(int maxNum, int flags) {
9025         final int callingUid = Binder.getCallingUid();
9026         ArrayList<RunningTaskInfo> list = new ArrayList<RunningTaskInfo>();
9027
9028         synchronized(this) {
9029             if (DEBUG_ALL) Slog.v(
9030                 TAG, "getTasks: max=" + maxNum + ", flags=" + flags);
9031
9032             final boolean allowed = isGetTasksAllowed("getTasks", Binder.getCallingPid(),
9033                     callingUid);
9034
9035             // TODO: Improve with MRU list from all ActivityStacks.
9036             mStackSupervisor.getTasksLocked(maxNum, list, callingUid, allowed);
9037         }
9038
9039         return list;
9040     }
9041
9042     /**
9043      * Creates a new RecentTaskInfo from a TaskRecord.
9044      */
9045     private ActivityManager.RecentTaskInfo createRecentTaskInfoFromTaskRecord(TaskRecord tr) {
9046         // Update the task description to reflect any changes in the task stack
9047         tr.updateTaskDescription();
9048
9049         // Compose the recent task info
9050         ActivityManager.RecentTaskInfo rti = new ActivityManager.RecentTaskInfo();
9051         rti.id = tr.getTopActivity() == null ? INVALID_TASK_ID : tr.taskId;
9052         rti.persistentId = tr.taskId;
9053         rti.baseIntent = new Intent(tr.getBaseIntent());
9054         rti.origActivity = tr.origActivity;
9055         rti.realActivity = tr.realActivity;
9056         rti.description = tr.lastDescription;
9057         rti.stackId = tr.stack != null ? tr.stack.mStackId : -1;
9058         rti.userId = tr.userId;
9059         rti.taskDescription = new ActivityManager.TaskDescription(tr.lastTaskDescription);
9060         rti.firstActiveTime = tr.firstActiveTime;
9061         rti.lastActiveTime = tr.lastActiveTime;
9062         rti.affiliatedTaskId = tr.mAffiliatedTaskId;
9063         rti.affiliatedTaskColor = tr.mAffiliatedTaskColor;
9064         rti.numActivities = 0;
9065         if (tr.mBounds != null) {
9066             rti.bounds = new Rect(tr.mBounds);
9067         }
9068         rti.isDockable = tr.canGoInDockedStack();
9069         rti.resizeMode = tr.mResizeMode;
9070
9071         ActivityRecord base = null;
9072         ActivityRecord top = null;
9073         ActivityRecord tmp;
9074
9075         for (int i = tr.mActivities.size() - 1; i >= 0; --i) {
9076             tmp = tr.mActivities.get(i);
9077             if (tmp.finishing) {
9078                 continue;
9079             }
9080             base = tmp;
9081             if (top == null || (top.state == ActivityState.INITIALIZING)) {
9082                 top = base;
9083             }
9084             rti.numActivities++;
9085         }
9086
9087         rti.baseActivity = (base != null) ? base.intent.getComponent() : null;
9088         rti.topActivity = (top != null) ? top.intent.getComponent() : null;
9089
9090         return rti;
9091     }
9092
9093     private boolean isGetTasksAllowed(String caller, int callingPid, int callingUid) {
9094         boolean allowed = checkPermission(android.Manifest.permission.REAL_GET_TASKS,
9095                 callingPid, callingUid) == PackageManager.PERMISSION_GRANTED;
9096         if (!allowed) {
9097             if (checkPermission(android.Manifest.permission.GET_TASKS,
9098                     callingPid, callingUid) == PackageManager.PERMISSION_GRANTED) {
9099                 // Temporary compatibility: some existing apps on the system image may
9100                 // still be requesting the old permission and not switched to the new
9101                 // one; if so, we'll still allow them full access.  This means we need
9102                 // to see if they are holding the old permission and are a system app.
9103                 try {
9104                     if (AppGlobals.getPackageManager().isUidPrivileged(callingUid)) {
9105                         allowed = true;
9106                         if (DEBUG_TASKS) Slog.w(TAG, caller + ": caller " + callingUid
9107                                 + " is using old GET_TASKS but privileged; allowing");
9108                     }
9109                 } catch (RemoteException e) {
9110                 }
9111             }
9112         }
9113         if (!allowed) {
9114             if (DEBUG_TASKS) Slog.w(TAG, caller + ": caller " + callingUid
9115                     + " does not hold REAL_GET_TASKS; limiting output");
9116         }
9117         return allowed;
9118     }
9119
9120     @Override
9121     public ParceledListSlice<ActivityManager.RecentTaskInfo> getRecentTasks(int maxNum, int flags,
9122             int userId) {
9123         final int callingUid = Binder.getCallingUid();
9124         userId = mUserController.handleIncomingUser(Binder.getCallingPid(), callingUid, userId,
9125                 false, ALLOW_FULL_ONLY, "getRecentTasks", null);
9126
9127         final boolean includeProfiles = (flags & ActivityManager.RECENT_INCLUDE_PROFILES) != 0;
9128         final boolean withExcluded = (flags&ActivityManager.RECENT_WITH_EXCLUDED) != 0;
9129         synchronized (this) {
9130             final boolean allowed = isGetTasksAllowed("getRecentTasks", Binder.getCallingPid(),
9131                     callingUid);
9132             final boolean detailed = checkCallingPermission(
9133                     android.Manifest.permission.GET_DETAILED_TASKS)
9134                     == PackageManager.PERMISSION_GRANTED;
9135
9136             if (!isUserRunning(userId, ActivityManager.FLAG_AND_UNLOCKED)) {
9137                 Slog.i(TAG, "user " + userId + " is still locked. Cannot load recents");
9138                 return ParceledListSlice.emptyList();
9139             }
9140             mRecentTasks.loadUserRecentsLocked(userId);
9141
9142             final int recentsCount = mRecentTasks.size();
9143             ArrayList<ActivityManager.RecentTaskInfo> res =
9144                     new ArrayList<>(maxNum < recentsCount ? maxNum : recentsCount);
9145
9146             final Set<Integer> includedUsers;
9147             if (includeProfiles) {
9148                 includedUsers = mUserController.getProfileIds(userId);
9149             } else {
9150                 includedUsers = new HashSet<>();
9151             }
9152             includedUsers.add(Integer.valueOf(userId));
9153
9154             for (int i = 0; i < recentsCount && maxNum > 0; i++) {
9155                 TaskRecord tr = mRecentTasks.get(i);
9156                 // Only add calling user or related users recent tasks
9157                 if (!includedUsers.contains(Integer.valueOf(tr.userId))) {
9158                     if (DEBUG_RECENTS) Slog.d(TAG_RECENTS, "Skipping, not user: " + tr);
9159                     continue;
9160                 }
9161
9162                 if (tr.realActivitySuspended) {
9163                     if (DEBUG_RECENTS) Slog.d(TAG_RECENTS, "Skipping, activity suspended: " + tr);
9164                     continue;
9165                 }
9166
9167                 // Return the entry if desired by the caller.  We always return
9168                 // the first entry, because callers always expect this to be the
9169                 // foreground app.  We may filter others if the caller has
9170                 // not supplied RECENT_WITH_EXCLUDED and there is some reason
9171                 // we should exclude the entry.
9172
9173                 if (i == 0
9174                         || withExcluded
9175                         || (tr.intent == null)
9176                         || ((tr.intent.getFlags() & Intent.FLAG_ACTIVITY_EXCLUDE_FROM_RECENTS)
9177                                 == 0)) {
9178                     if (!allowed) {
9179                         // If the caller doesn't have the GET_TASKS permission, then only
9180                         // allow them to see a small subset of tasks -- their own and home.
9181                         if (!tr.isHomeTask() && tr.effectiveUid != callingUid) {
9182                             if (DEBUG_RECENTS) Slog.d(TAG_RECENTS, "Skipping, not allowed: " + tr);
9183                             continue;
9184                         }
9185                     }
9186                     if ((flags & ActivityManager.RECENT_IGNORE_HOME_STACK_TASKS) != 0) {
9187                         if (tr.stack != null && tr.stack.isHomeStack()) {
9188                             if (DEBUG_RECENTS) Slog.d(TAG_RECENTS,
9189                                     "Skipping, home stack task: " + tr);
9190                             continue;
9191                         }
9192                     }
9193                     if ((flags & ActivityManager.RECENT_INGORE_DOCKED_STACK_TOP_TASK) != 0) {
9194                         final ActivityStack stack = tr.stack;
9195                         if (stack != null && stack.isDockedStack() && stack.topTask() == tr) {
9196                             if (DEBUG_RECENTS) Slog.d(TAG_RECENTS,
9197                                     "Skipping, top task in docked stack: " + tr);
9198                             continue;
9199                         }
9200                     }
9201                     if ((flags & ActivityManager.RECENT_INGORE_PINNED_STACK_TASKS) != 0) {
9202                         if (tr.stack != null && tr.stack.isPinnedStack()) {
9203                             if (DEBUG_RECENTS) Slog.d(TAG_RECENTS,
9204                                     "Skipping, pinned stack task: " + tr);
9205                             continue;
9206                         }
9207                     }
9208                     if (tr.autoRemoveRecents && tr.getTopActivity() == null) {
9209                         // Don't include auto remove tasks that are finished or finishing.
9210                         if (DEBUG_RECENTS) Slog.d(TAG_RECENTS,
9211                                 "Skipping, auto-remove without activity: " + tr);
9212                         continue;
9213                     }
9214                     if ((flags&ActivityManager.RECENT_IGNORE_UNAVAILABLE) != 0
9215                             && !tr.isAvailable) {
9216                         if (DEBUG_RECENTS) Slog.d(TAG_RECENTS,
9217                                 "Skipping, unavail real act: " + tr);
9218                         continue;
9219                     }
9220
9221                     if (!tr.mUserSetupComplete) {
9222                         // Don't include task launched while user is not done setting-up.
9223                         if (DEBUG_RECENTS) Slog.d(TAG_RECENTS,
9224                                 "Skipping, user setup not complete: " + tr);
9225                         continue;
9226                     }
9227
9228                     ActivityManager.RecentTaskInfo rti = createRecentTaskInfoFromTaskRecord(tr);
9229                     if (!detailed) {
9230                         rti.baseIntent.replaceExtras((Bundle)null);
9231                     }
9232
9233                     res.add(rti);
9234                     maxNum--;
9235                 }
9236             }
9237             return new ParceledListSlice<>(res);
9238         }
9239     }
9240
9241     @Override
9242     public ActivityManager.TaskThumbnail getTaskThumbnail(int id) {
9243         synchronized (this) {
9244             enforceCallingPermission(android.Manifest.permission.READ_FRAME_BUFFER,
9245                     "getTaskThumbnail()");
9246             final TaskRecord tr = mStackSupervisor.anyTaskForIdLocked(
9247                     id, !RESTORE_FROM_RECENTS, INVALID_STACK_ID);
9248             if (tr != null) {
9249                 return tr.getTaskThumbnailLocked();
9250             }
9251         }
9252         return null;
9253     }
9254
9255     @Override
9256     public int addAppTask(IBinder activityToken, Intent intent,
9257             ActivityManager.TaskDescription description, Bitmap thumbnail) throws RemoteException {
9258         final int callingUid = Binder.getCallingUid();
9259         final long callingIdent = Binder.clearCallingIdentity();
9260
9261         try {
9262             synchronized (this) {
9263                 ActivityRecord r = ActivityRecord.isInStackLocked(activityToken);
9264                 if (r == null) {
9265                     throw new IllegalArgumentException("Activity does not exist; token="
9266                             + activityToken);
9267                 }
9268                 ComponentName comp = intent.getComponent();
9269                 if (comp == null) {
9270                     throw new IllegalArgumentException("Intent " + intent
9271                             + " must specify explicit component");
9272                 }
9273                 if (thumbnail.getWidth() != mThumbnailWidth
9274                         || thumbnail.getHeight() != mThumbnailHeight) {
9275                     throw new IllegalArgumentException("Bad thumbnail size: got "
9276                             + thumbnail.getWidth() + "x" + thumbnail.getHeight() + ", require "
9277                             + mThumbnailWidth + "x" + mThumbnailHeight);
9278                 }
9279                 if (intent.getSelector() != null) {
9280                     intent.setSelector(null);
9281                 }
9282                 if (intent.getSourceBounds() != null) {
9283                     intent.setSourceBounds(null);
9284                 }
9285                 if ((intent.getFlags()&Intent.FLAG_ACTIVITY_NEW_DOCUMENT) != 0) {
9286                     if ((intent.getFlags()&Intent.FLAG_ACTIVITY_RETAIN_IN_RECENTS) == 0) {
9287                         // The caller has added this as an auto-remove task...  that makes no
9288                         // sense, so turn off auto-remove.
9289                         intent.addFlags(Intent.FLAG_ACTIVITY_RETAIN_IN_RECENTS);
9290                     }
9291                 } else if ((intent.getFlags()&Intent.FLAG_ACTIVITY_NEW_TASK) != 0) {
9292                     // Must be a new task.
9293                     intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
9294                 }
9295                 if (!comp.equals(mLastAddedTaskComponent) || callingUid != mLastAddedTaskUid) {
9296                     mLastAddedTaskActivity = null;
9297                 }
9298                 ActivityInfo ainfo = mLastAddedTaskActivity;
9299                 if (ainfo == null) {
9300                     ainfo = mLastAddedTaskActivity = AppGlobals.getPackageManager().getActivityInfo(
9301                             comp, 0, UserHandle.getUserId(callingUid));
9302                     if (ainfo.applicationInfo.uid != callingUid) {
9303                         throw new SecurityException(
9304                                 "Can't add task for another application: target uid="
9305                                 + ainfo.applicationInfo.uid + ", calling uid=" + callingUid);
9306                     }
9307                 }
9308
9309                 // Use the full screen as the context for the task thumbnail
9310                 final Point displaySize = new Point();
9311                 final TaskThumbnailInfo thumbnailInfo = new TaskThumbnailInfo();
9312                 r.task.stack.getDisplaySize(displaySize);
9313                 thumbnailInfo.taskWidth = displaySize.x;
9314                 thumbnailInfo.taskHeight = displaySize.y;
9315                 thumbnailInfo.screenOrientation = mConfiguration.orientation;
9316
9317                 TaskRecord task = new TaskRecord(this,
9318                         mStackSupervisor.getNextTaskIdForUserLocked(r.userId),
9319                         ainfo, intent, description, thumbnailInfo);
9320
9321                 int trimIdx = mRecentTasks.trimForTaskLocked(task, false);
9322                 if (trimIdx >= 0) {
9323                     // If this would have caused a trim, then we'll abort because that
9324                     // means it would be added at the end of the list but then just removed.
9325                     return INVALID_TASK_ID;
9326                 }
9327
9328                 final int N = mRecentTasks.size();
9329                 if (N >= (ActivityManager.getMaxRecentTasksStatic()-1)) {
9330                     final TaskRecord tr = mRecentTasks.remove(N - 1);
9331                     tr.removedFromRecents();
9332                 }
9333
9334                 task.inRecents = true;
9335                 mRecentTasks.add(task);
9336                 r.task.stack.addTask(task, false, "addAppTask");
9337
9338                 task.setLastThumbnailLocked(thumbnail);
9339                 task.freeLastThumbnail();
9340
9341                 return task.taskId;
9342             }
9343         } finally {
9344             Binder.restoreCallingIdentity(callingIdent);
9345         }
9346     }
9347
9348     @Override
9349     public Point getAppTaskThumbnailSize() {
9350         synchronized (this) {
9351             return new Point(mThumbnailWidth,  mThumbnailHeight);
9352         }
9353     }
9354
9355     @Override
9356     public void setTaskDescription(IBinder token, ActivityManager.TaskDescription td) {
9357         synchronized (this) {
9358             ActivityRecord r = ActivityRecord.isInStackLocked(token);
9359             if (r != null) {
9360                 r.setTaskDescription(td);
9361                 r.task.updateTaskDescription();
9362             }
9363         }
9364     }
9365
9366     @Override
9367     public void setTaskResizeable(int taskId, int resizeableMode) {
9368         synchronized (this) {
9369             final TaskRecord task = mStackSupervisor.anyTaskForIdLocked(
9370                     taskId, !RESTORE_FROM_RECENTS, INVALID_STACK_ID);
9371             if (task == null) {
9372                 Slog.w(TAG, "setTaskResizeable: taskId=" + taskId + " not found");
9373                 return;
9374             }
9375             if (task.mResizeMode != resizeableMode) {
9376                 task.mResizeMode = resizeableMode;
9377                 mWindowManager.setTaskResizeable(taskId, resizeableMode);
9378                 mStackSupervisor.ensureActivitiesVisibleLocked(null, 0, !PRESERVE_WINDOWS);
9379                 mStackSupervisor.resumeFocusedStackTopActivityLocked();
9380             }
9381         }
9382     }
9383
9384     @Override
9385     public void resizeTask(int taskId, Rect bounds, int resizeMode) {
9386         enforceCallingPermission(MANAGE_ACTIVITY_STACKS, "resizeTask()");
9387         long ident = Binder.clearCallingIdentity();
9388         try {
9389             synchronized (this) {
9390                 TaskRecord task = mStackSupervisor.anyTaskForIdLocked(taskId);
9391                 if (task == null) {
9392                     Slog.w(TAG, "resizeTask: taskId=" + taskId + " not found");
9393                     return;
9394                 }
9395                 int stackId = task.stack.mStackId;
9396                 // We allow the task to scroll instead of resizing if this is a non-resizeable task
9397                 // in crop windows resize mode or if the task size is affected by the docked stack
9398                 // changing size. No need to update configuration.
9399                 if (bounds != null && task.inCropWindowsResizeMode()
9400                         && mStackSupervisor.isStackDockedInEffect(stackId)) {
9401                     mWindowManager.scrollTask(task.taskId, bounds);
9402                     return;
9403                 }
9404
9405                 // Place the task in the right stack if it isn't there already based on
9406                 // the requested bounds.
9407                 // The stack transition logic is:
9408                 // - a null bounds on a freeform task moves that task to fullscreen
9409                 // - a non-null bounds on a non-freeform (fullscreen OR docked) task moves
9410                 //   that task to freeform
9411                 // - otherwise the task is not moved
9412                 if (!StackId.isTaskResizeAllowed(stackId)) {
9413                     throw new IllegalArgumentException("resizeTask not allowed on task=" + task);
9414                 }
9415                 if (bounds == null && stackId == FREEFORM_WORKSPACE_STACK_ID) {
9416                     stackId = FULLSCREEN_WORKSPACE_STACK_ID;
9417                 } else if (bounds != null && stackId != FREEFORM_WORKSPACE_STACK_ID ) {
9418                     stackId = FREEFORM_WORKSPACE_STACK_ID;
9419                 }
9420                 boolean preserveWindow = (resizeMode & RESIZE_MODE_PRESERVE_WINDOW) != 0;
9421                 if (stackId != task.stack.mStackId) {
9422                     mStackSupervisor.moveTaskToStackUncheckedLocked(
9423                             task, stackId, ON_TOP, !FORCE_FOCUS, "resizeTask");
9424                     preserveWindow = false;
9425                 }
9426
9427                 mStackSupervisor.resizeTaskLocked(task, bounds, resizeMode, preserveWindow,
9428                         false /* deferResume */);
9429             }
9430         } finally {
9431             Binder.restoreCallingIdentity(ident);
9432         }
9433     }
9434
9435     @Override
9436     public Rect getTaskBounds(int taskId) {
9437         enforceCallingPermission(MANAGE_ACTIVITY_STACKS, "getTaskBounds()");
9438         long ident = Binder.clearCallingIdentity();
9439         Rect rect = new Rect();
9440         try {
9441             synchronized (this) {
9442                 final TaskRecord task = mStackSupervisor.anyTaskForIdLocked(
9443                         taskId, !RESTORE_FROM_RECENTS, INVALID_STACK_ID);
9444                 if (task == null) {
9445                     Slog.w(TAG, "getTaskBounds: taskId=" + taskId + " not found");
9446                     return rect;
9447                 }
9448                 if (task.stack != null) {
9449                     // Return the bounds from window manager since it will be adjusted for various
9450                     // things like the presense of a docked stack for tasks that aren't resizeable.
9451                     mWindowManager.getTaskBounds(task.taskId, rect);
9452                 } else {
9453                     // Task isn't in window manager yet since it isn't associated with a stack.
9454                     // Return the persist value from activity manager
9455                     if (task.mBounds != null) {
9456                         rect.set(task.mBounds);
9457                     } else if (task.mLastNonFullscreenBounds != null) {
9458                         rect.set(task.mLastNonFullscreenBounds);
9459                     }
9460                 }
9461             }
9462         } finally {
9463             Binder.restoreCallingIdentity(ident);
9464         }
9465         return rect;
9466     }
9467
9468     @Override
9469     public Bitmap getTaskDescriptionIcon(String filePath, int userId) {
9470         if (userId != UserHandle.getCallingUserId()) {
9471             enforceCallingPermission(android.Manifest.permission.INTERACT_ACROSS_USERS_FULL,
9472                     "getTaskDescriptionIcon");
9473         }
9474         final File passedIconFile = new File(filePath);
9475         final File legitIconFile = new File(TaskPersister.getUserImagesDir(userId),
9476                 passedIconFile.getName());
9477         if (!legitIconFile.getPath().equals(filePath)
9478                 || !filePath.contains(ActivityRecord.ACTIVITY_ICON_SUFFIX)) {
9479             throw new IllegalArgumentException("Bad file path: " + filePath
9480                     + " passed for userId " + userId);
9481         }
9482         return mRecentTasks.getTaskDescriptionIcon(filePath);
9483     }
9484
9485     @Override
9486     public void startInPlaceAnimationOnFrontMostApplication(ActivityOptions opts)
9487             throws RemoteException {
9488         if (opts.getAnimationType() != ActivityOptions.ANIM_CUSTOM_IN_PLACE ||
9489                 opts.getCustomInPlaceResId() == 0) {
9490             throw new IllegalArgumentException("Expected in-place ActivityOption " +
9491                     "with valid animation");
9492         }
9493         mWindowManager.prepareAppTransition(TRANSIT_TASK_IN_PLACE, false);
9494         mWindowManager.overridePendingAppTransitionInPlace(opts.getPackageName(),
9495                 opts.getCustomInPlaceResId());
9496         mWindowManager.executeAppTransition();
9497     }
9498
9499     private void cleanUpRemovedTaskLocked(TaskRecord tr, boolean killProcess,
9500             boolean removeFromRecents) {
9501         if (removeFromRecents) {
9502             mRecentTasks.remove(tr);
9503             tr.removedFromRecents();
9504         }
9505         ComponentName component = tr.getBaseIntent().getComponent();
9506         if (component == null) {
9507             Slog.w(TAG, "No component for base intent of task: " + tr);
9508             return;
9509         }
9510
9511         // Find any running services associated with this app and stop if needed.
9512         mServices.cleanUpRemovedTaskLocked(tr, component, new Intent(tr.getBaseIntent()));
9513
9514         if (!killProcess) {
9515             return;
9516         }
9517
9518         // Determine if the process(es) for this task should be killed.
9519         final String pkg = component.getPackageName();
9520         ArrayList<ProcessRecord> procsToKill = new ArrayList<>();
9521         ArrayMap<String, SparseArray<ProcessRecord>> pmap = mProcessNames.getMap();
9522         for (int i = 0; i < pmap.size(); i++) {
9523
9524             SparseArray<ProcessRecord> uids = pmap.valueAt(i);
9525             for (int j = 0; j < uids.size(); j++) {
9526                 ProcessRecord proc = uids.valueAt(j);
9527                 if (proc.userId != tr.userId) {
9528                     // Don't kill process for a different user.
9529                     continue;
9530                 }
9531                 if (proc == mHomeProcess) {
9532                     // Don't kill the home process along with tasks from the same package.
9533                     continue;
9534                 }
9535                 if (!proc.pkgList.containsKey(pkg)) {
9536                     // Don't kill process that is not associated with this task.
9537                     continue;
9538                 }
9539
9540                 for (int k = 0; k < proc.activities.size(); k++) {
9541                     TaskRecord otherTask = proc.activities.get(k).task;
9542                     if (tr.taskId != otherTask.taskId && otherTask.inRecents) {
9543                         // Don't kill process(es) that has an activity in a different task that is
9544                         // also in recents.
9545                         return;
9546                     }
9547                 }
9548
9549                 if (proc.foregroundServices) {
9550                     // Don't kill process(es) with foreground service.
9551                     return;
9552                 }
9553
9554                 // Add process to kill list.
9555                 procsToKill.add(proc);
9556             }
9557         }
9558
9559         // Kill the running processes.
9560         for (int i = 0; i < procsToKill.size(); i++) {
9561             ProcessRecord pr = procsToKill.get(i);
9562             if (pr.setSchedGroup == ProcessList.SCHED_GROUP_BACKGROUND
9563                     && pr.curReceiver == null) {
9564                 pr.kill("remove task", true);
9565             } else {
9566                 // We delay killing processes that are not in the background or running a receiver.
9567                 pr.waitingToKill = "remove task";
9568             }
9569         }
9570     }
9571
9572     private void removeTasksByPackageNameLocked(String packageName, int userId) {
9573         // Remove all tasks with activities in the specified package from the list of recent tasks
9574         for (int i = mRecentTasks.size() - 1; i >= 0; i--) {
9575             TaskRecord tr = mRecentTasks.get(i);
9576             if (tr.userId != userId) continue;
9577
9578             ComponentName cn = tr.intent.getComponent();
9579             if (cn != null && cn.getPackageName().equals(packageName)) {
9580                 // If the package name matches, remove the task.
9581                 removeTaskByIdLocked(tr.taskId, true, REMOVE_FROM_RECENTS);
9582             }
9583         }
9584     }
9585
9586     private void cleanupDisabledPackageTasksLocked(String packageName, Set<String> filterByClasses,
9587             int userId) {
9588
9589         for (int i = mRecentTasks.size() - 1; i >= 0; i--) {
9590             TaskRecord tr = mRecentTasks.get(i);
9591             if (userId != UserHandle.USER_ALL && tr.userId != userId) {
9592                 continue;
9593             }
9594
9595             ComponentName cn = tr.intent.getComponent();
9596             final boolean sameComponent = cn != null && cn.getPackageName().equals(packageName)
9597                     && (filterByClasses == null || filterByClasses.contains(cn.getClassName()));
9598             if (sameComponent) {
9599                 removeTaskByIdLocked(tr.taskId, false, REMOVE_FROM_RECENTS);
9600             }
9601         }
9602     }
9603
9604     /**
9605      * Removes the task with the specified task id.
9606      *
9607      * @param taskId Identifier of the task to be removed.
9608      * @param killProcess Kill any process associated with the task if possible.
9609      * @param removeFromRecents Whether to also remove the task from recents.
9610      * @return Returns true if the given task was found and removed.
9611      */
9612     private boolean removeTaskByIdLocked(int taskId, boolean killProcess,
9613             boolean removeFromRecents) {
9614         final TaskRecord tr = mStackSupervisor.anyTaskForIdLocked(
9615                 taskId, !RESTORE_FROM_RECENTS, INVALID_STACK_ID);
9616         if (tr != null) {
9617             tr.removeTaskActivitiesLocked();
9618             cleanUpRemovedTaskLocked(tr, killProcess, removeFromRecents);
9619             if (tr.isPersistable) {
9620                 notifyTaskPersisterLocked(null, true);
9621             }
9622             return true;
9623         }
9624         Slog.w(TAG, "Request to remove task ignored for non-existent task " + taskId);
9625         return false;
9626     }
9627
9628     @Override
9629     public void removeStack(int stackId) {
9630         enforceCallingPermission(Manifest.permission.MANAGE_ACTIVITY_STACKS, "removeStack()");
9631         if (stackId == HOME_STACK_ID) {
9632             throw new IllegalArgumentException("Removing home stack is not allowed.");
9633         }
9634
9635         synchronized (this) {
9636             final long ident = Binder.clearCallingIdentity();
9637             try {
9638                 final ActivityStack stack = mStackSupervisor.getStack(stackId);
9639                 if (stack == null) {
9640                     return;
9641                 }
9642                 final ArrayList<TaskRecord> tasks = stack.getAllTasks();
9643                 for (int i = tasks.size() - 1; i >= 0; i--) {
9644                     removeTaskByIdLocked(
9645                             tasks.get(i).taskId, true /* killProcess */, REMOVE_FROM_RECENTS);
9646                 }
9647             } finally {
9648                 Binder.restoreCallingIdentity(ident);
9649             }
9650         }
9651     }
9652
9653     @Override
9654     public boolean removeTask(int taskId) {
9655         enforceCallingPermission(android.Manifest.permission.REMOVE_TASKS, "removeTask()");
9656         synchronized (this) {
9657             final long ident = Binder.clearCallingIdentity();
9658             try {
9659                 return removeTaskByIdLocked(taskId, true, REMOVE_FROM_RECENTS);
9660             } finally {
9661                 Binder.restoreCallingIdentity(ident);
9662             }
9663         }
9664     }
9665
9666     /**
9667      * TODO: Add mController hook
9668      */
9669     @Override
9670     public void moveTaskToFront(int taskId, int flags, Bundle bOptions) {
9671         enforceCallingPermission(android.Manifest.permission.REORDER_TASKS, "moveTaskToFront()");
9672
9673         if (DEBUG_STACK) Slog.d(TAG_STACK, "moveTaskToFront: moving taskId=" + taskId);
9674         synchronized(this) {
9675             moveTaskToFrontLocked(taskId, flags, bOptions);
9676         }
9677     }
9678
9679     void moveTaskToFrontLocked(int taskId, int flags, Bundle bOptions) {
9680         ActivityOptions options = ActivityOptions.fromBundle(bOptions);
9681
9682         if (!checkAppSwitchAllowedLocked(Binder.getCallingPid(),
9683                 Binder.getCallingUid(), -1, -1, "Task to front")) {
9684             ActivityOptions.abort(options);
9685             return;
9686         }
9687         final long origId = Binder.clearCallingIdentity();
9688         try {
9689             final TaskRecord task = mStackSupervisor.anyTaskForIdLocked(taskId);
9690             if (task == null) {
9691                 Slog.d(TAG, "Could not find task for id: "+ taskId);
9692                 return;
9693             }
9694             if (mStackSupervisor.isLockTaskModeViolation(task)) {
9695                 mStackSupervisor.showLockTaskToast();
9696                 Slog.e(TAG, "moveTaskToFront: Attempt to violate Lock Task Mode");
9697                 return;
9698             }
9699             final ActivityRecord prev = mStackSupervisor.topRunningActivityLocked();
9700             if (prev != null && prev.isRecentsActivity()) {
9701                 task.setTaskToReturnTo(ActivityRecord.RECENTS_ACTIVITY_TYPE);
9702             }
9703             mStackSupervisor.findTaskToMoveToFrontLocked(task, flags, options, "moveTaskToFront",
9704                     false /* forceNonResizable */);
9705         } finally {
9706             Binder.restoreCallingIdentity(origId);
9707         }
9708         ActivityOptions.abort(options);
9709     }
9710
9711     /**
9712      * Moves an activity, and all of the other activities within the same task, to the bottom
9713      * of the history stack.  The activity's order within the task is unchanged.
9714      *
9715      * @param token A reference to the activity we wish to move
9716      * @param nonRoot If false then this only works if the activity is the root
9717      *                of a task; if true it will work for any activity in a task.
9718      * @return Returns true if the move completed, false if not.
9719      */
9720     @Override
9721     public boolean moveActivityTaskToBack(IBinder token, boolean nonRoot) {
9722         enforceNotIsolatedCaller("moveActivityTaskToBack");
9723         synchronized(this) {
9724             final long origId = Binder.clearCallingIdentity();
9725             try {
9726                 int taskId = ActivityRecord.getTaskForActivityLocked(token, !nonRoot);
9727                 final TaskRecord task = mStackSupervisor.anyTaskForIdLocked(taskId);
9728                 if (task != null) {
9729                     if (mStackSupervisor.isLockedTask(task)) {
9730                         mStackSupervisor.showLockTaskToast();
9731                         return false;
9732                     }
9733                     return ActivityRecord.getStackLocked(token).moveTaskToBackLocked(taskId);
9734                 }
9735             } finally {
9736                 Binder.restoreCallingIdentity(origId);
9737             }
9738         }
9739         return false;
9740     }
9741
9742     @Override
9743     public void moveTaskBackwards(int task) {
9744         enforceCallingPermission(android.Manifest.permission.REORDER_TASKS,
9745                 "moveTaskBackwards()");
9746
9747         synchronized(this) {
9748             if (!checkAppSwitchAllowedLocked(Binder.getCallingPid(),
9749                     Binder.getCallingUid(), -1, -1, "Task backwards")) {
9750                 return;
9751             }
9752             final long origId = Binder.clearCallingIdentity();
9753             moveTaskBackwardsLocked(task);
9754             Binder.restoreCallingIdentity(origId);
9755         }
9756     }
9757
9758     private final void moveTaskBackwardsLocked(int task) {
9759         Slog.e(TAG, "moveTaskBackwards not yet implemented!");
9760     }
9761
9762     @Override
9763     public IActivityContainer createVirtualActivityContainer(IBinder parentActivityToken,
9764             IActivityContainerCallback callback) throws RemoteException {
9765         enforceCallingPermission(MANAGE_ACTIVITY_STACKS, "createActivityContainer()");
9766         synchronized (this) {
9767             if (parentActivityToken == null) {
9768                 throw new IllegalArgumentException("parent token must not be null");
9769             }
9770             ActivityRecord r = ActivityRecord.forTokenLocked(parentActivityToken);
9771             if (r == null) {
9772                 return null;
9773             }
9774             if (callback == null) {
9775                 throw new IllegalArgumentException("callback must not be null");
9776             }
9777             return mStackSupervisor.createVirtualActivityContainer(r, callback);
9778         }
9779     }
9780
9781     @Override
9782     public void deleteActivityContainer(IActivityContainer container) throws RemoteException {
9783         enforceCallingPermission(MANAGE_ACTIVITY_STACKS, "deleteActivityContainer()");
9784         synchronized (this) {
9785             mStackSupervisor.deleteActivityContainer(container);
9786         }
9787     }
9788
9789     @Override
9790     public IActivityContainer createStackOnDisplay(int displayId) throws RemoteException {
9791         enforceCallingPermission(MANAGE_ACTIVITY_STACKS, "createStackOnDisplay()");
9792         synchronized (this) {
9793             final int stackId = mStackSupervisor.getNextStackId();
9794             final ActivityStack stack =
9795                     mStackSupervisor.createStackOnDisplay(stackId, displayId, true /*onTop*/);
9796             if (stack == null) {
9797                 return null;
9798             }
9799             return stack.mActivityContainer;
9800         }
9801     }
9802
9803     @Override
9804     public int getActivityDisplayId(IBinder activityToken) throws RemoteException {
9805         synchronized (this) {
9806             ActivityStack stack = ActivityRecord.getStackLocked(activityToken);
9807             if (stack != null && stack.mActivityContainer.isAttachedLocked()) {
9808                 return stack.mActivityContainer.getDisplayId();
9809             }
9810             return Display.DEFAULT_DISPLAY;
9811         }
9812     }
9813
9814     @Override
9815     public int getActivityStackId(IBinder token) throws RemoteException {
9816         synchronized (this) {
9817             ActivityStack stack = ActivityRecord.getStackLocked(token);
9818             if (stack == null) {
9819                 return INVALID_STACK_ID;
9820             }
9821             return stack.mStackId;
9822         }
9823     }
9824
9825     @Override
9826     public void exitFreeformMode(IBinder token) throws RemoteException {
9827         synchronized (this) {
9828             long ident = Binder.clearCallingIdentity();
9829             try {
9830                 final ActivityRecord r = ActivityRecord.forTokenLocked(token);
9831                 if (r == null) {
9832                     throw new IllegalArgumentException(
9833                             "exitFreeformMode: No activity record matching token=" + token);
9834                 }
9835                 final ActivityStack stack = r.getStackLocked(token);
9836                 if (stack == null || stack.mStackId != FREEFORM_WORKSPACE_STACK_ID) {
9837                     throw new IllegalStateException(
9838                             "exitFreeformMode: You can only go fullscreen from freeform.");
9839                 }
9840                 if (DEBUG_STACK) Slog.d(TAG_STACK, "exitFreeformMode: " + r);
9841                 mStackSupervisor.moveTaskToStackLocked(r.task.taskId, FULLSCREEN_WORKSPACE_STACK_ID,
9842                         ON_TOP, !FORCE_FOCUS, "exitFreeformMode", ANIMATE);
9843             } finally {
9844                 Binder.restoreCallingIdentity(ident);
9845             }
9846         }
9847     }
9848
9849     @Override
9850     public void moveTaskToStack(int taskId, int stackId, boolean toTop) {
9851         enforceCallingPermission(MANAGE_ACTIVITY_STACKS, "moveTaskToStack()");
9852         if (stackId == HOME_STACK_ID) {
9853             throw new IllegalArgumentException(
9854                     "moveTaskToStack: Attempt to move task " + taskId + " to home stack");
9855         }
9856         synchronized (this) {
9857             long ident = Binder.clearCallingIdentity();
9858             try {
9859                 if (DEBUG_STACK) Slog.d(TAG_STACK, "moveTaskToStack: moving task=" + taskId
9860                         + " to stackId=" + stackId + " toTop=" + toTop);
9861                 if (stackId == DOCKED_STACK_ID) {
9862                     mWindowManager.setDockedStackCreateState(DOCKED_STACK_CREATE_MODE_TOP_OR_LEFT,
9863                             null /* initialBounds */);
9864                 }
9865                 boolean result = mStackSupervisor.moveTaskToStackLocked(taskId, stackId, toTop,
9866                         !FORCE_FOCUS, "moveTaskToStack", ANIMATE);
9867                 if (result && stackId == DOCKED_STACK_ID) {
9868                     // If task moved to docked stack - show recents if needed.
9869                     mStackSupervisor.moveHomeStackTaskToTop(RECENTS_ACTIVITY_TYPE,
9870                             "moveTaskToDockedStack");
9871                 }
9872             } finally {
9873                 Binder.restoreCallingIdentity(ident);
9874             }
9875         }
9876     }
9877
9878     @Override
9879     public void swapDockedAndFullscreenStack() throws RemoteException {
9880         enforceCallingPermission(MANAGE_ACTIVITY_STACKS, "swapDockedAndFullscreenStack()");
9881         synchronized (this) {
9882             long ident = Binder.clearCallingIdentity();
9883             try {
9884                 final ActivityStack fullscreenStack = mStackSupervisor.getStack(
9885                         FULLSCREEN_WORKSPACE_STACK_ID);
9886                 final TaskRecord topTask = fullscreenStack != null ? fullscreenStack.topTask()
9887                         : null;
9888                 final ActivityStack dockedStack = mStackSupervisor.getStack(DOCKED_STACK_ID);
9889                 final ArrayList<TaskRecord> tasks = dockedStack != null ? dockedStack.getAllTasks()
9890                         : null;
9891                 if (topTask == null || tasks == null || tasks.size() == 0) {
9892                     Slog.w(TAG,
9893                             "Unable to swap tasks, either docked or fullscreen stack is empty.");
9894                     return;
9895                 }
9896
9897                 // TODO: App transition
9898                 mWindowManager.prepareAppTransition(TRANSIT_ACTIVITY_RELAUNCH, false);
9899
9900                 // Defer the resume so resume/pausing while moving stacks is dangerous.
9901                 mStackSupervisor.moveTaskToStackLocked(topTask.taskId, DOCKED_STACK_ID,
9902                         false /* toTop */, !FORCE_FOCUS, "swapDockedAndFullscreenStack",
9903                         ANIMATE, true /* deferResume */);
9904                 final int size = tasks.size();
9905                 for (int i = 0; i < size; i++) {
9906                     final int id = tasks.get(i).taskId;
9907                     if (id == topTask.taskId) {
9908                         continue;
9909                     }
9910                     mStackSupervisor.moveTaskToStackLocked(id,
9911                             FULLSCREEN_WORKSPACE_STACK_ID, true /* toTop */, !FORCE_FOCUS,
9912                             "swapDockedAndFullscreenStack", ANIMATE, true /* deferResume */);
9913                 }
9914
9915                 // Because we deferred the resume, to avoid conflicts with stack switches while
9916                 // resuming, we need to do it after all the tasks are moved.
9917                 mStackSupervisor.ensureActivitiesVisibleLocked(null, 0, !PRESERVE_WINDOWS);
9918                 mStackSupervisor.resumeFocusedStackTopActivityLocked();
9919
9920                 mWindowManager.executeAppTransition();
9921             } finally {
9922                 Binder.restoreCallingIdentity(ident);
9923             }
9924         }
9925     }
9926
9927     /**
9928      * Moves the input task to the docked stack.
9929      *
9930      * @param taskId Id of task to move.
9931      * @param createMode The mode the docked stack should be created in if it doesn't exist
9932      *                   already. See
9933      *                   {@link android.app.ActivityManager#DOCKED_STACK_CREATE_MODE_TOP_OR_LEFT}
9934      *                   and
9935      *                   {@link android.app.ActivityManager#DOCKED_STACK_CREATE_MODE_BOTTOM_OR_RIGHT}
9936      * @param toTop If the task and stack should be moved to the top.
9937      * @param animate Whether we should play an animation for the moving the task
9938      * @param initialBounds If the docked stack gets created, it will use these bounds for the
9939      *                      docked stack. Pass {@code null} to use default bounds.
9940      */
9941     @Override
9942     public boolean moveTaskToDockedStack(int taskId, int createMode, boolean toTop, boolean animate,
9943             Rect initialBounds, boolean moveHomeStackFront) {
9944         enforceCallingPermission(MANAGE_ACTIVITY_STACKS, "moveTaskToDockedStack()");
9945         synchronized (this) {
9946             long ident = Binder.clearCallingIdentity();
9947             try {
9948                 if (DEBUG_STACK) Slog.d(TAG_STACK, "moveTaskToDockedStack: moving task=" + taskId
9949                         + " to createMode=" + createMode + " toTop=" + toTop);
9950                 mWindowManager.setDockedStackCreateState(createMode, initialBounds);
9951                 final boolean moved = mStackSupervisor.moveTaskToStackLocked(
9952                         taskId, DOCKED_STACK_ID, toTop, !FORCE_FOCUS, "moveTaskToDockedStack",
9953                         animate, DEFER_RESUME);
9954                 if (moved) {
9955                     if (moveHomeStackFront) {
9956                         mStackSupervisor.moveHomeStackToFront("moveTaskToDockedStack");
9957                     }
9958                     mStackSupervisor.ensureActivitiesVisibleLocked(null, 0, !PRESERVE_WINDOWS);
9959                 }
9960                 return moved;
9961             } finally {
9962                 Binder.restoreCallingIdentity(ident);
9963             }
9964         }
9965     }
9966
9967     /**
9968      * Moves the top activity in the input stackId to the pinned stack.
9969      *
9970      * @param stackId Id of stack to move the top activity to pinned stack.
9971      * @param bounds Bounds to use for pinned stack.
9972      *
9973      * @return True if the top activity of the input stack was successfully moved to the pinned
9974      *          stack.
9975      */
9976     @Override
9977     public boolean moveTopActivityToPinnedStack(int stackId, Rect bounds) {
9978         enforceCallingPermission(MANAGE_ACTIVITY_STACKS, "moveTopActivityToPinnedStack()");
9979         synchronized (this) {
9980             if (!mSupportsPictureInPicture) {
9981                 throw new IllegalStateException("moveTopActivityToPinnedStack:"
9982                         + "Device doesn't support picture-in-pciture mode");
9983             }
9984
9985             long ident = Binder.clearCallingIdentity();
9986             try {
9987                 return mStackSupervisor.moveTopStackActivityToPinnedStackLocked(stackId, bounds);
9988             } finally {
9989                 Binder.restoreCallingIdentity(ident);
9990             }
9991         }
9992     }
9993
9994     @Override
9995     public void resizeStack(int stackId, Rect bounds, boolean allowResizeInDockedMode,
9996             boolean preserveWindows, boolean animate, int animationDuration) {
9997         enforceCallingPermission(MANAGE_ACTIVITY_STACKS, "resizeStack()");
9998         long ident = Binder.clearCallingIdentity();
9999         try {
10000             synchronized (this) {
10001                 if (animate) {
10002                     if (stackId == PINNED_STACK_ID) {
10003                         mWindowManager.animateResizePinnedStack(bounds, animationDuration);
10004                     } else {
10005                         throw new IllegalArgumentException("Stack: " + stackId
10006                                 + " doesn't support animated resize.");
10007                     }
10008                 } else {
10009                     mStackSupervisor.resizeStackLocked(stackId, bounds, null /* tempTaskBounds */,
10010                             null /* tempTaskInsetBounds */, preserveWindows,
10011                             allowResizeInDockedMode, !DEFER_RESUME);
10012                 }
10013             }
10014         } finally {
10015             Binder.restoreCallingIdentity(ident);
10016         }
10017     }
10018
10019     @Override
10020     public void resizeDockedStack(Rect dockedBounds, Rect tempDockedTaskBounds,
10021             Rect tempDockedTaskInsetBounds,
10022             Rect tempOtherTaskBounds, Rect tempOtherTaskInsetBounds) {
10023         enforceCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS,
10024                 "resizeDockedStack()");
10025         long ident = Binder.clearCallingIdentity();
10026         try {
10027             synchronized (this) {
10028                 mStackSupervisor.resizeDockedStackLocked(dockedBounds, tempDockedTaskBounds,
10029                         tempDockedTaskInsetBounds, tempOtherTaskBounds, tempOtherTaskInsetBounds,
10030                         PRESERVE_WINDOWS);
10031             }
10032         } finally {
10033             Binder.restoreCallingIdentity(ident);
10034         }
10035     }
10036
10037     @Override
10038     public void resizePinnedStack(Rect pinnedBounds, Rect tempPinnedTaskBounds) {
10039         enforceCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS,
10040                 "resizePinnedStack()");
10041         final long ident = Binder.clearCallingIdentity();
10042         try {
10043             synchronized (this) {
10044                 mStackSupervisor.resizePinnedStackLocked(pinnedBounds, tempPinnedTaskBounds);
10045             }
10046         } finally {
10047             Binder.restoreCallingIdentity(ident);
10048         }
10049     }
10050
10051     @Override
10052     public void positionTaskInStack(int taskId, int stackId, int position) {
10053         enforceCallingPermission(MANAGE_ACTIVITY_STACKS, "positionTaskInStack()");
10054         if (stackId == HOME_STACK_ID) {
10055             throw new IllegalArgumentException(
10056                     "positionTaskInStack: Attempt to change the position of task "
10057                     + taskId + " in/to home stack");
10058         }
10059         synchronized (this) {
10060             long ident = Binder.clearCallingIdentity();
10061             try {
10062                 if (DEBUG_STACK) Slog.d(TAG_STACK,
10063                         "positionTaskInStack: positioning task=" + taskId
10064                         + " in stackId=" + stackId + " at position=" + position);
10065                 mStackSupervisor.positionTaskInStackLocked(taskId, stackId, position);
10066             } finally {
10067                 Binder.restoreCallingIdentity(ident);
10068             }
10069         }
10070     }
10071
10072     @Override
10073     public List<StackInfo> getAllStackInfos() {
10074         enforceCallingPermission(MANAGE_ACTIVITY_STACKS, "getAllStackInfos()");
10075         long ident = Binder.clearCallingIdentity();
10076         try {
10077             synchronized (this) {
10078                 return mStackSupervisor.getAllStackInfosLocked();
10079             }
10080         } finally {
10081             Binder.restoreCallingIdentity(ident);
10082         }
10083     }
10084
10085     @Override
10086     public StackInfo getStackInfo(int stackId) {
10087         enforceCallingPermission(MANAGE_ACTIVITY_STACKS, "getStackInfo()");
10088         long ident = Binder.clearCallingIdentity();
10089         try {
10090             synchronized (this) {
10091                 return mStackSupervisor.getStackInfoLocked(stackId);
10092             }
10093         } finally {
10094             Binder.restoreCallingIdentity(ident);
10095         }
10096     }
10097
10098     @Override
10099     public boolean isInHomeStack(int taskId) {
10100         enforceCallingPermission(MANAGE_ACTIVITY_STACKS, "getStackInfo()");
10101         long ident = Binder.clearCallingIdentity();
10102         try {
10103             synchronized (this) {
10104                 final TaskRecord tr = mStackSupervisor.anyTaskForIdLocked(
10105                         taskId, !RESTORE_FROM_RECENTS, INVALID_STACK_ID);
10106                 return tr != null && tr.stack != null && tr.stack.isHomeStack();
10107             }
10108         } finally {
10109             Binder.restoreCallingIdentity(ident);
10110         }
10111     }
10112
10113     @Override
10114     public int getTaskForActivity(IBinder token, boolean onlyRoot) {
10115         synchronized(this) {
10116             return ActivityRecord.getTaskForActivityLocked(token, onlyRoot);
10117         }
10118     }
10119
10120     @Override
10121     public void updateDeviceOwner(String packageName) {
10122         final int callingUid = Binder.getCallingUid();
10123         if (callingUid != 0 && callingUid != Process.SYSTEM_UID) {
10124             throw new SecurityException("updateDeviceOwner called from non-system process");
10125         }
10126         synchronized (this) {
10127             mDeviceOwnerName = packageName;
10128         }
10129     }
10130
10131     @Override
10132     public void updateLockTaskPackages(int userId, String[] packages) {
10133         final int callingUid = Binder.getCallingUid();
10134         if (callingUid != 0 && callingUid != Process.SYSTEM_UID) {
10135             enforceCallingPermission(android.Manifest.permission.UPDATE_LOCK_TASK_PACKAGES,
10136                     "updateLockTaskPackages()");
10137         }
10138         synchronized (this) {
10139             if (DEBUG_LOCKTASK) Slog.w(TAG_LOCKTASK, "Whitelisting " + userId + ":" +
10140                     Arrays.toString(packages));
10141             mLockTaskPackages.put(userId, packages);
10142             mStackSupervisor.onLockTaskPackagesUpdatedLocked();
10143         }
10144     }
10145
10146
10147     void startLockTaskModeLocked(TaskRecord task) {
10148         if (DEBUG_LOCKTASK) Slog.w(TAG_LOCKTASK, "startLockTaskModeLocked: " + task);
10149         if (task.mLockTaskAuth == LOCK_TASK_AUTH_DONT_LOCK) {
10150             return;
10151         }
10152
10153         // isSystemInitiated is used to distinguish between locked and pinned mode, as pinned mode
10154         // is initiated by system after the pinning request was shown and locked mode is initiated
10155         // by an authorized app directly
10156         final int callingUid = Binder.getCallingUid();
10157         boolean isSystemInitiated = callingUid == Process.SYSTEM_UID;
10158         long ident = Binder.clearCallingIdentity();
10159         try {
10160             if (!isSystemInitiated) {
10161                 task.mLockTaskUid = callingUid;
10162                 if (task.mLockTaskAuth == LOCK_TASK_AUTH_PINNABLE) {
10163                     // startLockTask() called by app and task mode is lockTaskModeDefault.
10164                     if (DEBUG_LOCKTASK) Slog.w(TAG_LOCKTASK, "Mode default, asking user");
10165                     StatusBarManagerInternal statusBarManager =
10166                             LocalServices.getService(StatusBarManagerInternal.class);
10167                     if (statusBarManager != null) {
10168                         statusBarManager.showScreenPinningRequest(task.taskId);
10169                     }
10170                     return;
10171                 }
10172
10173                 final ActivityStack stack = mStackSupervisor.getFocusedStack();
10174                 if (stack == null || task != stack.topTask()) {
10175                     throw new IllegalArgumentException("Invalid task, not in foreground");
10176                 }
10177             }
10178             if (DEBUG_LOCKTASK) Slog.w(TAG_LOCKTASK, isSystemInitiated ? "Locking pinned" :
10179                     "Locking fully");
10180             mStackSupervisor.setLockTaskModeLocked(task, isSystemInitiated ?
10181                     ActivityManager.LOCK_TASK_MODE_PINNED :
10182                     ActivityManager.LOCK_TASK_MODE_LOCKED,
10183                     "startLockTask", true);
10184         } finally {
10185             Binder.restoreCallingIdentity(ident);
10186         }
10187     }
10188
10189     @Override
10190     public void startLockTaskMode(int taskId) {
10191         synchronized (this) {
10192             final TaskRecord task = mStackSupervisor.anyTaskForIdLocked(taskId);
10193             if (task != null) {
10194                 startLockTaskModeLocked(task);
10195             }
10196         }
10197     }
10198
10199     @Override
10200     public void startLockTaskMode(IBinder token) {
10201         synchronized (this) {
10202             final ActivityRecord r = ActivityRecord.forTokenLocked(token);
10203             if (r == null) {
10204                 return;
10205             }
10206             final TaskRecord task = r.task;
10207             if (task != null) {
10208                 startLockTaskModeLocked(task);
10209             }
10210         }
10211     }
10212
10213     @Override
10214     public void startSystemLockTaskMode(int taskId) throws RemoteException {
10215         enforceCallingPermission(MANAGE_ACTIVITY_STACKS, "startSystemLockTaskMode");
10216         // This makes inner call to look as if it was initiated by system.
10217         long ident = Binder.clearCallingIdentity();
10218         try {
10219             synchronized (this) {
10220                 startLockTaskMode(taskId);
10221             }
10222         } finally {
10223             Binder.restoreCallingIdentity(ident);
10224         }
10225     }
10226
10227     @Override
10228     public void stopLockTaskMode() {
10229         final TaskRecord lockTask = mStackSupervisor.getLockedTaskLocked();
10230         if (lockTask == null) {
10231             // Our work here is done.
10232             return;
10233         }
10234
10235         final int callingUid = Binder.getCallingUid();
10236         final int lockTaskUid = lockTask.mLockTaskUid;
10237         final int lockTaskModeState = mStackSupervisor.getLockTaskModeState();
10238         if (lockTaskModeState == ActivityManager.LOCK_TASK_MODE_NONE) {
10239             // Done.
10240             return;
10241         } else {
10242             // Ensure the same caller for startLockTaskMode and stopLockTaskMode.
10243             // It is possible lockTaskMode was started by the system process because
10244             // android:lockTaskMode is set to a locking value in the application manifest
10245             // instead of the app calling startLockTaskMode. In this case
10246             // {@link TaskRecord.mLockTaskUid} will be 0, so we compare the callingUid to the
10247             // {@link TaskRecord.effectiveUid} instead. Also caller with
10248             // {@link MANAGE_ACTIVITY_STACKS} can stop any lock task.
10249             if (checkCallingPermission(MANAGE_ACTIVITY_STACKS) != PERMISSION_GRANTED
10250                     && callingUid != lockTaskUid
10251                     && (lockTaskUid != 0 || callingUid != lockTask.effectiveUid)) {
10252                 throw new SecurityException("Invalid uid, expected " + lockTaskUid
10253                         + " callingUid=" + callingUid + " effectiveUid=" + lockTask.effectiveUid);
10254             }
10255         }
10256         long ident = Binder.clearCallingIdentity();
10257         try {
10258             Log.d(TAG, "stopLockTaskMode");
10259             // Stop lock task
10260             synchronized (this) {
10261                 mStackSupervisor.setLockTaskModeLocked(null, ActivityManager.LOCK_TASK_MODE_NONE,
10262                         "stopLockTask", true);
10263             }
10264             TelecomManager tm = (TelecomManager) mContext.getSystemService(Context.TELECOM_SERVICE);
10265             if (tm != null) {
10266                 tm.showInCallScreen(false);
10267             }
10268         } finally {
10269             Binder.restoreCallingIdentity(ident);
10270         }
10271     }
10272
10273     /**
10274      * This API should be called by SystemUI only when user perform certain action to dismiss
10275      * lock task mode. We should only dismiss pinned lock task mode in this case.
10276      */
10277     @Override
10278     public void stopSystemLockTaskMode() throws RemoteException {
10279         if (mStackSupervisor.getLockTaskModeState() == ActivityManager.LOCK_TASK_MODE_PINNED) {
10280             stopLockTaskMode();
10281         } else {
10282             mStackSupervisor.showLockTaskToast();
10283         }
10284     }
10285
10286     @Override
10287     public boolean isInLockTaskMode() {
10288         return getLockTaskModeState() != ActivityManager.LOCK_TASK_MODE_NONE;
10289     }
10290
10291     @Override
10292     public int getLockTaskModeState() {
10293         synchronized (this) {
10294             return mStackSupervisor.getLockTaskModeState();
10295         }
10296     }
10297
10298     @Override
10299     public void showLockTaskEscapeMessage(IBinder token) {
10300         synchronized (this) {
10301             final ActivityRecord r = ActivityRecord.forTokenLocked(token);
10302             if (r == null) {
10303                 return;
10304             }
10305             mStackSupervisor.showLockTaskEscapeMessageLocked(r.task);
10306         }
10307     }
10308
10309     // =========================================================
10310     // CONTENT PROVIDERS
10311     // =========================================================
10312
10313     private final List<ProviderInfo> generateApplicationProvidersLocked(ProcessRecord app) {
10314         List<ProviderInfo> providers = null;
10315         try {
10316             providers = AppGlobals.getPackageManager()
10317                     .queryContentProviders(app.processName, app.uid,
10318                             STOCK_PM_FLAGS | PackageManager.GET_URI_PERMISSION_PATTERNS
10319                                     | MATCH_DEBUG_TRIAGED_MISSING)
10320                     .getList();
10321         } catch (RemoteException ex) {
10322         }
10323         if (DEBUG_MU) Slog.v(TAG_MU,
10324                 "generateApplicationProvidersLocked, app.info.uid = " + app.uid);
10325         int userId = app.userId;
10326         if (providers != null) {
10327             int N = providers.size();
10328             app.pubProviders.ensureCapacity(N + app.pubProviders.size());
10329             for (int i=0; i<N; i++) {
10330                 // TODO: keep logic in sync with installEncryptionUnawareProviders
10331                 ProviderInfo cpi =
10332                     (ProviderInfo)providers.get(i);
10333                 boolean singleton = isSingleton(cpi.processName, cpi.applicationInfo,
10334                         cpi.name, cpi.flags);
10335                 if (singleton && UserHandle.getUserId(app.uid) != UserHandle.USER_SYSTEM) {
10336                     // This is a singleton provider, but a user besides the
10337                     // default user is asking to initialize a process it runs
10338                     // in...  well, no, it doesn't actually run in this process,
10339                     // it runs in the process of the default user.  Get rid of it.
10340                     providers.remove(i);
10341                     N--;
10342                     i--;
10343                     continue;
10344                 }
10345
10346                 ComponentName comp = new ComponentName(cpi.packageName, cpi.name);
10347                 ContentProviderRecord cpr = mProviderMap.getProviderByClass(comp, userId);
10348                 if (cpr == null) {
10349                     cpr = new ContentProviderRecord(this, cpi, app.info, comp, singleton);
10350                     mProviderMap.putProviderByClass(comp, cpr);
10351                 }
10352                 if (DEBUG_MU) Slog.v(TAG_MU,
10353                         "generateApplicationProvidersLocked, cpi.uid = " + cpr.uid);
10354                 app.pubProviders.put(cpi.name, cpr);
10355                 if (!cpi.multiprocess || !"android".equals(cpi.packageName)) {
10356                     // Don't add this if it is a platform component that is marked
10357                     // to run in multiple processes, because this is actually
10358                     // part of the framework so doesn't make sense to track as a
10359                     // separate apk in the process.
10360                     app.addPackage(cpi.applicationInfo.packageName, cpi.applicationInfo.versionCode,
10361                             mProcessStats);
10362                 }
10363                 notifyPackageUse(cpi.applicationInfo.packageName,
10364                                  PackageManager.NOTIFY_PACKAGE_USE_CONTENT_PROVIDER);
10365             }
10366         }
10367         return providers;
10368     }
10369
10370     /**
10371      * Check if the calling UID has a possible chance at accessing the provider
10372      * at the given authority and user.
10373      */
10374     public String checkContentProviderAccess(String authority, int userId) {
10375         if (userId == UserHandle.USER_ALL) {
10376             mContext.enforceCallingOrSelfPermission(
10377                     Manifest.permission.INTERACT_ACROSS_USERS_FULL, TAG);
10378             userId = UserHandle.getCallingUserId();
10379         }
10380
10381         ProviderInfo cpi = null;
10382         try {
10383             cpi = AppGlobals.getPackageManager().resolveContentProvider(authority,
10384                     STOCK_PM_FLAGS | PackageManager.GET_URI_PERMISSION_PATTERNS
10385                             | PackageManager.MATCH_DIRECT_BOOT_AWARE
10386                             | PackageManager.MATCH_DIRECT_BOOT_UNAWARE,
10387                     userId);
10388         } catch (RemoteException ignored) {
10389         }
10390         if (cpi == null) {
10391             // TODO: make this an outright failure in a future platform release;
10392             // until then anonymous content notifications are unprotected
10393             //return "Failed to find provider " + authority + " for user " + userId;
10394             return null;
10395         }
10396
10397         ProcessRecord r = null;
10398         synchronized (mPidsSelfLocked) {
10399             r = mPidsSelfLocked.get(Binder.getCallingPid());
10400         }
10401         if (r == null) {
10402             return "Failed to find PID " + Binder.getCallingPid();
10403         }
10404
10405         synchronized (this) {
10406             return checkContentProviderPermissionLocked(cpi, r, userId, true);
10407         }
10408     }
10409
10410     /**
10411      * Check if {@link ProcessRecord} has a possible chance at accessing the
10412      * given {@link ProviderInfo}. Final permission checking is always done
10413      * in {@link ContentProvider}.
10414      */
10415     private final String checkContentProviderPermissionLocked(
10416             ProviderInfo cpi, ProcessRecord r, int userId, boolean checkUser) {
10417         final int callingPid = (r != null) ? r.pid : Binder.getCallingPid();
10418         final int callingUid = (r != null) ? r.uid : Binder.getCallingUid();
10419         boolean checkedGrants = false;
10420         if (checkUser) {
10421             // Looking for cross-user grants before enforcing the typical cross-users permissions
10422             int tmpTargetUserId = mUserController.unsafeConvertIncomingUserLocked(userId);
10423             if (tmpTargetUserId != UserHandle.getUserId(callingUid)) {
10424                 if (checkAuthorityGrants(callingUid, cpi, tmpTargetUserId, checkUser)) {
10425                     return null;
10426                 }
10427                 checkedGrants = true;
10428             }
10429             userId = mUserController.handleIncomingUser(callingPid, callingUid, userId, false,
10430                     ALLOW_NON_FULL, "checkContentProviderPermissionLocked " + cpi.authority, null);
10431             if (userId != tmpTargetUserId) {
10432                 // When we actually went to determine the final targer user ID, this ended
10433                 // up different than our initial check for the authority.  This is because
10434                 // they had asked for USER_CURRENT_OR_SELF and we ended up switching to
10435                 // SELF.  So we need to re-check the grants again.
10436                 checkedGrants = false;
10437             }
10438         }
10439         if (checkComponentPermission(cpi.readPermission, callingPid, callingUid,
10440                 cpi.applicationInfo.uid, cpi.exported)
10441                 == PackageManager.PERMISSION_GRANTED) {
10442             return null;
10443         }
10444         if (checkComponentPermission(cpi.writePermission, callingPid, callingUid,
10445                 cpi.applicationInfo.uid, cpi.exported)
10446                 == PackageManager.PERMISSION_GRANTED) {
10447             return null;
10448         }
10449
10450         PathPermission[] pps = cpi.pathPermissions;
10451         if (pps != null) {
10452             int i = pps.length;
10453             while (i > 0) {
10454                 i--;
10455                 PathPermission pp = pps[i];
10456                 String pprperm = pp.getReadPermission();
10457                 if (pprperm != null && checkComponentPermission(pprperm, callingPid, callingUid,
10458                         cpi.applicationInfo.uid, cpi.exported)
10459                         == PackageManager.PERMISSION_GRANTED) {
10460                     return null;
10461                 }
10462                 String ppwperm = pp.getWritePermission();
10463                 if (ppwperm != null && checkComponentPermission(ppwperm, callingPid, callingUid,
10464                         cpi.applicationInfo.uid, cpi.exported)
10465                         == PackageManager.PERMISSION_GRANTED) {
10466                     return null;
10467                 }
10468             }
10469         }
10470         if (!checkedGrants && checkAuthorityGrants(callingUid, cpi, userId, checkUser)) {
10471             return null;
10472         }
10473
10474         String msg;
10475         if (!cpi.exported) {
10476             msg = "Permission Denial: opening provider " + cpi.name
10477                     + " from " + (r != null ? r : "(null)") + " (pid=" + callingPid
10478                     + ", uid=" + callingUid + ") that is not exported from uid "
10479                     + cpi.applicationInfo.uid;
10480         } else {
10481             msg = "Permission Denial: opening provider " + cpi.name
10482                     + " from " + (r != null ? r : "(null)") + " (pid=" + callingPid
10483                     + ", uid=" + callingUid + ") requires "
10484                     + cpi.readPermission + " or " + cpi.writePermission;
10485         }
10486         Slog.w(TAG, msg);
10487         return msg;
10488     }
10489
10490     /**
10491      * Returns if the ContentProvider has granted a uri to callingUid
10492      */
10493     boolean checkAuthorityGrants(int callingUid, ProviderInfo cpi, int userId, boolean checkUser) {
10494         final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.get(callingUid);
10495         if (perms != null) {
10496             for (int i=perms.size()-1; i>=0; i--) {
10497                 GrantUri grantUri = perms.keyAt(i);
10498                 if (grantUri.sourceUserId == userId || !checkUser) {
10499                     if (matchesProvider(grantUri.uri, cpi)) {
10500                         return true;
10501                     }
10502                 }
10503             }
10504         }
10505         return false;
10506     }
10507
10508     /**
10509      * Returns true if the uri authority is one of the authorities specified in the provider.
10510      */
10511     boolean matchesProvider(Uri uri, ProviderInfo cpi) {
10512         String uriAuth = uri.getAuthority();
10513         String cpiAuth = cpi.authority;
10514         if (cpiAuth.indexOf(';') == -1) {
10515             return cpiAuth.equals(uriAuth);
10516         }
10517         String[] cpiAuths = cpiAuth.split(";");
10518         int length = cpiAuths.length;
10519         for (int i = 0; i < length; i++) {
10520             if (cpiAuths[i].equals(uriAuth)) return true;
10521         }
10522         return false;
10523     }
10524
10525     ContentProviderConnection incProviderCountLocked(ProcessRecord r,
10526             final ContentProviderRecord cpr, IBinder externalProcessToken, boolean stable) {
10527         if (r != null) {
10528             for (int i=0; i<r.conProviders.size(); i++) {
10529                 ContentProviderConnection conn = r.conProviders.get(i);
10530                 if (conn.provider == cpr) {
10531                     if (DEBUG_PROVIDER) Slog.v(TAG_PROVIDER,
10532                             "Adding provider requested by "
10533                             + r.processName + " from process "
10534                             + cpr.info.processName + ": " + cpr.name.flattenToShortString()
10535                             + " scnt=" + conn.stableCount + " uscnt=" + conn.unstableCount);
10536                     if (stable) {
10537                         conn.stableCount++;
10538                         conn.numStableIncs++;
10539                     } else {
10540                         conn.unstableCount++;
10541                         conn.numUnstableIncs++;
10542                     }
10543                     return conn;
10544                 }
10545             }
10546             ContentProviderConnection conn = new ContentProviderConnection(cpr, r);
10547             if (stable) {
10548                 conn.stableCount = 1;
10549                 conn.numStableIncs = 1;
10550             } else {
10551                 conn.unstableCount = 1;
10552                 conn.numUnstableIncs = 1;
10553             }
10554             cpr.connections.add(conn);
10555             r.conProviders.add(conn);
10556             startAssociationLocked(r.uid, r.processName, r.curProcState,
10557                     cpr.uid, cpr.name, cpr.info.processName);
10558             return conn;
10559         }
10560         cpr.addExternalProcessHandleLocked(externalProcessToken);
10561         return null;
10562     }
10563
10564     boolean decProviderCountLocked(ContentProviderConnection conn,
10565             ContentProviderRecord cpr, IBinder externalProcessToken, boolean stable) {
10566         if (conn != null) {
10567             cpr = conn.provider;
10568             if (DEBUG_PROVIDER) Slog.v(TAG_PROVIDER,
10569                     "Removing provider requested by "
10570                     + conn.client.processName + " from process "
10571                     + cpr.info.processName + ": " + cpr.name.flattenToShortString()
10572                     + " scnt=" + conn.stableCount + " uscnt=" + conn.unstableCount);
10573             if (stable) {
10574                 conn.stableCount--;
10575             } else {
10576                 conn.unstableCount--;
10577             }
10578             if (conn.stableCount == 0 && conn.unstableCount == 0) {
10579                 cpr.connections.remove(conn);
10580                 conn.client.conProviders.remove(conn);
10581                 if (conn.client.setProcState < ActivityManager.PROCESS_STATE_LAST_ACTIVITY) {
10582                     // The client is more important than last activity -- note the time this
10583                     // is happening, so we keep the old provider process around a bit as last
10584                     // activity to avoid thrashing it.
10585                     if (cpr.proc != null) {
10586                         cpr.proc.lastProviderTime = SystemClock.uptimeMillis();
10587                     }
10588                 }
10589                 stopAssociationLocked(conn.client.uid, conn.client.processName, cpr.uid, cpr.name);
10590                 return true;
10591             }
10592             return false;
10593         }
10594         cpr.removeExternalProcessHandleLocked(externalProcessToken);
10595         return false;
10596     }
10597
10598     private void checkTime(long startTime, String where) {
10599         long now = SystemClock.uptimeMillis();
10600         if ((now-startTime) > 50) {
10601             // If we are taking more than 50ms, log about it.
10602             Slog.w(TAG, "Slow operation: " + (now-startTime) + "ms so far, now at " + where);
10603         }
10604     }
10605
10606     private static final int[] PROCESS_STATE_STATS_FORMAT = new int[] {
10607             PROC_SPACE_TERM,
10608             PROC_SPACE_TERM|PROC_PARENS,
10609             PROC_SPACE_TERM|PROC_CHAR|PROC_OUT_LONG,        // 3: process state
10610     };
10611
10612     private final long[] mProcessStateStatsLongs = new long[1];
10613
10614     boolean isProcessAliveLocked(ProcessRecord proc) {
10615         if (proc.procStatFile == null) {
10616             proc.procStatFile = "/proc/" + proc.pid + "/stat";
10617         }
10618         mProcessStateStatsLongs[0] = 0;
10619         if (!Process.readProcFile(proc.procStatFile, PROCESS_STATE_STATS_FORMAT, null,
10620                 mProcessStateStatsLongs, null)) {
10621             if (DEBUG_OOM_ADJ) Slog.d(TAG, "UNABLE TO RETRIEVE STATE FOR " + proc.procStatFile);
10622             return false;
10623         }
10624         final long state = mProcessStateStatsLongs[0];
10625         if (DEBUG_OOM_ADJ) Slog.d(TAG, "RETRIEVED STATE FOR " + proc.procStatFile + ": "
10626                 + (char)state);
10627         return state != 'Z' && state != 'X' && state != 'x' && state != 'K';
10628     }
10629
10630     private ContentProviderHolder getContentProviderImpl(IApplicationThread caller,
10631             String name, IBinder token, boolean stable, int userId) {
10632         ContentProviderRecord cpr;
10633         ContentProviderConnection conn = null;
10634         ProviderInfo cpi = null;
10635
10636         synchronized(this) {
10637             long startTime = SystemClock.uptimeMillis();
10638
10639             ProcessRecord r = null;
10640             if (caller != null) {
10641                 r = getRecordForAppLocked(caller);
10642                 if (r == null) {
10643                     throw new SecurityException(
10644                             "Unable to find app for caller " + caller
10645                           + " (pid=" + Binder.getCallingPid()
10646                           + ") when getting content provider " + name);
10647                 }
10648             }
10649
10650             boolean checkCrossUser = true;
10651
10652             checkTime(startTime, "getContentProviderImpl: getProviderByName");
10653
10654             // First check if this content provider has been published...
10655             cpr = mProviderMap.getProviderByName(name, userId);
10656             // If that didn't work, check if it exists for user 0 and then
10657             // verify that it's a singleton provider before using it.
10658             if (cpr == null && userId != UserHandle.USER_SYSTEM) {
10659                 cpr = mProviderMap.getProviderByName(name, UserHandle.USER_SYSTEM);
10660                 if (cpr != null) {
10661                     cpi = cpr.info;
10662                     if (isSingleton(cpi.processName, cpi.applicationInfo,
10663                             cpi.name, cpi.flags)
10664                             && isValidSingletonCall(r.uid, cpi.applicationInfo.uid)) {
10665                         userId = UserHandle.USER_SYSTEM;
10666                         checkCrossUser = false;
10667                     } else {
10668                         cpr = null;
10669                         cpi = null;
10670                     }
10671                 }
10672             }
10673
10674             boolean providerRunning = cpr != null && cpr.proc != null && !cpr.proc.killed;
10675             if (providerRunning) {
10676                 cpi = cpr.info;
10677                 String msg;
10678                 checkTime(startTime, "getContentProviderImpl: before checkContentProviderPermission");
10679                 if ((msg = checkContentProviderPermissionLocked(cpi, r, userId, checkCrossUser))
10680                         != null) {
10681                     throw new SecurityException(msg);
10682                 }
10683                 checkTime(startTime, "getContentProviderImpl: after checkContentProviderPermission");
10684
10685                 if (r != null && cpr.canRunHere(r)) {
10686                     // This provider has been published or is in the process
10687                     // of being published...  but it is also allowed to run
10688                     // in the caller's process, so don't make a connection
10689                     // and just let the caller instantiate its own instance.
10690                     ContentProviderHolder holder = cpr.newHolder(null);
10691                     // don't give caller the provider object, it needs
10692                     // to make its own.
10693                     holder.provider = null;
10694                     return holder;
10695                 }
10696
10697                 final long origId = Binder.clearCallingIdentity();
10698
10699                 checkTime(startTime, "getContentProviderImpl: incProviderCountLocked");
10700
10701                 // In this case the provider instance already exists, so we can
10702                 // return it right away.
10703                 conn = incProviderCountLocked(r, cpr, token, stable);
10704                 if (conn != null && (conn.stableCount+conn.unstableCount) == 1) {
10705                     if (cpr.proc != null && r.setAdj <= ProcessList.PERCEPTIBLE_APP_ADJ) {
10706                         // If this is a perceptible app accessing the provider,
10707                         // make sure to count it as being accessed and thus
10708                         // back up on the LRU list.  This is good because
10709                         // content providers are often expensive to start.
10710                         checkTime(startTime, "getContentProviderImpl: before updateLruProcess");
10711                         updateLruProcessLocked(cpr.proc, false, null);
10712                         checkTime(startTime, "getContentProviderImpl: after updateLruProcess");
10713                     }
10714                 }
10715
10716                 checkTime(startTime, "getContentProviderImpl: before updateOomAdj");
10717                 final int verifiedAdj = cpr.proc.verifiedAdj;
10718                 boolean success = updateOomAdjLocked(cpr.proc);
10719                 // XXX things have changed so updateOomAdjLocked doesn't actually tell us
10720                 // if the process has been successfully adjusted.  So to reduce races with
10721                 // it, we will check whether the process still exists.  Note that this doesn't
10722                 // completely get rid of races with LMK killing the process, but should make
10723                 // them much smaller.
10724                 if (success && verifiedAdj != cpr.proc.setAdj && !isProcessAliveLocked(cpr.proc)) {
10725                     success = false;
10726                 }
10727                 maybeUpdateProviderUsageStatsLocked(r, cpr.info.packageName, name);
10728                 checkTime(startTime, "getContentProviderImpl: after updateOomAdj");
10729                 if (DEBUG_PROVIDER) Slog.i(TAG_PROVIDER, "Adjust success: " + success);
10730                 // NOTE: there is still a race here where a signal could be
10731                 // pending on the process even though we managed to update its
10732                 // adj level.  Not sure what to do about this, but at least
10733                 // the race is now smaller.
10734                 if (!success) {
10735                     // Uh oh...  it looks like the provider's process
10736                     // has been killed on us.  We need to wait for a new
10737                     // process to be started, and make sure its death
10738                     // doesn't kill our process.
10739                     Slog.i(TAG, "Existing provider " + cpr.name.flattenToShortString()
10740                             + " is crashing; detaching " + r);
10741                     boolean lastRef = decProviderCountLocked(conn, cpr, token, stable);
10742                     checkTime(startTime, "getContentProviderImpl: before appDied");
10743                     appDiedLocked(cpr.proc);
10744                     checkTime(startTime, "getContentProviderImpl: after appDied");
10745                     if (!lastRef) {
10746                         // This wasn't the last ref our process had on
10747                         // the provider...  we have now been killed, bail.
10748                         return null;
10749                     }
10750                     providerRunning = false;
10751                     conn = null;
10752                 } else {
10753                     cpr.proc.verifiedAdj = cpr.proc.setAdj;
10754                 }
10755
10756                 Binder.restoreCallingIdentity(origId);
10757             }
10758
10759             if (!providerRunning) {
10760                 try {
10761                     checkTime(startTime, "getContentProviderImpl: before resolveContentProvider");
10762                     cpi = AppGlobals.getPackageManager().
10763                         resolveContentProvider(name,
10764                             STOCK_PM_FLAGS | PackageManager.GET_URI_PERMISSION_PATTERNS, userId);
10765                     checkTime(startTime, "getContentProviderImpl: after resolveContentProvider");
10766                 } catch (RemoteException ex) {
10767                 }
10768                 if (cpi == null) {
10769                     return null;
10770                 }
10771                 // If the provider is a singleton AND
10772                 // (it's a call within the same user || the provider is a
10773                 // privileged app)
10774                 // Then allow connecting to the singleton provider
10775                 boolean singleton = isSingleton(cpi.processName, cpi.applicationInfo,
10776                         cpi.name, cpi.flags)
10777                         && isValidSingletonCall(r.uid, cpi.applicationInfo.uid);
10778                 if (singleton) {
10779                     userId = UserHandle.USER_SYSTEM;
10780                 }
10781                 cpi.applicationInfo = getAppInfoForUser(cpi.applicationInfo, userId);
10782                 checkTime(startTime, "getContentProviderImpl: got app info for user");
10783
10784                 String msg;
10785                 checkTime(startTime, "getContentProviderImpl: before checkContentProviderPermission");
10786                 if ((msg = checkContentProviderPermissionLocked(cpi, r, userId, !singleton))
10787                         != null) {
10788                     throw new SecurityException(msg);
10789                 }
10790                 checkTime(startTime, "getContentProviderImpl: after checkContentProviderPermission");
10791
10792                 if (!mProcessesReady
10793                         && !cpi.processName.equals("system")) {
10794                     // If this content provider does not run in the system
10795                     // process, and the system is not yet ready to run other
10796                     // processes, then fail fast instead of hanging.
10797                     throw new IllegalArgumentException(
10798                             "Attempt to launch content provider before system ready");
10799                 }
10800
10801                 // Make sure that the user who owns this provider is running.  If not,
10802                 // we don't want to allow it to run.
10803                 if (!mUserController.isUserRunningLocked(userId, 0)) {
10804                     Slog.w(TAG, "Unable to launch app "
10805                             + cpi.applicationInfo.packageName + "/"
10806                             + cpi.applicationInfo.uid + " for provider "
10807                             + name + ": user " + userId + " is stopped");
10808                     return null;
10809                 }
10810
10811                 ComponentName comp = new ComponentName(cpi.packageName, cpi.name);
10812                 checkTime(startTime, "getContentProviderImpl: before getProviderByClass");
10813                 cpr = mProviderMap.getProviderByClass(comp, userId);
10814                 checkTime(startTime, "getContentProviderImpl: after getProviderByClass");
10815                 final boolean firstClass = cpr == null;
10816                 if (firstClass) {
10817                     final long ident = Binder.clearCallingIdentity();
10818
10819                     // If permissions need a review before any of the app components can run,
10820                     // we return no provider and launch a review activity if the calling app
10821                     // is in the foreground.
10822                     if (Build.PERMISSIONS_REVIEW_REQUIRED) {
10823                         if (!requestTargetProviderPermissionsReviewIfNeededLocked(cpi, r, userId)) {
10824                             return null;
10825                         }
10826                     }
10827
10828                     try {
10829                         checkTime(startTime, "getContentProviderImpl: before getApplicationInfo");
10830                         ApplicationInfo ai =
10831                             AppGlobals.getPackageManager().
10832                                 getApplicationInfo(
10833                                         cpi.applicationInfo.packageName,
10834                                         STOCK_PM_FLAGS, userId);
10835                         checkTime(startTime, "getContentProviderImpl: after getApplicationInfo");
10836                         if (ai == null) {
10837                             Slog.w(TAG, "No package info for content provider "
10838                                     + cpi.name);
10839                             return null;
10840                         }
10841                         ai = getAppInfoForUser(ai, userId);
10842                         cpr = new ContentProviderRecord(this, cpi, ai, comp, singleton);
10843                     } catch (RemoteException ex) {
10844                         // pm is in same process, this will never happen.
10845                     } finally {
10846                         Binder.restoreCallingIdentity(ident);
10847                     }
10848                 }
10849
10850                 checkTime(startTime, "getContentProviderImpl: now have ContentProviderRecord");
10851
10852                 if (r != null && cpr.canRunHere(r)) {
10853                     // If this is a multiprocess provider, then just return its
10854                     // info and allow the caller to instantiate it.  Only do
10855                     // this if the provider is the same user as the caller's
10856                     // process, or can run as root (so can be in any process).
10857                     return cpr.newHolder(null);
10858                 }
10859
10860                 if (DEBUG_PROVIDER) Slog.w(TAG_PROVIDER, "LAUNCHING REMOTE PROVIDER (myuid "
10861                             + (r != null ? r.uid : null) + " pruid " + cpr.appInfo.uid + "): "
10862                             + cpr.info.name + " callers=" + Debug.getCallers(6));
10863
10864                 // This is single process, and our app is now connecting to it.
10865                 // See if we are already in the process of launching this
10866                 // provider.
10867                 final int N = mLaunchingProviders.size();
10868                 int i;
10869                 for (i = 0; i < N; i++) {
10870                     if (mLaunchingProviders.get(i) == cpr) {
10871                         break;
10872                     }
10873                 }
10874
10875                 // If the provider is not already being launched, then get it
10876                 // started.
10877                 if (i >= N) {
10878                     final long origId = Binder.clearCallingIdentity();
10879
10880                     try {
10881                         // Content provider is now in use, its package can't be stopped.
10882                         try {
10883                             checkTime(startTime, "getContentProviderImpl: before set stopped state");
10884                             AppGlobals.getPackageManager().setPackageStoppedState(
10885                                     cpr.appInfo.packageName, false, userId);
10886                             checkTime(startTime, "getContentProviderImpl: after set stopped state");
10887                         } catch (RemoteException e) {
10888                         } catch (IllegalArgumentException e) {
10889                             Slog.w(TAG, "Failed trying to unstop package "
10890                                     + cpr.appInfo.packageName + ": " + e);
10891                         }
10892
10893                         // Use existing process if already started
10894                         checkTime(startTime, "getContentProviderImpl: looking for process record");
10895                         ProcessRecord proc = getProcessRecordLocked(
10896                                 cpi.processName, cpr.appInfo.uid, false);
10897                         if (proc != null && proc.thread != null && !proc.killed) {
10898                             if (DEBUG_PROVIDER) Slog.d(TAG_PROVIDER,
10899                                     "Installing in existing process " + proc);
10900                             if (!proc.pubProviders.containsKey(cpi.name)) {
10901                                 checkTime(startTime, "getContentProviderImpl: scheduling install");
10902                                 proc.pubProviders.put(cpi.name, cpr);
10903                                 try {
10904                                     proc.thread.scheduleInstallProvider(cpi);
10905                                 } catch (RemoteException e) {
10906                                 }
10907                             }
10908                         } else {
10909                             checkTime(startTime, "getContentProviderImpl: before start process");
10910                             proc = startProcessLocked(cpi.processName,
10911                                     cpr.appInfo, false, 0, "content provider",
10912                                     new ComponentName(cpi.applicationInfo.packageName,
10913                                             cpi.name), false, false, false);
10914                             checkTime(startTime, "getContentProviderImpl: after start process");
10915                             if (proc == null) {
10916                                 Slog.w(TAG, "Unable to launch app "
10917                                         + cpi.applicationInfo.packageName + "/"
10918                                         + cpi.applicationInfo.uid + " for provider "
10919                                         + name + ": process is bad");
10920                                 return null;
10921                             }
10922                         }
10923                         cpr.launchingApp = proc;
10924                         mLaunchingProviders.add(cpr);
10925                     } finally {
10926                         Binder.restoreCallingIdentity(origId);
10927                     }
10928                 }
10929
10930                 checkTime(startTime, "getContentProviderImpl: updating data structures");
10931
10932                 // Make sure the provider is published (the same provider class
10933                 // may be published under multiple names).
10934                 if (firstClass) {
10935                     mProviderMap.putProviderByClass(comp, cpr);
10936                 }
10937
10938                 mProviderMap.putProviderByName(name, cpr);
10939                 conn = incProviderCountLocked(r, cpr, token, stable);
10940                 if (conn != null) {
10941                     conn.waiting = true;
10942                 }
10943             }
10944             checkTime(startTime, "getContentProviderImpl: done!");
10945         }
10946
10947         // Wait for the provider to be published...
10948         synchronized (cpr) {
10949             while (cpr.provider == null) {
10950                 if (cpr.launchingApp == null) {
10951                     Slog.w(TAG, "Unable to launch app "
10952                             + cpi.applicationInfo.packageName + "/"
10953                             + cpi.applicationInfo.uid + " for provider "
10954                             + name + ": launching app became null");
10955                     EventLog.writeEvent(EventLogTags.AM_PROVIDER_LOST_PROCESS,
10956                             UserHandle.getUserId(cpi.applicationInfo.uid),
10957                             cpi.applicationInfo.packageName,
10958                             cpi.applicationInfo.uid, name);
10959                     return null;
10960                 }
10961                 try {
10962                     if (DEBUG_MU) Slog.v(TAG_MU,
10963                             "Waiting to start provider " + cpr
10964                             + " launchingApp=" + cpr.launchingApp);
10965                     if (conn != null) {
10966                         conn.waiting = true;
10967                     }
10968                     cpr.wait();
10969                 } catch (InterruptedException ex) {
10970                 } finally {
10971                     if (conn != null) {
10972                         conn.waiting = false;
10973                     }
10974                 }
10975             }
10976         }
10977         return cpr != null ? cpr.newHolder(conn) : null;
10978     }
10979
10980     private boolean requestTargetProviderPermissionsReviewIfNeededLocked(ProviderInfo cpi,
10981             ProcessRecord r, final int userId) {
10982         if (getPackageManagerInternalLocked().isPermissionsReviewRequired(
10983                 cpi.packageName, userId)) {
10984
10985             final boolean callerForeground = r == null || r.setSchedGroup
10986                     != ProcessList.SCHED_GROUP_BACKGROUND;
10987
10988             // Show a permission review UI only for starting from a foreground app
10989             if (!callerForeground) {
10990                 Slog.w(TAG, "u" + userId + " Instantiating a provider in package"
10991                         + cpi.packageName + " requires a permissions review");
10992                 return false;
10993             }
10994
10995             final Intent intent = new Intent(Intent.ACTION_REVIEW_PERMISSIONS);
10996             intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK
10997                     | Intent.FLAG_ACTIVITY_EXCLUDE_FROM_RECENTS);
10998             intent.putExtra(Intent.EXTRA_PACKAGE_NAME, cpi.packageName);
10999
11000             if (DEBUG_PERMISSIONS_REVIEW) {
11001                 Slog.i(TAG, "u" + userId + " Launching permission review "
11002                         + "for package " + cpi.packageName);
11003             }
11004
11005             final UserHandle userHandle = new UserHandle(userId);
11006             mHandler.post(new Runnable() {
11007                 @Override
11008                 public void run() {
11009                     mContext.startActivityAsUser(intent, userHandle);
11010                 }
11011             });
11012
11013             return false;
11014         }
11015
11016         return true;
11017     }
11018
11019     PackageManagerInternal getPackageManagerInternalLocked() {
11020         if (mPackageManagerInt == null) {
11021             mPackageManagerInt = LocalServices.getService(PackageManagerInternal.class);
11022         }
11023         return mPackageManagerInt;
11024     }
11025
11026     @Override
11027     public final ContentProviderHolder getContentProvider(
11028             IApplicationThread caller, String name, int userId, boolean stable) {
11029         enforceNotIsolatedCaller("getContentProvider");
11030         if (caller == null) {
11031             String msg = "null IApplicationThread when getting content provider "
11032                     + name;
11033             Slog.w(TAG, msg);
11034             throw new SecurityException(msg);
11035         }
11036         // The incoming user check is now handled in checkContentProviderPermissionLocked() to deal
11037         // with cross-user grant.
11038         return getContentProviderImpl(caller, name, null, stable, userId);
11039     }
11040
11041     public ContentProviderHolder getContentProviderExternal(
11042             String name, int userId, IBinder token) {
11043         enforceCallingPermission(android.Manifest.permission.ACCESS_CONTENT_PROVIDERS_EXTERNALLY,
11044             "Do not have permission in call getContentProviderExternal()");
11045         userId = mUserController.handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(),
11046                 userId, false, ALLOW_FULL_ONLY, "getContentProvider", null);
11047         return getContentProviderExternalUnchecked(name, token, userId);
11048     }
11049
11050     private ContentProviderHolder getContentProviderExternalUnchecked(String name,
11051             IBinder token, int userId) {
11052         return getContentProviderImpl(null, name, token, true, userId);
11053     }
11054
11055     /**
11056      * Drop a content provider from a ProcessRecord's bookkeeping
11057      */
11058     public void removeContentProvider(IBinder connection, boolean stable) {
11059         enforceNotIsolatedCaller("removeContentProvider");
11060         long ident = Binder.clearCallingIdentity();
11061         try {
11062             synchronized (this) {
11063                 ContentProviderConnection conn;
11064                 try {
11065                     conn = (ContentProviderConnection)connection;
11066                 } catch (ClassCastException e) {
11067                     String msg ="removeContentProvider: " + connection
11068                             + " not a ContentProviderConnection";
11069                     Slog.w(TAG, msg);
11070                     throw new IllegalArgumentException(msg);
11071                 }
11072                 if (conn == null) {
11073                     throw new NullPointerException("connection is null");
11074                 }
11075                 if (decProviderCountLocked(conn, null, null, stable)) {
11076                     updateOomAdjLocked();
11077                 }
11078             }
11079         } finally {
11080             Binder.restoreCallingIdentity(ident);
11081         }
11082     }
11083
11084     public void removeContentProviderExternal(String name, IBinder token) {
11085         enforceCallingPermission(android.Manifest.permission.ACCESS_CONTENT_PROVIDERS_EXTERNALLY,
11086             "Do not have permission in call removeContentProviderExternal()");
11087         int userId = UserHandle.getCallingUserId();
11088         long ident = Binder.clearCallingIdentity();
11089         try {
11090             removeContentProviderExternalUnchecked(name, token, userId);
11091         } finally {
11092             Binder.restoreCallingIdentity(ident);
11093         }
11094     }
11095
11096     private void removeContentProviderExternalUnchecked(String name, IBinder token, int userId) {
11097         synchronized (this) {
11098             ContentProviderRecord cpr = mProviderMap.getProviderByName(name, userId);
11099             if(cpr == null) {
11100                 //remove from mProvidersByClass
11101                 if(DEBUG_ALL) Slog.v(TAG, name+" content provider not found in providers list");
11102                 return;
11103             }
11104
11105             //update content provider record entry info
11106             ComponentName comp = new ComponentName(cpr.info.packageName, cpr.info.name);
11107             ContentProviderRecord localCpr = mProviderMap.getProviderByClass(comp, userId);
11108             if (localCpr.hasExternalProcessHandles()) {
11109                 if (localCpr.removeExternalProcessHandleLocked(token)) {
11110                     updateOomAdjLocked();
11111                 } else {
11112                     Slog.e(TAG, "Attmpt to remove content provider " + localCpr
11113                             + " with no external reference for token: "
11114                             + token + ".");
11115                 }
11116             } else {
11117                 Slog.e(TAG, "Attmpt to remove content provider: " + localCpr
11118                         + " with no external references.");
11119             }
11120         }
11121     }
11122
11123     public final void publishContentProviders(IApplicationThread caller,
11124             List<ContentProviderHolder> providers) {
11125         if (providers == null) {
11126             return;
11127         }
11128
11129         enforceNotIsolatedCaller("publishContentProviders");
11130         synchronized (this) {
11131             final ProcessRecord r = getRecordForAppLocked(caller);
11132             if (DEBUG_MU) Slog.v(TAG_MU, "ProcessRecord uid = " + r.uid);
11133             if (r == null) {
11134                 throw new SecurityException(
11135                         "Unable to find app for caller " + caller
11136                       + " (pid=" + Binder.getCallingPid()
11137                       + ") when publishing content providers");
11138             }
11139
11140             final long origId = Binder.clearCallingIdentity();
11141
11142             final int N = providers.size();
11143             for (int i = 0; i < N; i++) {
11144                 ContentProviderHolder src = providers.get(i);
11145                 if (src == null || src.info == null || src.provider == null) {
11146                     continue;
11147                 }
11148                 ContentProviderRecord dst = r.pubProviders.get(src.info.name);
11149                 if (DEBUG_MU) Slog.v(TAG_MU, "ContentProviderRecord uid = " + dst.uid);
11150                 if (dst != null) {
11151                     ComponentName comp = new ComponentName(dst.info.packageName, dst.info.name);
11152                     mProviderMap.putProviderByClass(comp, dst);
11153                     String names[] = dst.info.authority.split(";");
11154                     for (int j = 0; j < names.length; j++) {
11155                         mProviderMap.putProviderByName(names[j], dst);
11156                     }
11157
11158                     int launchingCount = mLaunchingProviders.size();
11159                     int j;
11160                     boolean wasInLaunchingProviders = false;
11161                     for (j = 0; j < launchingCount; j++) {
11162                         if (mLaunchingProviders.get(j) == dst) {
11163                             mLaunchingProviders.remove(j);
11164                             wasInLaunchingProviders = true;
11165                             j--;
11166                             launchingCount--;
11167                         }
11168                     }
11169                     if (wasInLaunchingProviders) {
11170                         mHandler.removeMessages(CONTENT_PROVIDER_PUBLISH_TIMEOUT_MSG, r);
11171                     }
11172                     synchronized (dst) {
11173                         dst.provider = src.provider;
11174                         dst.proc = r;
11175                         dst.notifyAll();
11176                     }
11177                     updateOomAdjLocked(r);
11178                     maybeUpdateProviderUsageStatsLocked(r, src.info.packageName,
11179                             src.info.authority);
11180                 }
11181             }
11182
11183             Binder.restoreCallingIdentity(origId);
11184         }
11185     }
11186
11187     public boolean refContentProvider(IBinder connection, int stable, int unstable) {
11188         ContentProviderConnection conn;
11189         try {
11190             conn = (ContentProviderConnection)connection;
11191         } catch (ClassCastException e) {
11192             String msg ="refContentProvider: " + connection
11193                     + " not a ContentProviderConnection";
11194             Slog.w(TAG, msg);
11195             throw new IllegalArgumentException(msg);
11196         }
11197         if (conn == null) {
11198             throw new NullPointerException("connection is null");
11199         }
11200
11201         synchronized (this) {
11202             if (stable > 0) {
11203                 conn.numStableIncs += stable;
11204             }
11205             stable = conn.stableCount + stable;
11206             if (stable < 0) {
11207                 throw new IllegalStateException("stableCount < 0: " + stable);
11208             }
11209
11210             if (unstable > 0) {
11211                 conn.numUnstableIncs += unstable;
11212             }
11213             unstable = conn.unstableCount + unstable;
11214             if (unstable < 0) {
11215                 throw new IllegalStateException("unstableCount < 0: " + unstable);
11216             }
11217
11218             if ((stable+unstable) <= 0) {
11219                 throw new IllegalStateException("ref counts can't go to zero here: stable="
11220                         + stable + " unstable=" + unstable);
11221             }
11222             conn.stableCount = stable;
11223             conn.unstableCount = unstable;
11224             return !conn.dead;
11225         }
11226     }
11227
11228     public void unstableProviderDied(IBinder connection) {
11229         ContentProviderConnection conn;
11230         try {
11231             conn = (ContentProviderConnection)connection;
11232         } catch (ClassCastException e) {
11233             String msg ="refContentProvider: " + connection
11234                     + " not a ContentProviderConnection";
11235             Slog.w(TAG, msg);
11236             throw new IllegalArgumentException(msg);
11237         }
11238         if (conn == null) {
11239             throw new NullPointerException("connection is null");
11240         }
11241
11242         // Safely retrieve the content provider associated with the connection.
11243         IContentProvider provider;
11244         synchronized (this) {
11245             provider = conn.provider.provider;
11246         }
11247
11248         if (provider == null) {
11249             // Um, yeah, we're way ahead of you.
11250             return;
11251         }
11252
11253         // Make sure the caller is being honest with us.
11254         if (provider.asBinder().pingBinder()) {
11255             // Er, no, still looks good to us.
11256             synchronized (this) {
11257                 Slog.w(TAG, "unstableProviderDied: caller " + Binder.getCallingUid()
11258                         + " says " + conn + " died, but we don't agree");
11259                 return;
11260             }
11261         }
11262
11263         // Well look at that!  It's dead!
11264         synchronized (this) {
11265             if (conn.provider.provider != provider) {
11266                 // But something changed...  good enough.
11267                 return;
11268             }
11269
11270             ProcessRecord proc = conn.provider.proc;
11271             if (proc == null || proc.thread == null) {
11272                 // Seems like the process is already cleaned up.
11273                 return;
11274             }
11275
11276             // As far as we're concerned, this is just like receiving a
11277             // death notification...  just a bit prematurely.
11278             Slog.i(TAG, "Process " + proc.processName + " (pid " + proc.pid
11279                     + ") early provider death");
11280             final long ident = Binder.clearCallingIdentity();
11281             try {
11282                 appDiedLocked(proc);
11283             } finally {
11284                 Binder.restoreCallingIdentity(ident);
11285             }
11286         }
11287     }
11288
11289     @Override
11290     public void appNotRespondingViaProvider(IBinder connection) {
11291         enforceCallingPermission(
11292                 android.Manifest.permission.REMOVE_TASKS, "appNotRespondingViaProvider()");
11293
11294         final ContentProviderConnection conn = (ContentProviderConnection) connection;
11295         if (conn == null) {
11296             Slog.w(TAG, "ContentProviderConnection is null");
11297             return;
11298         }
11299
11300         final ProcessRecord host = conn.provider.proc;
11301         if (host == null) {
11302             Slog.w(TAG, "Failed to find hosting ProcessRecord");
11303             return;
11304         }
11305
11306         mHandler.post(new Runnable() {
11307             @Override
11308             public void run() {
11309                 mAppErrors.appNotResponding(host, null, null, false,
11310                         "ContentProvider not responding");
11311             }
11312         });
11313     }
11314
11315     public final void installSystemProviders() {
11316         List<ProviderInfo> providers;
11317         synchronized (this) {
11318             ProcessRecord app = mProcessNames.get("system", Process.SYSTEM_UID);
11319             providers = generateApplicationProvidersLocked(app);
11320             if (providers != null) {
11321                 for (int i=providers.size()-1; i>=0; i--) {
11322                     ProviderInfo pi = (ProviderInfo)providers.get(i);
11323                     if ((pi.applicationInfo.flags&ApplicationInfo.FLAG_SYSTEM) == 0) {
11324                         Slog.w(TAG, "Not installing system proc provider " + pi.name
11325                                 + ": not system .apk");
11326                         providers.remove(i);
11327                     }
11328                 }
11329             }
11330         }
11331         if (providers != null) {
11332             mSystemThread.installSystemProviders(providers);
11333         }
11334
11335         mCoreSettingsObserver = new CoreSettingsObserver(this);
11336         mFontScaleSettingObserver = new FontScaleSettingObserver();
11337
11338         //mUsageStatsService.monitorPackages();
11339     }
11340
11341     private void startPersistentApps(int matchFlags) {
11342         if (mFactoryTest == FactoryTest.FACTORY_TEST_LOW_LEVEL) return;
11343
11344         synchronized (this) {
11345             try {
11346                 final List<ApplicationInfo> apps = AppGlobals.getPackageManager()
11347                         .getPersistentApplications(STOCK_PM_FLAGS | matchFlags).getList();
11348                 for (ApplicationInfo app : apps) {
11349                     if (!"android".equals(app.packageName)) {
11350                         addAppLocked(app, false, null /* ABI override */);
11351                     }
11352                 }
11353             } catch (RemoteException ex) {
11354             }
11355         }
11356     }
11357
11358     /**
11359      * When a user is unlocked, we need to install encryption-unaware providers
11360      * belonging to any running apps.
11361      */
11362     private void installEncryptionUnawareProviders(int userId) {
11363         // We're only interested in providers that are encryption unaware, and
11364         // we don't care about uninstalled apps, since there's no way they're
11365         // running at this point.
11366         final int matchFlags = GET_PROVIDERS | MATCH_DIRECT_BOOT_UNAWARE;
11367
11368         synchronized (this) {
11369             final int NP = mProcessNames.getMap().size();
11370             for (int ip = 0; ip < NP; ip++) {
11371                 final SparseArray<ProcessRecord> apps = mProcessNames.getMap().valueAt(ip);
11372                 final int NA = apps.size();
11373                 for (int ia = 0; ia < NA; ia++) {
11374                     final ProcessRecord app = apps.valueAt(ia);
11375                     if (app.userId != userId || app.thread == null || app.unlocked) continue;
11376
11377                     final int NG = app.pkgList.size();
11378                     for (int ig = 0; ig < NG; ig++) {
11379                         try {
11380                             final String pkgName = app.pkgList.keyAt(ig);
11381                             final PackageInfo pkgInfo = AppGlobals.getPackageManager()
11382                                     .getPackageInfo(pkgName, matchFlags, userId);
11383                             if (pkgInfo != null && !ArrayUtils.isEmpty(pkgInfo.providers)) {
11384                                 for (ProviderInfo pi : pkgInfo.providers) {
11385                                     // TODO: keep in sync with generateApplicationProvidersLocked
11386                                     final boolean processMatch = Objects.equals(pi.processName,
11387                                             app.processName) || pi.multiprocess;
11388                                     final boolean userMatch = isSingleton(pi.processName,
11389                                             pi.applicationInfo, pi.name, pi.flags)
11390                                                     ? (app.userId == UserHandle.USER_SYSTEM) : true;
11391                                     if (processMatch && userMatch) {
11392                                         Log.v(TAG, "Installing " + pi);
11393                                         app.thread.scheduleInstallProvider(pi);
11394                                     } else {
11395                                         Log.v(TAG, "Skipping " + pi);
11396                                     }
11397                                 }
11398                             }
11399                         } catch (RemoteException ignored) {
11400                         }
11401                     }
11402                 }
11403             }
11404         }
11405     }
11406
11407     /**
11408      * Allows apps to retrieve the MIME type of a URI.
11409      * If an app is in the same user as the ContentProvider, or if it is allowed to interact across
11410      * users, then it does not need permission to access the ContentProvider.
11411      * Either, it needs cross-user uri grants.
11412      *
11413      * CTS tests for this functionality can be run with "runtest cts-appsecurity".
11414      *
11415      * Test cases are at cts/tests/appsecurity-tests/test-apps/UsePermissionDiffCert/
11416      *     src/com/android/cts/usespermissiondiffcertapp/AccessPermissionWithDiffSigTest.java
11417      */
11418     public String getProviderMimeType(Uri uri, int userId) {
11419         enforceNotIsolatedCaller("getProviderMimeType");
11420         final String name = uri.getAuthority();
11421         int callingUid = Binder.getCallingUid();
11422         int callingPid = Binder.getCallingPid();
11423         long ident = 0;
11424         boolean clearedIdentity = false;
11425         synchronized (this) {
11426             userId = mUserController.unsafeConvertIncomingUserLocked(userId);
11427         }
11428         if (canClearIdentity(callingPid, callingUid, userId)) {
11429             clearedIdentity = true;
11430             ident = Binder.clearCallingIdentity();
11431         }
11432         ContentProviderHolder holder = null;
11433         try {
11434             holder = getContentProviderExternalUnchecked(name, null, userId);
11435             if (holder != null) {
11436                 return holder.provider.getType(uri);
11437             }
11438         } catch (RemoteException e) {
11439             Log.w(TAG, "Content provider dead retrieving " + uri, e);
11440             return null;
11441         } catch (Exception e) {
11442             Log.w(TAG, "Exception while determining type of " + uri, e);
11443             return null;
11444         } finally {
11445             // We need to clear the identity to call removeContentProviderExternalUnchecked
11446             if (!clearedIdentity) {
11447                 ident = Binder.clearCallingIdentity();
11448             }
11449             try {
11450                 if (holder != null) {
11451                     removeContentProviderExternalUnchecked(name, null, userId);
11452                 }
11453             } finally {
11454                 Binder.restoreCallingIdentity(ident);
11455             }
11456         }
11457
11458         return null;
11459     }
11460
11461     private boolean canClearIdentity(int callingPid, int callingUid, int userId) {
11462         if (UserHandle.getUserId(callingUid) == userId) {
11463             return true;
11464         }
11465         if (checkComponentPermission(INTERACT_ACROSS_USERS, callingPid,
11466                 callingUid, -1, true) == PackageManager.PERMISSION_GRANTED
11467                 || checkComponentPermission(INTERACT_ACROSS_USERS_FULL, callingPid,
11468                 callingUid, -1, true) == PackageManager.PERMISSION_GRANTED) {
11469                 return true;
11470         }
11471         return false;
11472     }
11473
11474     // =========================================================
11475     // GLOBAL MANAGEMENT
11476     // =========================================================
11477
11478     final ProcessRecord newProcessRecordLocked(ApplicationInfo info, String customProcess,
11479             boolean isolated, int isolatedUid) {
11480         String proc = customProcess != null ? customProcess : info.processName;
11481         BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
11482         final int userId = UserHandle.getUserId(info.uid);
11483         int uid = info.uid;
11484         if (isolated) {
11485             if (isolatedUid == 0) {
11486                 int stepsLeft = Process.LAST_ISOLATED_UID - Process.FIRST_ISOLATED_UID + 1;
11487                 while (true) {
11488                     if (mNextIsolatedProcessUid < Process.FIRST_ISOLATED_UID
11489                             || mNextIsolatedProcessUid > Process.LAST_ISOLATED_UID) {
11490                         mNextIsolatedProcessUid = Process.FIRST_ISOLATED_UID;
11491                     }
11492                     uid = UserHandle.getUid(userId, mNextIsolatedProcessUid);
11493                     mNextIsolatedProcessUid++;
11494                     if (mIsolatedProcesses.indexOfKey(uid) < 0) {
11495                         // No process for this uid, use it.
11496                         break;
11497                     }
11498                     stepsLeft--;
11499                     if (stepsLeft <= 0) {
11500                         return null;
11501                     }
11502                 }
11503             } else {
11504                 // Special case for startIsolatedProcess (internal only), where
11505                 // the uid of the isolated process is specified by the caller.
11506                 uid = isolatedUid;
11507             }
11508         }
11509         final ProcessRecord r = new ProcessRecord(stats, info, proc, uid);
11510         if (!mBooted && !mBooting
11511                 && userId == UserHandle.USER_SYSTEM
11512                 && (info.flags & PERSISTENT_MASK) == PERSISTENT_MASK) {
11513             r.persistent = true;
11514         }
11515         addProcessNameLocked(r);
11516         return r;
11517     }
11518
11519     final ProcessRecord addAppLocked(ApplicationInfo info, boolean isolated,
11520             String abiOverride) {
11521         ProcessRecord app;
11522         if (!isolated) {
11523             app = getProcessRecordLocked(info.processName, info.uid, true);
11524         } else {
11525             app = null;
11526         }
11527
11528         if (app == null) {
11529             app = newProcessRecordLocked(info, null, isolated, 0);
11530             updateLruProcessLocked(app, false, null);
11531             updateOomAdjLocked();
11532         }
11533
11534         // This package really, really can not be stopped.
11535         try {
11536             AppGlobals.getPackageManager().setPackageStoppedState(
11537                     info.packageName, false, UserHandle.getUserId(app.uid));
11538         } catch (RemoteException e) {
11539         } catch (IllegalArgumentException e) {
11540             Slog.w(TAG, "Failed trying to unstop package "
11541                     + info.packageName + ": " + e);
11542         }
11543
11544         if ((info.flags & PERSISTENT_MASK) == PERSISTENT_MASK) {
11545             app.persistent = true;
11546             app.maxAdj = ProcessList.PERSISTENT_PROC_ADJ;
11547         }
11548         if (app.thread == null && mPersistentStartingProcesses.indexOf(app) < 0) {
11549             mPersistentStartingProcesses.add(app);
11550             startProcessLocked(app, "added application", app.processName, abiOverride,
11551                     null /* entryPoint */, null /* entryPointArgs */);
11552         }
11553
11554         return app;
11555     }
11556
11557     public void unhandledBack() {
11558         enforceCallingPermission(android.Manifest.permission.FORCE_BACK,
11559                 "unhandledBack()");
11560
11561         synchronized(this) {
11562             final long origId = Binder.clearCallingIdentity();
11563             try {
11564                 getFocusedStack().unhandledBackLocked();
11565             } finally {
11566                 Binder.restoreCallingIdentity(origId);
11567             }
11568         }
11569     }
11570
11571     public ParcelFileDescriptor openContentUri(Uri uri) throws RemoteException {
11572         enforceNotIsolatedCaller("openContentUri");
11573         final int userId = UserHandle.getCallingUserId();
11574         String name = uri.getAuthority();
11575         ContentProviderHolder cph = getContentProviderExternalUnchecked(name, null, userId);
11576         ParcelFileDescriptor pfd = null;
11577         if (cph != null) {
11578             // We record the binder invoker's uid in thread-local storage before
11579             // going to the content provider to open the file.  Later, in the code
11580             // that handles all permissions checks, we look for this uid and use
11581             // that rather than the Activity Manager's own uid.  The effect is that
11582             // we do the check against the caller's permissions even though it looks
11583             // to the content provider like the Activity Manager itself is making
11584             // the request.
11585             Binder token = new Binder();
11586             sCallerIdentity.set(new Identity(
11587                     token, Binder.getCallingPid(), Binder.getCallingUid()));
11588             try {
11589                 pfd = cph.provider.openFile(null, uri, "r", null, token);
11590             } catch (FileNotFoundException e) {
11591                 // do nothing; pfd will be returned null
11592             } finally {
11593                 // Ensure that whatever happens, we clean up the identity state
11594                 sCallerIdentity.remove();
11595                 // Ensure we're done with the provider.
11596                 removeContentProviderExternalUnchecked(name, null, userId);
11597             }
11598         } else {
11599             Slog.d(TAG, "Failed to get provider for authority '" + name + "'");
11600         }
11601         return pfd;
11602     }
11603
11604     // Actually is sleeping or shutting down or whatever else in the future
11605     // is an inactive state.
11606     boolean isSleepingOrShuttingDownLocked() {
11607         return isSleepingLocked() || mShuttingDown;
11608     }
11609
11610     boolean isShuttingDownLocked() {
11611         return mShuttingDown;
11612     }
11613
11614     boolean isSleepingLocked() {
11615         return mSleeping;
11616     }
11617
11618     void onWakefulnessChanged(int wakefulness) {
11619         synchronized(this) {
11620             mWakefulness = wakefulness;
11621             updateSleepIfNeededLocked();
11622         }
11623     }
11624
11625     void finishRunningVoiceLocked() {
11626         if (mRunningVoice != null) {
11627             mRunningVoice = null;
11628             mVoiceWakeLock.release();
11629             updateSleepIfNeededLocked();
11630         }
11631     }
11632
11633     void startTimeTrackingFocusedActivityLocked() {
11634         if (!mSleeping && mCurAppTimeTracker != null && mFocusedActivity != null) {
11635             mCurAppTimeTracker.start(mFocusedActivity.packageName);
11636         }
11637     }
11638
11639     void updateSleepIfNeededLocked() {
11640         if (mSleeping && !shouldSleepLocked()) {
11641             mSleeping = false;
11642             startTimeTrackingFocusedActivityLocked();
11643             mTopProcessState = ActivityManager.PROCESS_STATE_TOP;
11644             mStackSupervisor.comeOutOfSleepIfNeededLocked();
11645             updateOomAdjLocked();
11646         } else if (!mSleeping && shouldSleepLocked()) {
11647             mSleeping = true;
11648             if (mCurAppTimeTracker != null) {
11649                 mCurAppTimeTracker.stop();
11650             }
11651             mTopProcessState = ActivityManager.PROCESS_STATE_TOP_SLEEPING;
11652             mStackSupervisor.goingToSleepLocked();
11653             updateOomAdjLocked();
11654
11655             // Initialize the wake times of all processes.
11656             checkExcessivePowerUsageLocked(false);
11657             mHandler.removeMessages(CHECK_EXCESSIVE_WAKE_LOCKS_MSG);
11658             Message nmsg = mHandler.obtainMessage(CHECK_EXCESSIVE_WAKE_LOCKS_MSG);
11659             mHandler.sendMessageDelayed(nmsg, POWER_CHECK_DELAY);
11660         }
11661     }
11662
11663     private boolean shouldSleepLocked() {
11664         // Resume applications while running a voice interactor.
11665         if (mRunningVoice != null) {
11666             return false;
11667         }
11668
11669         // TODO: Transform the lock screen state into a sleep token instead.
11670         switch (mWakefulness) {
11671             case PowerManagerInternal.WAKEFULNESS_AWAKE:
11672             case PowerManagerInternal.WAKEFULNESS_DREAMING:
11673             case PowerManagerInternal.WAKEFULNESS_DOZING:
11674                 // Pause applications whenever the lock screen is shown or any sleep
11675                 // tokens have been acquired.
11676                 return (mLockScreenShown != LOCK_SCREEN_HIDDEN || !mSleepTokens.isEmpty());
11677             case PowerManagerInternal.WAKEFULNESS_ASLEEP:
11678             default:
11679                 // If we're asleep then pause applications unconditionally.
11680                 return true;
11681         }
11682     }
11683
11684     /** Pokes the task persister. */
11685     void notifyTaskPersisterLocked(TaskRecord task, boolean flush) {
11686         mRecentTasks.notifyTaskPersisterLocked(task, flush);
11687     }
11688
11689     /** Notifies all listeners when the task stack has changed. */
11690     void notifyTaskStackChangedLocked() {
11691         mHandler.sendEmptyMessage(LOG_STACK_STATE);
11692         mHandler.removeMessages(NOTIFY_TASK_STACK_CHANGE_LISTENERS_MSG);
11693         Message nmsg = mHandler.obtainMessage(NOTIFY_TASK_STACK_CHANGE_LISTENERS_MSG);
11694         mHandler.sendMessageDelayed(nmsg, NOTIFY_TASK_STACK_CHANGE_LISTENERS_DELAY);
11695     }
11696
11697     /** Notifies all listeners when an Activity is pinned. */
11698     void notifyActivityPinnedLocked() {
11699         mHandler.removeMessages(NOTIFY_ACTIVITY_PINNED_LISTENERS_MSG);
11700         mHandler.obtainMessage(NOTIFY_ACTIVITY_PINNED_LISTENERS_MSG).sendToTarget();
11701     }
11702
11703     /**
11704      * Notifies all listeners when an attempt was made to start an an activity that is already
11705      * running in the pinned stack and the activity was not actually started, but the task is
11706      * either brought to the front or a new Intent is delivered to it.
11707      */
11708     void notifyPinnedActivityRestartAttemptLocked() {
11709         mHandler.removeMessages(NOTIFY_PINNED_ACTIVITY_RESTART_ATTEMPT_LISTENERS_MSG);
11710         mHandler.obtainMessage(NOTIFY_PINNED_ACTIVITY_RESTART_ATTEMPT_LISTENERS_MSG).sendToTarget();
11711     }
11712
11713     /** Notifies all listeners when the pinned stack animation ends. */
11714     @Override
11715     public void notifyPinnedStackAnimationEnded() {
11716         synchronized (this) {
11717             mHandler.removeMessages(NOTIFY_PINNED_STACK_ANIMATION_ENDED_LISTENERS_MSG);
11718             mHandler.obtainMessage(
11719                     NOTIFY_PINNED_STACK_ANIMATION_ENDED_LISTENERS_MSG).sendToTarget();
11720         }
11721     }
11722
11723     @Override
11724     public void notifyCleartextNetwork(int uid, byte[] firstPacket) {
11725         mHandler.obtainMessage(NOTIFY_CLEARTEXT_NETWORK_MSG, uid, 0, firstPacket).sendToTarget();
11726     }
11727
11728     @Override
11729     public boolean shutdown(int timeout) {
11730         if (checkCallingPermission(android.Manifest.permission.SHUTDOWN)
11731                 != PackageManager.PERMISSION_GRANTED) {
11732             throw new SecurityException("Requires permission "
11733                     + android.Manifest.permission.SHUTDOWN);
11734         }
11735
11736         boolean timedout = false;
11737
11738         synchronized(this) {
11739             mShuttingDown = true;
11740             updateEventDispatchingLocked();
11741             timedout = mStackSupervisor.shutdownLocked(timeout);
11742         }
11743
11744         mAppOpsService.shutdown();
11745         if (mUsageStatsService != null) {
11746             mUsageStatsService.prepareShutdown();
11747         }
11748         mBatteryStatsService.shutdown();
11749         synchronized (this) {
11750             mProcessStats.shutdownLocked();
11751             notifyTaskPersisterLocked(null, true);
11752         }
11753
11754         return timedout;
11755     }
11756
11757     public final void activitySlept(IBinder token) {
11758         if (DEBUG_ALL) Slog.v(TAG, "Activity slept: token=" + token);
11759
11760         final long origId = Binder.clearCallingIdentity();
11761
11762         synchronized (this) {
11763             final ActivityRecord r = ActivityRecord.isInStackLocked(token);
11764             if (r != null) {
11765                 mStackSupervisor.activitySleptLocked(r);
11766             }
11767         }
11768
11769         Binder.restoreCallingIdentity(origId);
11770     }
11771
11772     private String lockScreenShownToString() {
11773         switch (mLockScreenShown) {
11774             case LOCK_SCREEN_HIDDEN: return "LOCK_SCREEN_HIDDEN";
11775             case LOCK_SCREEN_LEAVING: return "LOCK_SCREEN_LEAVING";
11776             case LOCK_SCREEN_SHOWN: return "LOCK_SCREEN_SHOWN";
11777             default: return "Unknown=" + mLockScreenShown;
11778         }
11779     }
11780
11781     void logLockScreen(String msg) {
11782         if (DEBUG_LOCKSCREEN) Slog.d(TAG_LOCKSCREEN, Debug.getCallers(2) + ":" + msg
11783                 + " mLockScreenShown=" + lockScreenShownToString() + " mWakefulness="
11784                 + PowerManagerInternal.wakefulnessToString(mWakefulness)
11785                 + " mSleeping=" + mSleeping);
11786     }
11787
11788     void startRunningVoiceLocked(IVoiceInteractionSession session, int targetUid) {
11789         Slog.d(TAG, "<<<  startRunningVoiceLocked()");
11790         mVoiceWakeLock.setWorkSource(new WorkSource(targetUid));
11791         if (mRunningVoice == null || mRunningVoice.asBinder() != session.asBinder()) {
11792             boolean wasRunningVoice = mRunningVoice != null;
11793             mRunningVoice = session;
11794             if (!wasRunningVoice) {
11795                 mVoiceWakeLock.acquire();
11796                 updateSleepIfNeededLocked();
11797             }
11798         }
11799     }
11800
11801     private void updateEventDispatchingLocked() {
11802         mWindowManager.setEventDispatching(mBooted && !mShuttingDown);
11803     }
11804
11805     public void setLockScreenShown(boolean showing, boolean occluded) {
11806         if (checkCallingPermission(android.Manifest.permission.DEVICE_POWER)
11807                 != PackageManager.PERMISSION_GRANTED) {
11808             throw new SecurityException("Requires permission "
11809                     + android.Manifest.permission.DEVICE_POWER);
11810         }
11811
11812         synchronized(this) {
11813             long ident = Binder.clearCallingIdentity();
11814             try {
11815                 if (DEBUG_LOCKSCREEN) logLockScreen(" showing=" + showing + " occluded=" + occluded);
11816                 mLockScreenShown = (showing && !occluded) ? LOCK_SCREEN_SHOWN : LOCK_SCREEN_HIDDEN;
11817                 if (showing && occluded) {
11818                     // The lock screen is currently showing, but is occluded by a window that can
11819                     // show on top of the lock screen. In this can we want to dismiss the docked
11820                     // stack since it will be complicated/risky to try to put the activity on top
11821                     // of the lock screen in the right fullscreen configuration.
11822                     mStackSupervisor.moveTasksToFullscreenStackLocked(DOCKED_STACK_ID,
11823                             mStackSupervisor.mFocusedStack.getStackId() == DOCKED_STACK_ID);
11824                 }
11825
11826                 updateSleepIfNeededLocked();
11827             } finally {
11828                 Binder.restoreCallingIdentity(ident);
11829             }
11830         }
11831     }
11832
11833     @Override
11834     public void notifyLockedProfile(@UserIdInt int userId) {
11835         try {
11836             if (!AppGlobals.getPackageManager().isUidPrivileged(Binder.getCallingUid())) {
11837                 throw new SecurityException("Only privileged app can call notifyLockedProfile");
11838             }
11839         } catch (RemoteException ex) {
11840             throw new SecurityException("Fail to check is caller a privileged app", ex);
11841         }
11842
11843         synchronized (this) {
11844             if (mStackSupervisor.isUserLockedProfile(userId)) {
11845                 final long ident = Binder.clearCallingIdentity();
11846                 try {
11847                     final int currentUserId = mUserController.getCurrentUserIdLocked();
11848
11849                     // Drop locked freeform tasks out into the fullscreen stack.
11850                     // TODO: Redact the tasks in place. It's much better to keep them on the screen
11851                     //       where they were before, but in an obscured state.
11852                     mStackSupervisor.moveProfileTasksFromFreeformToFullscreenStackLocked(userId);
11853
11854                     if (mUserController.isLockScreenDisabled(currentUserId)) {
11855                         // If there is no device lock, we will show the profile's credential page.
11856                         mActivityStarter.showConfirmDeviceCredential(userId);
11857                     } else {
11858                         // Showing launcher to avoid user entering credential twice.
11859                         startHomeActivityLocked(currentUserId, "notifyLockedProfile");
11860                     }
11861                 } finally {
11862                     Binder.restoreCallingIdentity(ident);
11863                 }
11864             }
11865         }
11866     }
11867
11868     @Override
11869     public void startConfirmDeviceCredentialIntent(Intent intent) {
11870         enforceCallingPermission(MANAGE_ACTIVITY_STACKS, "startConfirmDeviceCredentialIntent");
11871         synchronized (this) {
11872             final long ident = Binder.clearCallingIdentity();
11873             try {
11874                 mActivityStarter.startConfirmCredentialIntent(intent);
11875             } finally {
11876                 Binder.restoreCallingIdentity(ident);
11877             }
11878         }
11879     }
11880
11881     @Override
11882     public void stopAppSwitches() {
11883         if (checkCallingPermission(android.Manifest.permission.STOP_APP_SWITCHES)
11884                 != PackageManager.PERMISSION_GRANTED) {
11885             throw new SecurityException("viewquires permission "
11886                     + android.Manifest.permission.STOP_APP_SWITCHES);
11887         }
11888
11889         synchronized(this) {
11890             mAppSwitchesAllowedTime = SystemClock.uptimeMillis()
11891                     + APP_SWITCH_DELAY_TIME;
11892             mDidAppSwitch = false;
11893             mHandler.removeMessages(DO_PENDING_ACTIVITY_LAUNCHES_MSG);
11894             Message msg = mHandler.obtainMessage(DO_PENDING_ACTIVITY_LAUNCHES_MSG);
11895             mHandler.sendMessageDelayed(msg, APP_SWITCH_DELAY_TIME);
11896         }
11897     }
11898
11899     public void resumeAppSwitches() {
11900         if (checkCallingPermission(android.Manifest.permission.STOP_APP_SWITCHES)
11901                 != PackageManager.PERMISSION_GRANTED) {
11902             throw new SecurityException("Requires permission "
11903                     + android.Manifest.permission.STOP_APP_SWITCHES);
11904         }
11905
11906         synchronized(this) {
11907             // Note that we don't execute any pending app switches... we will
11908             // let those wait until either the timeout, or the next start
11909             // activity request.
11910             mAppSwitchesAllowedTime = 0;
11911         }
11912     }
11913
11914     boolean checkAppSwitchAllowedLocked(int sourcePid, int sourceUid,
11915             int callingPid, int callingUid, String name) {
11916         if (mAppSwitchesAllowedTime < SystemClock.uptimeMillis()) {
11917             return true;
11918         }
11919
11920         int perm = checkComponentPermission(
11921                 android.Manifest.permission.STOP_APP_SWITCHES, sourcePid,
11922                 sourceUid, -1, true);
11923         if (perm == PackageManager.PERMISSION_GRANTED) {
11924             return true;
11925         }
11926
11927         // If the actual IPC caller is different from the logical source, then
11928         // also see if they are allowed to control app switches.
11929         if (callingUid != -1 && callingUid != sourceUid) {
11930             perm = checkComponentPermission(
11931                     android.Manifest.permission.STOP_APP_SWITCHES, callingPid,
11932                     callingUid, -1, true);
11933             if (perm == PackageManager.PERMISSION_GRANTED) {
11934                 return true;
11935             }
11936         }
11937
11938         Slog.w(TAG, name + " request from " + sourceUid + " stopped");
11939         return false;
11940     }
11941
11942     public void setDebugApp(String packageName, boolean waitForDebugger,
11943             boolean persistent) {
11944         enforceCallingPermission(android.Manifest.permission.SET_DEBUG_APP,
11945                 "setDebugApp()");
11946
11947         long ident = Binder.clearCallingIdentity();
11948         try {
11949             // Note that this is not really thread safe if there are multiple
11950             // callers into it at the same time, but that's not a situation we
11951             // care about.
11952             if (persistent) {
11953                 final ContentResolver resolver = mContext.getContentResolver();
11954                 Settings.Global.putString(
11955                     resolver, Settings.Global.DEBUG_APP,
11956                     packageName);
11957                 Settings.Global.putInt(
11958                     resolver, Settings.Global.WAIT_FOR_DEBUGGER,
11959                     waitForDebugger ? 1 : 0);
11960             }
11961
11962             synchronized (this) {
11963                 if (!persistent) {
11964                     mOrigDebugApp = mDebugApp;
11965                     mOrigWaitForDebugger = mWaitForDebugger;
11966                 }
11967                 mDebugApp = packageName;
11968                 mWaitForDebugger = waitForDebugger;
11969                 mDebugTransient = !persistent;
11970                 if (packageName != null) {
11971                     forceStopPackageLocked(packageName, -1, false, false, true, true,
11972                             false, UserHandle.USER_ALL, "set debug app");
11973                 }
11974             }
11975         } finally {
11976             Binder.restoreCallingIdentity(ident);
11977         }
11978     }
11979
11980     void setTrackAllocationApp(ApplicationInfo app, String processName) {
11981         synchronized (this) {
11982             boolean isDebuggable = "1".equals(SystemProperties.get(SYSTEM_DEBUGGABLE, "0"));
11983             if (!isDebuggable) {
11984                 if ((app.flags & ApplicationInfo.FLAG_DEBUGGABLE) == 0) {
11985                     throw new SecurityException("Process not debuggable: " + app.packageName);
11986                 }
11987             }
11988
11989             mTrackAllocationApp = processName;
11990         }
11991     }
11992
11993     void setProfileApp(ApplicationInfo app, String processName, ProfilerInfo profilerInfo) {
11994         synchronized (this) {
11995             boolean isDebuggable = "1".equals(SystemProperties.get(SYSTEM_DEBUGGABLE, "0"));
11996             if (!isDebuggable) {
11997                 if ((app.flags & ApplicationInfo.FLAG_DEBUGGABLE) == 0) {
11998                     throw new SecurityException("Process not debuggable: " + app.packageName);
11999                 }
12000             }
12001             mProfileApp = processName;
12002             mProfileFile = profilerInfo.profileFile;
12003             if (mProfileFd != null) {
12004                 try {
12005                     mProfileFd.close();
12006                 } catch (IOException e) {
12007                 }
12008                 mProfileFd = null;
12009             }
12010             mProfileFd = profilerInfo.profileFd;
12011             mSamplingInterval = profilerInfo.samplingInterval;
12012             mAutoStopProfiler = profilerInfo.autoStopProfiler;
12013             mProfileType = 0;
12014         }
12015     }
12016
12017     void setNativeDebuggingAppLocked(ApplicationInfo app, String processName) {
12018         boolean isDebuggable = "1".equals(SystemProperties.get(SYSTEM_DEBUGGABLE, "0"));
12019         if (!isDebuggable) {
12020             if ((app.flags & ApplicationInfo.FLAG_DEBUGGABLE) == 0) {
12021                 throw new SecurityException("Process not debuggable: " + app.packageName);
12022             }
12023         }
12024         mNativeDebuggingApp = processName;
12025     }
12026
12027     @Override
12028     public void setAlwaysFinish(boolean enabled) {
12029         enforceCallingPermission(android.Manifest.permission.SET_ALWAYS_FINISH,
12030                 "setAlwaysFinish()");
12031
12032         long ident = Binder.clearCallingIdentity();
12033         try {
12034             Settings.Global.putInt(
12035                     mContext.getContentResolver(),
12036                     Settings.Global.ALWAYS_FINISH_ACTIVITIES, enabled ? 1 : 0);
12037
12038             synchronized (this) {
12039                 mAlwaysFinishActivities = enabled;
12040             }
12041         } finally {
12042             Binder.restoreCallingIdentity(ident);
12043         }
12044     }
12045
12046     @Override
12047     public void setLenientBackgroundCheck(boolean enabled) {
12048         enforceCallingPermission(android.Manifest.permission.SET_PROCESS_LIMIT,
12049                 "setLenientBackgroundCheck()");
12050
12051         long ident = Binder.clearCallingIdentity();
12052         try {
12053             Settings.Global.putInt(
12054                     mContext.getContentResolver(),
12055                     Settings.Global.LENIENT_BACKGROUND_CHECK, enabled ? 1 : 0);
12056
12057             synchronized (this) {
12058                 mLenientBackgroundCheck = enabled;
12059             }
12060         } finally {
12061             Binder.restoreCallingIdentity(ident);
12062         }
12063     }
12064
12065     @Override
12066     public void setActivityController(IActivityController controller, boolean imAMonkey) {
12067         enforceCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER,
12068                 "setActivityController()");
12069         synchronized (this) {
12070             mController = controller;
12071             mControllerIsAMonkey = imAMonkey;
12072             Watchdog.getInstance().setActivityController(controller);
12073         }
12074     }
12075
12076     @Override
12077     public void setUserIsMonkey(boolean userIsMonkey) {
12078         synchronized (this) {
12079             synchronized (mPidsSelfLocked) {
12080                 final int callingPid = Binder.getCallingPid();
12081                 ProcessRecord precessRecord = mPidsSelfLocked.get(callingPid);
12082                 if (precessRecord == null) {
12083                     throw new SecurityException("Unknown process: " + callingPid);
12084                 }
12085                 if (precessRecord.instrumentationUiAutomationConnection  == null) {
12086                     throw new SecurityException("Only an instrumentation process "
12087                             + "with a UiAutomation can call setUserIsMonkey");
12088                 }
12089             }
12090             mUserIsMonkey = userIsMonkey;
12091         }
12092     }
12093
12094     @Override
12095     public boolean isUserAMonkey() {
12096         synchronized (this) {
12097             // If there is a controller also implies the user is a monkey.
12098             return (mUserIsMonkey || (mController != null && mControllerIsAMonkey));
12099         }
12100     }
12101
12102     public void requestBugReport(int bugreportType) {
12103         String service = null;
12104         switch (bugreportType) {
12105             case ActivityManager.BUGREPORT_OPTION_FULL:
12106                 service = "bugreport";
12107                 break;
12108             case ActivityManager.BUGREPORT_OPTION_INTERACTIVE:
12109                 service = "bugreportplus";
12110                 break;
12111             case ActivityManager.BUGREPORT_OPTION_REMOTE:
12112                 service = "bugreportremote";
12113                 break;
12114         }
12115         if (service == null) {
12116             throw new IllegalArgumentException("Provided bugreport type is not correct, value: "
12117                     + bugreportType);
12118         }
12119         enforceCallingPermission(android.Manifest.permission.DUMP, "requestBugReport");
12120         SystemProperties.set("ctl.start", service);
12121     }
12122
12123     public static long getInputDispatchingTimeoutLocked(ActivityRecord r) {
12124         return r != null ? getInputDispatchingTimeoutLocked(r.app) : KEY_DISPATCHING_TIMEOUT;
12125     }
12126
12127     public static long getInputDispatchingTimeoutLocked(ProcessRecord r) {
12128         if (r != null && (r.instrumentationClass != null || r.usingWrapper)) {
12129             return INSTRUMENTATION_KEY_DISPATCHING_TIMEOUT;
12130         }
12131         return KEY_DISPATCHING_TIMEOUT;
12132     }
12133
12134     @Override
12135     public long inputDispatchingTimedOut(int pid, final boolean aboveSystem, String reason) {
12136         if (checkCallingPermission(android.Manifest.permission.FILTER_EVENTS)
12137                 != PackageManager.PERMISSION_GRANTED) {
12138             throw new SecurityException("Requires permission "
12139                     + android.Manifest.permission.FILTER_EVENTS);
12140         }
12141         ProcessRecord proc;
12142         long timeout;
12143         synchronized (this) {
12144             synchronized (mPidsSelfLocked) {
12145                 proc = mPidsSelfLocked.get(pid);
12146             }
12147             timeout = getInputDispatchingTimeoutLocked(proc);
12148         }
12149
12150         if (!inputDispatchingTimedOut(proc, null, null, aboveSystem, reason)) {
12151             return -1;
12152         }
12153
12154         return timeout;
12155     }
12156
12157     /**
12158      * Handle input dispatching timeouts.
12159      * Returns whether input dispatching should be aborted or not.
12160      */
12161     public boolean inputDispatchingTimedOut(final ProcessRecord proc,
12162             final ActivityRecord activity, final ActivityRecord parent,
12163             final boolean aboveSystem, String reason) {
12164         if (checkCallingPermission(android.Manifest.permission.FILTER_EVENTS)
12165                 != PackageManager.PERMISSION_GRANTED) {
12166             throw new SecurityException("Requires permission "
12167                     + android.Manifest.permission.FILTER_EVENTS);
12168         }
12169
12170         final String annotation;
12171         if (reason == null) {
12172             annotation = "Input dispatching timed out";
12173         } else {
12174             annotation = "Input dispatching timed out (" + reason + ")";
12175         }
12176
12177         if (proc != null) {
12178             synchronized (this) {
12179                 if (proc.debugging) {
12180                     return false;
12181                 }
12182
12183                 if (mDidDexOpt) {
12184                     // Give more time since we were dexopting.
12185                     mDidDexOpt = false;
12186                     return false;
12187                 }
12188
12189                 if (proc.instrumentationClass != null) {
12190                     Bundle info = new Bundle();
12191                     info.putString("shortMsg", "keyDispatchingTimedOut");
12192                     info.putString("longMsg", annotation);
12193                     finishInstrumentationLocked(proc, Activity.RESULT_CANCELED, info);
12194                     return true;
12195                 }
12196             }
12197             mHandler.post(new Runnable() {
12198                 @Override
12199                 public void run() {
12200                     mAppErrors.appNotResponding(proc, activity, parent, aboveSystem, annotation);
12201                 }
12202             });
12203         }
12204
12205         return true;
12206     }
12207
12208     @Override
12209     public Bundle getAssistContextExtras(int requestType) {
12210         PendingAssistExtras pae = enqueueAssistContext(requestType, null, null, null,
12211                 null, null, true /* focused */, true /* newSessionId */,
12212                 UserHandle.getCallingUserId(), null, PENDING_ASSIST_EXTRAS_TIMEOUT);
12213         if (pae == null) {
12214             return null;
12215         }
12216         synchronized (pae) {
12217             while (!pae.haveResult) {
12218                 try {
12219                     pae.wait();
12220                 } catch (InterruptedException e) {
12221                 }
12222             }
12223         }
12224         synchronized (this) {
12225             buildAssistBundleLocked(pae, pae.result);
12226             mPendingAssistExtras.remove(pae);
12227             mUiHandler.removeCallbacks(pae);
12228         }
12229         return pae.extras;
12230     }
12231
12232     @Override
12233     public boolean isAssistDataAllowedOnCurrentActivity() {
12234         int userId;
12235         synchronized (this) {
12236             userId = mUserController.getCurrentUserIdLocked();
12237             ActivityRecord activity = getFocusedStack().topActivity();
12238             if (activity == null) {
12239                 return false;
12240             }
12241             userId = activity.userId;
12242         }
12243         DevicePolicyManager dpm = (DevicePolicyManager) mContext.getSystemService(
12244                 Context.DEVICE_POLICY_SERVICE);
12245         return (dpm == null) || (!dpm.getScreenCaptureDisabled(null, userId));
12246     }
12247
12248     @Override
12249     public boolean showAssistFromActivity(IBinder token, Bundle args) {
12250         long ident = Binder.clearCallingIdentity();
12251         try {
12252             synchronized (this) {
12253                 ActivityRecord caller = ActivityRecord.forTokenLocked(token);
12254                 ActivityRecord top = getFocusedStack().topActivity();
12255                 if (top != caller) {
12256                     Slog.w(TAG, "showAssistFromActivity failed: caller " + caller
12257                             + " is not current top " + top);
12258                     return false;
12259                 }
12260                 if (!top.nowVisible) {
12261                     Slog.w(TAG, "showAssistFromActivity failed: caller " + caller
12262                             + " is not visible");
12263                     return false;
12264                 }
12265             }
12266             AssistUtils utils = new AssistUtils(mContext);
12267             return utils.showSessionForActiveService(args,
12268                     VoiceInteractionSession.SHOW_SOURCE_APPLICATION, null, token);
12269         } finally {
12270             Binder.restoreCallingIdentity(ident);
12271         }
12272     }
12273
12274     @Override
12275     public boolean requestAssistContextExtras(int requestType, IResultReceiver receiver,
12276             Bundle receiverExtras,
12277             IBinder activityToken, boolean focused, boolean newSessionId) {
12278         return enqueueAssistContext(requestType, null, null, receiver, receiverExtras,
12279                 activityToken, focused, newSessionId,
12280                 UserHandle.getCallingUserId(), null, PENDING_ASSIST_EXTRAS_LONG_TIMEOUT)
12281                 != null;
12282     }
12283
12284     private PendingAssistExtras enqueueAssistContext(int requestType, Intent intent, String hint,
12285             IResultReceiver receiver, Bundle receiverExtras, IBinder activityToken,
12286             boolean focused, boolean newSessionId, int userHandle, Bundle args, long timeout) {
12287         enforceCallingPermission(android.Manifest.permission.GET_TOP_ACTIVITY_INFO,
12288                 "enqueueAssistContext()");
12289         synchronized (this) {
12290             ActivityRecord activity = getFocusedStack().topActivity();
12291             if (activity == null) {
12292                 Slog.w(TAG, "getAssistContextExtras failed: no top activity");
12293                 return null;
12294             }
12295             if (activity.app == null || activity.app.thread == null) {
12296                 Slog.w(TAG, "getAssistContextExtras failed: no process for " + activity);
12297                 return null;
12298             }
12299             if (focused) {
12300                 if (activityToken != null) {
12301                     ActivityRecord caller = ActivityRecord.forTokenLocked(activityToken);
12302                     if (activity != caller) {
12303                         Slog.w(TAG, "enqueueAssistContext failed: caller " + caller
12304                                 + " is not current top " + activity);
12305                         return null;
12306                     }
12307                 }
12308             } else {
12309                 activity = ActivityRecord.forTokenLocked(activityToken);
12310                 if (activity == null) {
12311                     Slog.w(TAG, "enqueueAssistContext failed: activity for token=" + activityToken
12312                             + " couldn't be found");
12313                     return null;
12314                 }
12315             }
12316
12317             PendingAssistExtras pae;
12318             Bundle extras = new Bundle();
12319             if (args != null) {
12320                 extras.putAll(args);
12321             }
12322             extras.putString(Intent.EXTRA_ASSIST_PACKAGE, activity.packageName);
12323             extras.putInt(Intent.EXTRA_ASSIST_UID, activity.app.uid);
12324             pae = new PendingAssistExtras(activity, extras, intent, hint, receiver, receiverExtras,
12325                     userHandle);
12326             // Increment the sessionId if necessary
12327             if (newSessionId) {
12328                 mViSessionId++;
12329             }
12330             try {
12331                 activity.app.thread.requestAssistContextExtras(activity.appToken, pae,
12332                         requestType, mViSessionId);
12333                 mPendingAssistExtras.add(pae);
12334                 mUiHandler.postDelayed(pae, timeout);
12335             } catch (RemoteException e) {
12336                 Slog.w(TAG, "getAssistContextExtras failed: crash calling " + activity);
12337                 return null;
12338             }
12339             return pae;
12340         }
12341     }
12342
12343     void pendingAssistExtrasTimedOut(PendingAssistExtras pae) {
12344         IResultReceiver receiver;
12345         synchronized (this) {
12346             mPendingAssistExtras.remove(pae);
12347             receiver = pae.receiver;
12348         }
12349         if (receiver != null) {
12350             // Caller wants result sent back to them.
12351             Bundle sendBundle = new Bundle();
12352             // At least return the receiver extras
12353             sendBundle.putBundle(VoiceInteractionSession.KEY_RECEIVER_EXTRAS,
12354                     pae.receiverExtras);
12355             try {
12356                 pae.receiver.send(0, sendBundle);
12357             } catch (RemoteException e) {
12358             }
12359         }
12360     }
12361
12362     private void buildAssistBundleLocked(PendingAssistExtras pae, Bundle result) {
12363         if (result != null) {
12364             pae.extras.putBundle(Intent.EXTRA_ASSIST_CONTEXT, result);
12365         }
12366         if (pae.hint != null) {
12367             pae.extras.putBoolean(pae.hint, true);
12368         }
12369     }
12370
12371     public void reportAssistContextExtras(IBinder token, Bundle extras, AssistStructure structure,
12372             AssistContent content, Uri referrer) {
12373         PendingAssistExtras pae = (PendingAssistExtras)token;
12374         synchronized (pae) {
12375             pae.result = extras;
12376             pae.structure = structure;
12377             pae.content = content;
12378             if (referrer != null) {
12379                 pae.extras.putParcelable(Intent.EXTRA_REFERRER, referrer);
12380             }
12381             pae.haveResult = true;
12382             pae.notifyAll();
12383             if (pae.intent == null && pae.receiver == null) {
12384                 // Caller is just waiting for the result.
12385                 return;
12386             }
12387         }
12388
12389         // We are now ready to launch the assist activity.
12390         IResultReceiver sendReceiver = null;
12391         Bundle sendBundle = null;
12392         synchronized (this) {
12393             buildAssistBundleLocked(pae, extras);
12394             boolean exists = mPendingAssistExtras.remove(pae);
12395             mUiHandler.removeCallbacks(pae);
12396             if (!exists) {
12397                 // Timed out.
12398                 return;
12399             }
12400             if ((sendReceiver=pae.receiver) != null) {
12401                 // Caller wants result sent back to them.
12402                 sendBundle = new Bundle();
12403                 sendBundle.putBundle(VoiceInteractionSession.KEY_DATA, pae.extras);
12404                 sendBundle.putParcelable(VoiceInteractionSession.KEY_STRUCTURE, pae.structure);
12405                 sendBundle.putParcelable(VoiceInteractionSession.KEY_CONTENT, pae.content);
12406                 sendBundle.putBundle(VoiceInteractionSession.KEY_RECEIVER_EXTRAS,
12407                         pae.receiverExtras);
12408             }
12409         }
12410         if (sendReceiver != null) {
12411             try {
12412                 sendReceiver.send(0, sendBundle);
12413             } catch (RemoteException e) {
12414             }
12415             return;
12416         }
12417
12418         long ident = Binder.clearCallingIdentity();
12419         try {
12420             pae.intent.replaceExtras(pae.extras);
12421             pae.intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK
12422                     | Intent.FLAG_ACTIVITY_SINGLE_TOP
12423                     | Intent.FLAG_ACTIVITY_CLEAR_TOP);
12424             closeSystemDialogs("assist");
12425             try {
12426                 mContext.startActivityAsUser(pae.intent, new UserHandle(pae.userHandle));
12427             } catch (ActivityNotFoundException e) {
12428                 Slog.w(TAG, "No activity to handle assist action.", e);
12429             }
12430         } finally {
12431             Binder.restoreCallingIdentity(ident);
12432         }
12433     }
12434
12435     public boolean launchAssistIntent(Intent intent, int requestType, String hint, int userHandle,
12436             Bundle args) {
12437         return enqueueAssistContext(requestType, intent, hint, null, null, null,
12438                 true /* focused */, true /* newSessionId */,
12439                 userHandle, args, PENDING_ASSIST_EXTRAS_TIMEOUT) != null;
12440     }
12441
12442     public void registerProcessObserver(IProcessObserver observer) {
12443         enforceCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER,
12444                 "registerProcessObserver()");
12445         synchronized (this) {
12446             mProcessObservers.register(observer);
12447         }
12448     }
12449
12450     @Override
12451     public void unregisterProcessObserver(IProcessObserver observer) {
12452         synchronized (this) {
12453             mProcessObservers.unregister(observer);
12454         }
12455     }
12456
12457     @Override
12458     public void registerUidObserver(IUidObserver observer, int which) {
12459         enforceCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER,
12460                 "registerUidObserver()");
12461         synchronized (this) {
12462             mUidObservers.register(observer, which);
12463         }
12464     }
12465
12466     @Override
12467     public void unregisterUidObserver(IUidObserver observer) {
12468         synchronized (this) {
12469             mUidObservers.unregister(observer);
12470         }
12471     }
12472
12473     @Override
12474     public boolean convertFromTranslucent(IBinder token) {
12475         final long origId = Binder.clearCallingIdentity();
12476         try {
12477             synchronized (this) {
12478                 final ActivityRecord r = ActivityRecord.isInStackLocked(token);
12479                 if (r == null) {
12480                     return false;
12481                 }
12482                 final boolean translucentChanged = r.changeWindowTranslucency(true);
12483                 if (translucentChanged) {
12484                     r.task.stack.releaseBackgroundResources(r);
12485                     mStackSupervisor.ensureActivitiesVisibleLocked(null, 0, !PRESERVE_WINDOWS);
12486                 }
12487                 mWindowManager.setAppFullscreen(token, true);
12488                 return translucentChanged;
12489             }
12490         } finally {
12491             Binder.restoreCallingIdentity(origId);
12492         }
12493     }
12494
12495     @Override
12496     public boolean convertToTranslucent(IBinder token, ActivityOptions options) {
12497         final long origId = Binder.clearCallingIdentity();
12498         try {
12499             synchronized (this) {
12500                 final ActivityRecord r = ActivityRecord.isInStackLocked(token);
12501                 if (r == null) {
12502                     return false;
12503                 }
12504                 int index = r.task.mActivities.lastIndexOf(r);
12505                 if (index > 0) {
12506                     ActivityRecord under = r.task.mActivities.get(index - 1);
12507                     under.returningOptions = options;
12508                 }
12509                 final boolean translucentChanged = r.changeWindowTranslucency(false);
12510                 if (translucentChanged) {
12511                     r.task.stack.convertActivityToTranslucent(r);
12512                 }
12513                 mStackSupervisor.ensureActivitiesVisibleLocked(null, 0, !PRESERVE_WINDOWS);
12514                 mWindowManager.setAppFullscreen(token, false);
12515                 return translucentChanged;
12516             }
12517         } finally {
12518             Binder.restoreCallingIdentity(origId);
12519         }
12520     }
12521
12522     @Override
12523     public boolean requestVisibleBehind(IBinder token, boolean visible) {
12524         final long origId = Binder.clearCallingIdentity();
12525         try {
12526             synchronized (this) {
12527                 final ActivityRecord r = ActivityRecord.isInStackLocked(token);
12528                 if (r != null) {
12529                     return mStackSupervisor.requestVisibleBehindLocked(r, visible);
12530                 }
12531             }
12532             return false;
12533         } finally {
12534             Binder.restoreCallingIdentity(origId);
12535         }
12536     }
12537
12538     @Override
12539     public boolean isBackgroundVisibleBehind(IBinder token) {
12540         final long origId = Binder.clearCallingIdentity();
12541         try {
12542             synchronized (this) {
12543                 final ActivityStack stack = ActivityRecord.getStackLocked(token);
12544                 final boolean visible = stack == null ? false : stack.hasVisibleBehindActivity();
12545                 if (DEBUG_VISIBLE_BEHIND) Slog.d(TAG_VISIBLE_BEHIND,
12546                         "isBackgroundVisibleBehind: stack=" + stack + " visible=" + visible);
12547                 return visible;
12548             }
12549         } finally {
12550             Binder.restoreCallingIdentity(origId);
12551         }
12552     }
12553
12554     @Override
12555     public ActivityOptions getActivityOptions(IBinder token) {
12556         final long origId = Binder.clearCallingIdentity();
12557         try {
12558             synchronized (this) {
12559                 final ActivityRecord r = ActivityRecord.isInStackLocked(token);
12560                 if (r != null) {
12561                     final ActivityOptions activityOptions = r.pendingOptions;
12562                     r.pendingOptions = null;
12563                     return activityOptions;
12564                 }
12565                 return null;
12566             }
12567         } finally {
12568             Binder.restoreCallingIdentity(origId);
12569         }
12570     }
12571
12572     @Override
12573     public void setImmersive(IBinder token, boolean immersive) {
12574         synchronized(this) {
12575             final ActivityRecord r = ActivityRecord.isInStackLocked(token);
12576             if (r == null) {
12577                 throw new IllegalArgumentException();
12578             }
12579             r.immersive = immersive;
12580
12581             // update associated state if we're frontmost
12582             if (r == mFocusedActivity) {
12583                 if (DEBUG_IMMERSIVE) Slog.d(TAG_IMMERSIVE, "Frontmost changed immersion: "+ r);
12584                 applyUpdateLockStateLocked(r);
12585             }
12586         }
12587     }
12588
12589     @Override
12590     public boolean isImmersive(IBinder token) {
12591         synchronized (this) {
12592             ActivityRecord r = ActivityRecord.isInStackLocked(token);
12593             if (r == null) {
12594                 throw new IllegalArgumentException();
12595             }
12596             return r.immersive;
12597         }
12598     }
12599
12600     @Override
12601     public int setVrMode(IBinder token, boolean enabled, ComponentName packageName) {
12602         if (!mContext.getPackageManager().hasSystemFeature(PackageManager.FEATURE_VR_MODE)) {
12603             throw new UnsupportedOperationException("VR mode not supported on this device!");
12604         }
12605
12606         final VrManagerInternal vrService = LocalServices.getService(VrManagerInternal.class);
12607
12608         ActivityRecord r;
12609         synchronized (this) {
12610             r = ActivityRecord.isInStackLocked(token);
12611         }
12612
12613         if (r == null) {
12614             throw new IllegalArgumentException();
12615         }
12616
12617         int err;
12618         if ((err = vrService.hasVrPackage(packageName, r.userId)) !=
12619                 VrManagerInternal.NO_ERROR) {
12620             return err;
12621         }
12622
12623         synchronized(this) {
12624             r.requestedVrComponent = (enabled) ? packageName : null;
12625
12626             // Update associated state if this activity is currently focused
12627             if (r == mFocusedActivity) {
12628                 applyUpdateVrModeLocked(r);
12629             }
12630             return 0;
12631         }
12632     }
12633
12634     @Override
12635     public boolean isVrModePackageEnabled(ComponentName packageName) {
12636         if (!mContext.getPackageManager().hasSystemFeature(PackageManager.FEATURE_VR_MODE)) {
12637             throw new UnsupportedOperationException("VR mode not supported on this device!");
12638         }
12639
12640         final VrManagerInternal vrService = LocalServices.getService(VrManagerInternal.class);
12641
12642         return vrService.hasVrPackage(packageName, UserHandle.getCallingUserId()) ==
12643                 VrManagerInternal.NO_ERROR;
12644     }
12645
12646     public boolean isTopActivityImmersive() {
12647         enforceNotIsolatedCaller("startActivity");
12648         synchronized (this) {
12649             ActivityRecord r = getFocusedStack().topRunningActivityLocked();
12650             return (r != null) ? r.immersive : false;
12651         }
12652     }
12653
12654     @Override
12655     public boolean isTopOfTask(IBinder token) {
12656         synchronized (this) {
12657             ActivityRecord r = ActivityRecord.isInStackLocked(token);
12658             if (r == null) {
12659                 throw new IllegalArgumentException();
12660             }
12661             return r.task.getTopActivity() == r;
12662         }
12663     }
12664
12665     public final void enterSafeMode() {
12666         synchronized(this) {
12667             // It only makes sense to do this before the system is ready
12668             // and started launching other packages.
12669             if (!mSystemReady) {
12670                 try {
12671                     AppGlobals.getPackageManager().enterSafeMode();
12672                 } catch (RemoteException e) {
12673                 }
12674             }
12675
12676             mSafeMode = true;
12677         }
12678     }
12679
12680     public final void showSafeModeOverlay() {
12681         View v = LayoutInflater.from(mContext).inflate(
12682                 com.android.internal.R.layout.safe_mode, null);
12683         WindowManager.LayoutParams lp = new WindowManager.LayoutParams();
12684         lp.type = WindowManager.LayoutParams.TYPE_SECURE_SYSTEM_OVERLAY;
12685         lp.width = WindowManager.LayoutParams.WRAP_CONTENT;
12686         lp.height = WindowManager.LayoutParams.WRAP_CONTENT;
12687         lp.gravity = Gravity.BOTTOM | Gravity.START;
12688         lp.format = v.getBackground().getOpacity();
12689         lp.flags = WindowManager.LayoutParams.FLAG_NOT_FOCUSABLE
12690                 | WindowManager.LayoutParams.FLAG_NOT_TOUCHABLE;
12691         lp.privateFlags |= WindowManager.LayoutParams.PRIVATE_FLAG_SHOW_FOR_ALL_USERS;
12692         ((WindowManager)mContext.getSystemService(
12693                 Context.WINDOW_SERVICE)).addView(v, lp);
12694     }
12695
12696     public void noteWakeupAlarm(IIntentSender sender, int sourceUid, String sourcePkg, String tag) {
12697         if (sender != null && !(sender instanceof PendingIntentRecord)) {
12698             return;
12699         }
12700         final PendingIntentRecord rec = (PendingIntentRecord)sender;
12701         final BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
12702         synchronized (stats) {
12703             if (mBatteryStatsService.isOnBattery()) {
12704                 mBatteryStatsService.enforceCallingPermission();
12705                 int MY_UID = Binder.getCallingUid();
12706                 final int uid;
12707                 if (sender == null) {
12708                     uid = sourceUid;
12709                 } else {
12710                     uid = rec.uid == MY_UID ? Process.SYSTEM_UID : rec.uid;
12711                 }
12712                 BatteryStatsImpl.Uid.Pkg pkg =
12713                     stats.getPackageStatsLocked(sourceUid >= 0 ? sourceUid : uid,
12714                             sourcePkg != null ? sourcePkg : rec.key.packageName);
12715                 pkg.noteWakeupAlarmLocked(tag);
12716             }
12717         }
12718     }
12719
12720     public void noteAlarmStart(IIntentSender sender, int sourceUid, String tag) {
12721         if (sender != null && !(sender instanceof PendingIntentRecord)) {
12722             return;
12723         }
12724         final PendingIntentRecord rec = (PendingIntentRecord)sender;
12725         final BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
12726         synchronized (stats) {
12727             mBatteryStatsService.enforceCallingPermission();
12728             int MY_UID = Binder.getCallingUid();
12729             final int uid;
12730             if (sender == null) {
12731                 uid = sourceUid;
12732             } else {
12733                 uid = rec.uid == MY_UID ? Process.SYSTEM_UID : rec.uid;
12734             }
12735             mBatteryStatsService.noteAlarmStart(tag, sourceUid >= 0 ? sourceUid : uid);
12736         }
12737     }
12738
12739     public void noteAlarmFinish(IIntentSender sender, int sourceUid, String tag) {
12740         if (sender != null && !(sender instanceof PendingIntentRecord)) {
12741             return;
12742         }
12743         final PendingIntentRecord rec = (PendingIntentRecord)sender;
12744         final BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
12745         synchronized (stats) {
12746             mBatteryStatsService.enforceCallingPermission();
12747             int MY_UID = Binder.getCallingUid();
12748             final int uid;
12749             if (sender == null) {
12750                 uid = sourceUid;
12751             } else {
12752                 uid = rec.uid == MY_UID ? Process.SYSTEM_UID : rec.uid;
12753             }
12754             mBatteryStatsService.noteAlarmFinish(tag, sourceUid >= 0 ? sourceUid : uid);
12755         }
12756     }
12757
12758     public boolean killPids(int[] pids, String pReason, boolean secure) {
12759         if (Binder.getCallingUid() != Process.SYSTEM_UID) {
12760             throw new SecurityException("killPids only available to the system");
12761         }
12762         String reason = (pReason == null) ? "Unknown" : pReason;
12763         // XXX Note: don't acquire main activity lock here, because the window
12764         // manager calls in with its locks held.
12765
12766         boolean killed = false;
12767         synchronized (mPidsSelfLocked) {
12768             int worstType = 0;
12769             for (int i=0; i<pids.length; i++) {
12770                 ProcessRecord proc = mPidsSelfLocked.get(pids[i]);
12771                 if (proc != null) {
12772                     int type = proc.setAdj;
12773                     if (type > worstType) {
12774                         worstType = type;
12775                     }
12776                 }
12777             }
12778
12779             // If the worst oom_adj is somewhere in the cached proc LRU range,
12780             // then constrain it so we will kill all cached procs.
12781             if (worstType < ProcessList.CACHED_APP_MAX_ADJ
12782                     && worstType > ProcessList.CACHED_APP_MIN_ADJ) {
12783                 worstType = ProcessList.CACHED_APP_MIN_ADJ;
12784             }
12785
12786             // If this is not a secure call, don't let it kill processes that
12787             // are important.
12788             if (!secure && worstType < ProcessList.SERVICE_ADJ) {
12789                 worstType = ProcessList.SERVICE_ADJ;
12790             }
12791
12792             Slog.w(TAG, "Killing processes " + reason + " at adjustment " + worstType);
12793             for (int i=0; i<pids.length; i++) {
12794                 ProcessRecord proc = mPidsSelfLocked.get(pids[i]);
12795                 if (proc == null) {
12796                     continue;
12797                 }
12798                 int adj = proc.setAdj;
12799                 if (adj >= worstType && !proc.killedByAm) {
12800                     proc.kill(reason, true);
12801                     killed = true;
12802                 }
12803             }
12804         }
12805         return killed;
12806     }
12807
12808     @Override
12809     public void killUid(int appId, int userId, String reason) {
12810         enforceCallingPermission(Manifest.permission.KILL_UID, "killUid");
12811         synchronized (this) {
12812             final long identity = Binder.clearCallingIdentity();
12813             try {
12814                 killPackageProcessesLocked(null, appId, userId,
12815                         ProcessList.PERSISTENT_PROC_ADJ, false, true, true, true,
12816                         reason != null ? reason : "kill uid");
12817             } finally {
12818                 Binder.restoreCallingIdentity(identity);
12819             }
12820         }
12821     }
12822
12823     @Override
12824     public boolean killProcessesBelowForeground(String reason) {
12825         if (Binder.getCallingUid() != Process.SYSTEM_UID) {
12826             throw new SecurityException("killProcessesBelowForeground() only available to system");
12827         }
12828
12829         return killProcessesBelowAdj(ProcessList.FOREGROUND_APP_ADJ, reason);
12830     }
12831
12832     private boolean killProcessesBelowAdj(int belowAdj, String reason) {
12833         if (Binder.getCallingUid() != Process.SYSTEM_UID) {
12834             throw new SecurityException("killProcessesBelowAdj() only available to system");
12835         }
12836
12837         boolean killed = false;
12838         synchronized (mPidsSelfLocked) {
12839             final int size = mPidsSelfLocked.size();
12840             for (int i = 0; i < size; i++) {
12841                 final int pid = mPidsSelfLocked.keyAt(i);
12842                 final ProcessRecord proc = mPidsSelfLocked.valueAt(i);
12843                 if (proc == null) continue;
12844
12845                 final int adj = proc.setAdj;
12846                 if (adj > belowAdj && !proc.killedByAm) {
12847                     proc.kill(reason, true);
12848                     killed = true;
12849                 }
12850             }
12851         }
12852         return killed;
12853     }
12854
12855     @Override
12856     public void hang(final IBinder who, boolean allowRestart) {
12857         if (checkCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER)
12858                 != PackageManager.PERMISSION_GRANTED) {
12859             throw new SecurityException("Requires permission "
12860                     + android.Manifest.permission.SET_ACTIVITY_WATCHER);
12861         }
12862
12863         final IBinder.DeathRecipient death = new DeathRecipient() {
12864             @Override
12865             public void binderDied() {
12866                 synchronized (this) {
12867                     notifyAll();
12868                 }
12869             }
12870         };
12871
12872         try {
12873             who.linkToDeath(death, 0);
12874         } catch (RemoteException e) {
12875             Slog.w(TAG, "hang: given caller IBinder is already dead.");
12876             return;
12877         }
12878
12879         synchronized (this) {
12880             Watchdog.getInstance().setAllowRestart(allowRestart);
12881             Slog.i(TAG, "Hanging system process at request of pid " + Binder.getCallingPid());
12882             synchronized (death) {
12883                 while (who.isBinderAlive()) {
12884                     try {
12885                         death.wait();
12886                     } catch (InterruptedException e) {
12887                     }
12888                 }
12889             }
12890             Watchdog.getInstance().setAllowRestart(true);
12891         }
12892     }
12893
12894     @Override
12895     public void restart() {
12896         if (checkCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER)
12897                 != PackageManager.PERMISSION_GRANTED) {
12898             throw new SecurityException("Requires permission "
12899                     + android.Manifest.permission.SET_ACTIVITY_WATCHER);
12900         }
12901
12902         Log.i(TAG, "Sending shutdown broadcast...");
12903
12904         BroadcastReceiver br = new BroadcastReceiver() {
12905             @Override public void onReceive(Context context, Intent intent) {
12906                 // Now the broadcast is done, finish up the low-level shutdown.
12907                 Log.i(TAG, "Shutting down activity manager...");
12908                 shutdown(10000);
12909                 Log.i(TAG, "Shutdown complete, restarting!");
12910                 Process.killProcess(Process.myPid());
12911                 System.exit(10);
12912             }
12913         };
12914
12915         // First send the high-level shut down broadcast.
12916         Intent intent = new Intent(Intent.ACTION_SHUTDOWN);
12917         intent.addFlags(Intent.FLAG_RECEIVER_FOREGROUND);
12918         intent.putExtra(Intent.EXTRA_SHUTDOWN_USERSPACE_ONLY, true);
12919         /* For now we are not doing a clean shutdown, because things seem to get unhappy.
12920         mContext.sendOrderedBroadcastAsUser(intent,
12921                 UserHandle.ALL, null, br, mHandler, 0, null, null);
12922         */
12923         br.onReceive(mContext, intent);
12924     }
12925
12926     private long getLowRamTimeSinceIdle(long now) {
12927         return mLowRamTimeSinceLastIdle + (mLowRamStartTime > 0 ? (now-mLowRamStartTime) : 0);
12928     }
12929
12930     @Override
12931     public void performIdleMaintenance() {
12932         if (checkCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER)
12933                 != PackageManager.PERMISSION_GRANTED) {
12934             throw new SecurityException("Requires permission "
12935                     + android.Manifest.permission.SET_ACTIVITY_WATCHER);
12936         }
12937
12938         synchronized (this) {
12939             final long now = SystemClock.uptimeMillis();
12940             final long timeSinceLastIdle = now - mLastIdleTime;
12941             final long lowRamSinceLastIdle = getLowRamTimeSinceIdle(now);
12942             mLastIdleTime = now;
12943             mLowRamTimeSinceLastIdle = 0;
12944             if (mLowRamStartTime != 0) {
12945                 mLowRamStartTime = now;
12946             }
12947
12948             StringBuilder sb = new StringBuilder(128);
12949             sb.append("Idle maintenance over ");
12950             TimeUtils.formatDuration(timeSinceLastIdle, sb);
12951             sb.append(" low RAM for ");
12952             TimeUtils.formatDuration(lowRamSinceLastIdle, sb);
12953             Slog.i(TAG, sb.toString());
12954
12955             // If at least 1/3 of our time since the last idle period has been spent
12956             // with RAM low, then we want to kill processes.
12957             boolean doKilling = lowRamSinceLastIdle > (timeSinceLastIdle/3);
12958
12959             for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) {
12960                 ProcessRecord proc = mLruProcesses.get(i);
12961                 if (proc.notCachedSinceIdle) {
12962                     if (proc.setProcState != ActivityManager.PROCESS_STATE_TOP_SLEEPING
12963                             && proc.setProcState >= ActivityManager.PROCESS_STATE_FOREGROUND_SERVICE
12964                             && proc.setProcState <= ActivityManager.PROCESS_STATE_SERVICE) {
12965                         if (doKilling && proc.initialIdlePss != 0
12966                                 && proc.lastPss > ((proc.initialIdlePss*3)/2)) {
12967                             sb = new StringBuilder(128);
12968                             sb.append("Kill");
12969                             sb.append(proc.processName);
12970                             sb.append(" in idle maint: pss=");
12971                             sb.append(proc.lastPss);
12972                             sb.append(", swapPss=");
12973                             sb.append(proc.lastSwapPss);
12974                             sb.append(", initialPss=");
12975                             sb.append(proc.initialIdlePss);
12976                             sb.append(", period=");
12977                             TimeUtils.formatDuration(timeSinceLastIdle, sb);
12978                             sb.append(", lowRamPeriod=");
12979                             TimeUtils.formatDuration(lowRamSinceLastIdle, sb);
12980                             Slog.wtfQuiet(TAG, sb.toString());
12981                             proc.kill("idle maint (pss " + proc.lastPss
12982                                     + " from " + proc.initialIdlePss + ")", true);
12983                         }
12984                     }
12985                 } else if (proc.setProcState < ActivityManager.PROCESS_STATE_HOME
12986                         && proc.setProcState > ActivityManager.PROCESS_STATE_NONEXISTENT) {
12987                     proc.notCachedSinceIdle = true;
12988                     proc.initialIdlePss = 0;
12989                     proc.nextPssTime = ProcessList.computeNextPssTime(proc.setProcState, true,
12990                             mTestPssMode, isSleepingLocked(), now);
12991                 }
12992             }
12993
12994             mHandler.removeMessages(REQUEST_ALL_PSS_MSG);
12995             mHandler.sendEmptyMessageDelayed(REQUEST_ALL_PSS_MSG, 2*60*1000);
12996         }
12997     }
12998
12999     @Override
13000     public void sendIdleJobTrigger() {
13001         if (checkCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER)
13002                 != PackageManager.PERMISSION_GRANTED) {
13003             throw new SecurityException("Requires permission "
13004                     + android.Manifest.permission.SET_ACTIVITY_WATCHER);
13005         }
13006
13007         final long ident = Binder.clearCallingIdentity();
13008         try {
13009             Intent intent = new Intent(ACTION_TRIGGER_IDLE)
13010                     .setPackage("android")
13011                     .addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY);
13012             broadcastIntent(null, intent, null, null, 0, null, null, null,
13013                     android.app.AppOpsManager.OP_NONE, null, true, false, UserHandle.USER_ALL);
13014         } finally {
13015             Binder.restoreCallingIdentity(ident);
13016         }
13017     }
13018
13019     private void retrieveSettings() {
13020         final ContentResolver resolver = mContext.getContentResolver();
13021         final boolean freeformWindowManagement =
13022                 mContext.getPackageManager().hasSystemFeature(FEATURE_FREEFORM_WINDOW_MANAGEMENT)
13023                         || Settings.Global.getInt(
13024                                 resolver, DEVELOPMENT_ENABLE_FREEFORM_WINDOWS_SUPPORT, 0) != 0;
13025         final boolean supportsPictureInPicture =
13026                 mContext.getPackageManager().hasSystemFeature(FEATURE_PICTURE_IN_PICTURE);
13027
13028         final boolean supportsMultiWindow = ActivityManager.supportsMultiWindow();
13029         final String debugApp = Settings.Global.getString(resolver, DEBUG_APP);
13030         final boolean waitForDebugger = Settings.Global.getInt(resolver, WAIT_FOR_DEBUGGER, 0) != 0;
13031         final boolean alwaysFinishActivities =
13032                 Settings.Global.getInt(resolver, ALWAYS_FINISH_ACTIVITIES, 0) != 0;
13033         final boolean lenientBackgroundCheck =
13034                 Settings.Global.getInt(resolver, LENIENT_BACKGROUND_CHECK, 0) != 0;
13035         final boolean forceRtl = Settings.Global.getInt(resolver, DEVELOPMENT_FORCE_RTL, 0) != 0;
13036         final boolean forceResizable = Settings.Global.getInt(
13037                 resolver, DEVELOPMENT_FORCE_RESIZABLE_ACTIVITIES, 0) != 0;
13038         final boolean supportsLeanbackOnly =
13039                 mContext.getPackageManager().hasSystemFeature(FEATURE_LEANBACK_ONLY);
13040
13041         // Transfer any global setting for forcing RTL layout, into a System Property
13042         SystemProperties.set(DEVELOPMENT_FORCE_RTL, forceRtl ? "1":"0");
13043
13044         final Configuration configuration = new Configuration();
13045         Settings.System.getConfiguration(resolver, configuration);
13046         if (forceRtl) {
13047             // This will take care of setting the correct layout direction flags
13048             configuration.setLayoutDirection(configuration.locale);
13049         }
13050
13051         synchronized (this) {
13052             mDebugApp = mOrigDebugApp = debugApp;
13053             mWaitForDebugger = mOrigWaitForDebugger = waitForDebugger;
13054             mAlwaysFinishActivities = alwaysFinishActivities;
13055             mLenientBackgroundCheck = lenientBackgroundCheck;
13056             mSupportsLeanbackOnly = supportsLeanbackOnly;
13057             mForceResizableActivities = forceResizable;
13058             mWindowManager.setForceResizableTasks(mForceResizableActivities);
13059             if (supportsMultiWindow || forceResizable) {
13060                 mSupportsMultiWindow = true;
13061                 mSupportsFreeformWindowManagement = freeformWindowManagement || forceResizable;
13062                 mSupportsPictureInPicture = supportsPictureInPicture || forceResizable;
13063             } else {
13064                 mSupportsMultiWindow = false;
13065                 mSupportsFreeformWindowManagement = false;
13066                 mSupportsPictureInPicture = false;
13067             }
13068             // This happens before any activities are started, so we can
13069             // change mConfiguration in-place.
13070             updateConfigurationLocked(configuration, null, true);
13071             if (DEBUG_CONFIGURATION) Slog.v(TAG_CONFIGURATION,
13072                     "Initial config: " + mConfiguration);
13073
13074             // Load resources only after the current configuration has been set.
13075             final Resources res = mContext.getResources();
13076             mHasRecents = res.getBoolean(com.android.internal.R.bool.config_hasRecents);
13077             mThumbnailWidth = res.getDimensionPixelSize(
13078                     com.android.internal.R.dimen.thumbnail_width);
13079             mThumbnailHeight = res.getDimensionPixelSize(
13080                     com.android.internal.R.dimen.thumbnail_height);
13081             mDefaultPinnedStackBounds = Rect.unflattenFromString(res.getString(
13082                     com.android.internal.R.string.config_defaultPictureInPictureBounds));
13083             mAppErrors.loadAppsNotReportingCrashesFromConfigLocked(res.getString(
13084                     com.android.internal.R.string.config_appsNotReportingCrashes));
13085             if ((mConfiguration.uiMode & UI_MODE_TYPE_TELEVISION) == UI_MODE_TYPE_TELEVISION) {
13086                 mFullscreenThumbnailScale = (float) res
13087                     .getInteger(com.android.internal.R.integer.thumbnail_width_tv) /
13088                     (float) mConfiguration.screenWidthDp;
13089             } else {
13090                 mFullscreenThumbnailScale = res.getFraction(
13091                     com.android.internal.R.fraction.thumbnail_fullscreen_scale, 1, 1);
13092             }
13093         }
13094     }
13095
13096     public boolean testIsSystemReady() {
13097         // no need to synchronize(this) just to read & return the value
13098         return mSystemReady;
13099     }
13100
13101     public void systemReady(final Runnable goingCallback) {
13102         synchronized(this) {
13103             if (mSystemReady) {
13104                 // If we're done calling all the receivers, run the next "boot phase" passed in
13105                 // by the SystemServer
13106                 if (goingCallback != null) {
13107                     goingCallback.run();
13108                 }
13109                 return;
13110             }
13111
13112             mLocalDeviceIdleController
13113                     = LocalServices.getService(DeviceIdleController.LocalService.class);
13114
13115             // Make sure we have the current profile info, since it is needed for security checks.
13116             mUserController.onSystemReady();
13117             mRecentTasks.onSystemReadyLocked();
13118             mAppOpsService.systemReady();
13119             mSystemReady = true;
13120         }
13121
13122         ArrayList<ProcessRecord> procsToKill = null;
13123         synchronized(mPidsSelfLocked) {
13124             for (int i=mPidsSelfLocked.size()-1; i>=0; i--) {
13125                 ProcessRecord proc = mPidsSelfLocked.valueAt(i);
13126                 if (!isAllowedWhileBooting(proc.info)){
13127                     if (procsToKill == null) {
13128                         procsToKill = new ArrayList<ProcessRecord>();
13129                     }
13130                     procsToKill.add(proc);
13131                 }
13132             }
13133         }
13134
13135         synchronized(this) {
13136             if (procsToKill != null) {
13137                 for (int i=procsToKill.size()-1; i>=0; i--) {
13138                     ProcessRecord proc = procsToKill.get(i);
13139                     Slog.i(TAG, "Removing system update proc: " + proc);
13140                     removeProcessLocked(proc, true, false, "system update done");
13141                 }
13142             }
13143
13144             // Now that we have cleaned up any update processes, we
13145             // are ready to start launching real processes and know that
13146             // we won't trample on them any more.
13147             mProcessesReady = true;
13148         }
13149
13150         Slog.i(TAG, "System now ready");
13151         EventLog.writeEvent(EventLogTags.BOOT_PROGRESS_AMS_READY,
13152             SystemClock.uptimeMillis());
13153
13154         synchronized(this) {
13155             // Make sure we have no pre-ready processes sitting around.
13156
13157             if (mFactoryTest == FactoryTest.FACTORY_TEST_LOW_LEVEL) {
13158                 ResolveInfo ri = mContext.getPackageManager()
13159                         .resolveActivity(new Intent(Intent.ACTION_FACTORY_TEST),
13160                                 STOCK_PM_FLAGS);
13161                 CharSequence errorMsg = null;
13162                 if (ri != null) {
13163                     ActivityInfo ai = ri.activityInfo;
13164                     ApplicationInfo app = ai.applicationInfo;
13165                     if ((app.flags&ApplicationInfo.FLAG_SYSTEM) != 0) {
13166                         mTopAction = Intent.ACTION_FACTORY_TEST;
13167                         mTopData = null;
13168                         mTopComponent = new ComponentName(app.packageName,
13169                                 ai.name);
13170                     } else {
13171                         errorMsg = mContext.getResources().getText(
13172                                 com.android.internal.R.string.factorytest_not_system);
13173                     }
13174                 } else {
13175                     errorMsg = mContext.getResources().getText(
13176                             com.android.internal.R.string.factorytest_no_action);
13177                 }
13178                 if (errorMsg != null) {
13179                     mTopAction = null;
13180                     mTopData = null;
13181                     mTopComponent = null;
13182                     Message msg = Message.obtain();
13183                     msg.what = SHOW_FACTORY_ERROR_UI_MSG;
13184                     msg.getData().putCharSequence("msg", errorMsg);
13185                     mUiHandler.sendMessage(msg);
13186                 }
13187             }
13188         }
13189
13190         retrieveSettings();
13191         final int currentUserId;
13192         synchronized (this) {
13193             currentUserId = mUserController.getCurrentUserIdLocked();
13194             readGrantedUriPermissionsLocked();
13195         }
13196
13197         if (goingCallback != null) goingCallback.run();
13198
13199         mBatteryStatsService.noteEvent(BatteryStats.HistoryItem.EVENT_USER_RUNNING_START,
13200                 Integer.toString(currentUserId), currentUserId);
13201         mBatteryStatsService.noteEvent(BatteryStats.HistoryItem.EVENT_USER_FOREGROUND_START,
13202                 Integer.toString(currentUserId), currentUserId);
13203         mSystemServiceManager.startUser(currentUserId);
13204
13205         synchronized (this) {
13206             // Only start up encryption-aware persistent apps; once user is
13207             // unlocked we'll come back around and start unaware apps
13208             startPersistentApps(PackageManager.MATCH_DIRECT_BOOT_AWARE);
13209
13210             // Start up initial activity.
13211             mBooting = true;
13212             // Enable home activity for system user, so that the system can always boot
13213             if (UserManager.isSplitSystemUser()) {
13214                 ComponentName cName = new ComponentName(mContext, SystemUserHomeActivity.class);
13215                 try {
13216                     AppGlobals.getPackageManager().setComponentEnabledSetting(cName,
13217                             PackageManager.COMPONENT_ENABLED_STATE_ENABLED, 0,
13218                             UserHandle.USER_SYSTEM);
13219                 } catch (RemoteException e) {
13220                     throw e.rethrowAsRuntimeException();
13221                 }
13222             }
13223             startHomeActivityLocked(currentUserId, "systemReady");
13224
13225             try {
13226                 if (AppGlobals.getPackageManager().hasSystemUidErrors()) {
13227                     Slog.e(TAG, "UIDs on the system are inconsistent, you need to wipe your"
13228                             + " data partition or your device will be unstable.");
13229                     mUiHandler.obtainMessage(SHOW_UID_ERROR_UI_MSG).sendToTarget();
13230                 }
13231             } catch (RemoteException e) {
13232             }
13233
13234             if (!Build.isBuildConsistent()) {
13235                 Slog.e(TAG, "Build fingerprint is not consistent, warning user");
13236                 mUiHandler.obtainMessage(SHOW_FINGERPRINT_ERROR_UI_MSG).sendToTarget();
13237             }
13238
13239             long ident = Binder.clearCallingIdentity();
13240             try {
13241                 Intent intent = new Intent(Intent.ACTION_USER_STARTED);
13242                 intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY
13243                         | Intent.FLAG_RECEIVER_FOREGROUND);
13244                 intent.putExtra(Intent.EXTRA_USER_HANDLE, currentUserId);
13245                 broadcastIntentLocked(null, null, intent,
13246                         null, null, 0, null, null, null, AppOpsManager.OP_NONE,
13247                         null, false, false, MY_PID, Process.SYSTEM_UID,
13248                         currentUserId);
13249                 intent = new Intent(Intent.ACTION_USER_STARTING);
13250                 intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY);
13251                 intent.putExtra(Intent.EXTRA_USER_HANDLE, currentUserId);
13252                 broadcastIntentLocked(null, null, intent,
13253                         null, new IIntentReceiver.Stub() {
13254                             @Override
13255                             public void performReceive(Intent intent, int resultCode, String data,
13256                                     Bundle extras, boolean ordered, boolean sticky, int sendingUser)
13257                                     throws RemoteException {
13258                             }
13259                         }, 0, null, null,
13260                         new String[] {INTERACT_ACROSS_USERS}, AppOpsManager.OP_NONE,
13261                         null, true, false, MY_PID, Process.SYSTEM_UID, UserHandle.USER_ALL);
13262             } catch (Throwable t) {
13263                 Slog.wtf(TAG, "Failed sending first user broadcasts", t);
13264             } finally {
13265                 Binder.restoreCallingIdentity(ident);
13266             }
13267             mStackSupervisor.resumeFocusedStackTopActivityLocked();
13268             mUserController.sendUserSwitchBroadcastsLocked(-1, currentUserId);
13269         }
13270     }
13271
13272     void killAppAtUsersRequest(ProcessRecord app, Dialog fromDialog) {
13273         synchronized (this) {
13274             mAppErrors.killAppAtUserRequestLocked(app, fromDialog);
13275         }
13276     }
13277
13278     void skipCurrentReceiverLocked(ProcessRecord app) {
13279         for (BroadcastQueue queue : mBroadcastQueues) {
13280             queue.skipCurrentReceiverLocked(app);
13281         }
13282     }
13283
13284     /**
13285      * Used by {@link com.android.internal.os.RuntimeInit} to report when an application crashes.
13286      * The application process will exit immediately after this call returns.
13287      * @param app object of the crashing app, null for the system server
13288      * @param crashInfo describing the exception
13289      */
13290     public void handleApplicationCrash(IBinder app, ApplicationErrorReport.CrashInfo crashInfo) {
13291         ProcessRecord r = findAppProcess(app, "Crash");
13292         final String processName = app == null ? "system_server"
13293                 : (r == null ? "unknown" : r.processName);
13294
13295         handleApplicationCrashInner("crash", r, processName, crashInfo);
13296     }
13297
13298     /* Native crash reporting uses this inner version because it needs to be somewhat
13299      * decoupled from the AM-managed cleanup lifecycle
13300      */
13301     void handleApplicationCrashInner(String eventType, ProcessRecord r, String processName,
13302             ApplicationErrorReport.CrashInfo crashInfo) {
13303         EventLog.writeEvent(EventLogTags.AM_CRASH, Binder.getCallingPid(),
13304                 UserHandle.getUserId(Binder.getCallingUid()), processName,
13305                 r == null ? -1 : r.info.flags,
13306                 crashInfo.exceptionClassName,
13307                 crashInfo.exceptionMessage,
13308                 crashInfo.throwFileName,
13309                 crashInfo.throwLineNumber);
13310
13311         addErrorToDropBox(eventType, r, processName, null, null, null, null, null, crashInfo);
13312
13313         mAppErrors.crashApplication(r, crashInfo);
13314     }
13315
13316     public void handleApplicationStrictModeViolation(
13317             IBinder app,
13318             int violationMask,
13319             StrictMode.ViolationInfo info) {
13320         ProcessRecord r = findAppProcess(app, "StrictMode");
13321         if (r == null) {
13322             return;
13323         }
13324
13325         if ((violationMask & StrictMode.PENALTY_DROPBOX) != 0) {
13326             Integer stackFingerprint = info.hashCode();
13327             boolean logIt = true;
13328             synchronized (mAlreadyLoggedViolatedStacks) {
13329                 if (mAlreadyLoggedViolatedStacks.contains(stackFingerprint)) {
13330                     logIt = false;
13331                     // TODO: sub-sample into EventLog for these, with
13332                     // the info.durationMillis?  Then we'd get
13333                     // the relative pain numbers, without logging all
13334                     // the stack traces repeatedly.  We'd want to do
13335                     // likewise in the client code, which also does
13336                     // dup suppression, before the Binder call.
13337                 } else {
13338                     if (mAlreadyLoggedViolatedStacks.size() >= MAX_DUP_SUPPRESSED_STACKS) {
13339                         mAlreadyLoggedViolatedStacks.clear();
13340                     }
13341                     mAlreadyLoggedViolatedStacks.add(stackFingerprint);
13342                 }
13343             }
13344             if (logIt) {
13345                 logStrictModeViolationToDropBox(r, info);
13346             }
13347         }
13348
13349         if ((violationMask & StrictMode.PENALTY_DIALOG) != 0) {
13350             AppErrorResult result = new AppErrorResult();
13351             synchronized (this) {
13352                 final long origId = Binder.clearCallingIdentity();
13353
13354                 Message msg = Message.obtain();
13355                 msg.what = SHOW_STRICT_MODE_VIOLATION_UI_MSG;
13356                 HashMap<String, Object> data = new HashMap<String, Object>();
13357                 data.put("result", result);
13358                 data.put("app", r);
13359                 data.put("violationMask", violationMask);
13360                 data.put("info", info);
13361                 msg.obj = data;
13362                 mUiHandler.sendMessage(msg);
13363
13364                 Binder.restoreCallingIdentity(origId);
13365             }
13366             int res = result.get();
13367             Slog.w(TAG, "handleApplicationStrictModeViolation; res=" + res);
13368         }
13369     }
13370
13371     // Depending on the policy in effect, there could be a bunch of
13372     // these in quick succession so we try to batch these together to
13373     // minimize disk writes, number of dropbox entries, and maximize
13374     // compression, by having more fewer, larger records.
13375     private void logStrictModeViolationToDropBox(
13376             ProcessRecord process,
13377             StrictMode.ViolationInfo info) {
13378         if (info == null) {
13379             return;
13380         }
13381         final boolean isSystemApp = process == null ||
13382                 (process.info.flags & (ApplicationInfo.FLAG_SYSTEM |
13383                                        ApplicationInfo.FLAG_UPDATED_SYSTEM_APP)) != 0;
13384         final String processName = process == null ? "unknown" : process.processName;
13385         final String dropboxTag = isSystemApp ? "system_app_strictmode" : "data_app_strictmode";
13386         final DropBoxManager dbox = (DropBoxManager)
13387                 mContext.getSystemService(Context.DROPBOX_SERVICE);
13388
13389         // Exit early if the dropbox isn't configured to accept this report type.
13390         if (dbox == null || !dbox.isTagEnabled(dropboxTag)) return;
13391
13392         boolean bufferWasEmpty;
13393         boolean needsFlush;
13394         final StringBuilder sb = isSystemApp ? mStrictModeBuffer : new StringBuilder(1024);
13395         synchronized (sb) {
13396             bufferWasEmpty = sb.length() == 0;
13397             appendDropBoxProcessHeaders(process, processName, sb);
13398             sb.append("Build: ").append(Build.FINGERPRINT).append("\n");
13399             sb.append("System-App: ").append(isSystemApp).append("\n");
13400             sb.append("Uptime-Millis: ").append(info.violationUptimeMillis).append("\n");
13401             if (info.violationNumThisLoop != 0) {
13402                 sb.append("Loop-Violation-Number: ").append(info.violationNumThisLoop).append("\n");
13403             }
13404             if (info.numAnimationsRunning != 0) {
13405                 sb.append("Animations-Running: ").append(info.numAnimationsRunning).append("\n");
13406             }
13407             if (info.broadcastIntentAction != null) {
13408                 sb.append("Broadcast-Intent-Action: ").append(info.broadcastIntentAction).append("\n");
13409             }
13410             if (info.durationMillis != -1) {
13411                 sb.append("Duration-Millis: ").append(info.durationMillis).append("\n");
13412             }
13413             if (info.numInstances != -1) {
13414                 sb.append("Instance-Count: ").append(info.numInstances).append("\n");
13415             }
13416             if (info.tags != null) {
13417                 for (String tag : info.tags) {
13418                     sb.append("Span-Tag: ").append(tag).append("\n");
13419                 }
13420             }
13421             sb.append("\n");
13422             if (info.crashInfo != null && info.crashInfo.stackTrace != null) {
13423                 sb.append(info.crashInfo.stackTrace);
13424                 sb.append("\n");
13425             }
13426             if (info.message != null) {
13427                 sb.append(info.message);
13428                 sb.append("\n");
13429             }
13430
13431             // Only buffer up to ~64k.  Various logging bits truncate
13432             // things at 128k.
13433             needsFlush = (sb.length() > 64 * 1024);
13434         }
13435
13436         // Flush immediately if the buffer's grown too large, or this
13437         // is a non-system app.  Non-system apps are isolated with a
13438         // different tag & policy and not batched.
13439         //
13440         // Batching is useful during internal testing with
13441         // StrictMode settings turned up high.  Without batching,
13442         // thousands of separate files could be created on boot.
13443         if (!isSystemApp || needsFlush) {
13444             new Thread("Error dump: " + dropboxTag) {
13445                 @Override
13446                 public void run() {
13447                     String report;
13448                     synchronized (sb) {
13449                         report = sb.toString();
13450                         sb.delete(0, sb.length());
13451                         sb.trimToSize();
13452                     }
13453                     if (report.length() != 0) {
13454                         dbox.addText(dropboxTag, report);
13455                     }
13456                 }
13457             }.start();
13458             return;
13459         }
13460
13461         // System app batching:
13462         if (!bufferWasEmpty) {
13463             // An existing dropbox-writing thread is outstanding, so
13464             // we don't need to start it up.  The existing thread will
13465             // catch the buffer appends we just did.
13466             return;
13467         }
13468
13469         // Worker thread to both batch writes and to avoid blocking the caller on I/O.
13470         // (After this point, we shouldn't access AMS internal data structures.)
13471         new Thread("Error dump: " + dropboxTag) {
13472             @Override
13473             public void run() {
13474                 // 5 second sleep to let stacks arrive and be batched together
13475                 try {
13476                     Thread.sleep(5000);  // 5 seconds
13477                 } catch (InterruptedException e) {}
13478
13479                 String errorReport;
13480                 synchronized (mStrictModeBuffer) {
13481                     errorReport = mStrictModeBuffer.toString();
13482                     if (errorReport.length() == 0) {
13483                         return;
13484                     }
13485                     mStrictModeBuffer.delete(0, mStrictModeBuffer.length());
13486                     mStrictModeBuffer.trimToSize();
13487                 }
13488                 dbox.addText(dropboxTag, errorReport);
13489             }
13490         }.start();
13491     }
13492
13493     /**
13494      * Used by {@link Log} via {@link com.android.internal.os.RuntimeInit} to report serious errors.
13495      * @param app object of the crashing app, null for the system server
13496      * @param tag reported by the caller
13497      * @param system whether this wtf is coming from the system
13498      * @param crashInfo describing the context of the error
13499      * @return true if the process should exit immediately (WTF is fatal)
13500      */
13501     public boolean handleApplicationWtf(final IBinder app, final String tag, boolean system,
13502             final ApplicationErrorReport.CrashInfo crashInfo) {
13503         final int callingUid = Binder.getCallingUid();
13504         final int callingPid = Binder.getCallingPid();
13505
13506         if (system) {
13507             // If this is coming from the system, we could very well have low-level
13508             // system locks held, so we want to do this all asynchronously.  And we
13509             // never want this to become fatal, so there is that too.
13510             mHandler.post(new Runnable() {
13511                 @Override public void run() {
13512                     handleApplicationWtfInner(callingUid, callingPid, app, tag, crashInfo);
13513                 }
13514             });
13515             return false;
13516         }
13517
13518         final ProcessRecord r = handleApplicationWtfInner(callingUid, callingPid, app, tag,
13519                 crashInfo);
13520
13521         if (r != null && r.pid != Process.myPid() &&
13522                 Settings.Global.getInt(mContext.getContentResolver(),
13523                         Settings.Global.WTF_IS_FATAL, 0) != 0) {
13524             mAppErrors.crashApplication(r, crashInfo);
13525             return true;
13526         } else {
13527             return false;
13528         }
13529     }
13530
13531     ProcessRecord handleApplicationWtfInner(int callingUid, int callingPid, IBinder app, String tag,
13532             final ApplicationErrorReport.CrashInfo crashInfo) {
13533         final ProcessRecord r = findAppProcess(app, "WTF");
13534         final String processName = app == null ? "system_server"
13535                 : (r == null ? "unknown" : r.processName);
13536
13537         EventLog.writeEvent(EventLogTags.AM_WTF, UserHandle.getUserId(callingUid), callingPid,
13538                 processName, r == null ? -1 : r.info.flags, tag, crashInfo.exceptionMessage);
13539
13540         addErrorToDropBox("wtf", r, processName, null, null, tag, null, null, crashInfo);
13541
13542         return r;
13543     }
13544
13545     /**
13546      * @param app object of some object (as stored in {@link com.android.internal.os.RuntimeInit})
13547      * @return the corresponding {@link ProcessRecord} object, or null if none could be found
13548      */
13549     private ProcessRecord findAppProcess(IBinder app, String reason) {
13550         if (app == null) {
13551             return null;
13552         }
13553
13554         synchronized (this) {
13555             final int NP = mProcessNames.getMap().size();
13556             for (int ip=0; ip<NP; ip++) {
13557                 SparseArray<ProcessRecord> apps = mProcessNames.getMap().valueAt(ip);
13558                 final int NA = apps.size();
13559                 for (int ia=0; ia<NA; ia++) {
13560                     ProcessRecord p = apps.valueAt(ia);
13561                     if (p.thread != null && p.thread.asBinder() == app) {
13562                         return p;
13563                     }
13564                 }
13565             }
13566
13567             Slog.w(TAG, "Can't find mystery application for " + reason
13568                     + " from pid=" + Binder.getCallingPid()
13569                     + " uid=" + Binder.getCallingUid() + ": " + app);
13570             return null;
13571         }
13572     }
13573
13574     /**
13575      * Utility function for addErrorToDropBox and handleStrictModeViolation's logging
13576      * to append various headers to the dropbox log text.
13577      */
13578     private void appendDropBoxProcessHeaders(ProcessRecord process, String processName,
13579             StringBuilder sb) {
13580         // Watchdog thread ends up invoking this function (with
13581         // a null ProcessRecord) to add the stack file to dropbox.
13582         // Do not acquire a lock on this (am) in such cases, as it
13583         // could cause a potential deadlock, if and when watchdog
13584         // is invoked due to unavailability of lock on am and it
13585         // would prevent watchdog from killing system_server.
13586         if (process == null) {
13587             sb.append("Process: ").append(processName).append("\n");
13588             return;
13589         }
13590         // Note: ProcessRecord 'process' is guarded by the service
13591         // instance.  (notably process.pkgList, which could otherwise change
13592         // concurrently during execution of this method)
13593         synchronized (this) {
13594             sb.append("Process: ").append(processName).append("\n");
13595             int flags = process.info.flags;
13596             IPackageManager pm = AppGlobals.getPackageManager();
13597             sb.append("Flags: 0x").append(Integer.toString(flags, 16)).append("\n");
13598             for (int ip=0; ip<process.pkgList.size(); ip++) {
13599                 String pkg = process.pkgList.keyAt(ip);
13600                 sb.append("Package: ").append(pkg);
13601                 try {
13602                     PackageInfo pi = pm.getPackageInfo(pkg, 0, UserHandle.getCallingUserId());
13603                     if (pi != null) {
13604                         sb.append(" v").append(pi.versionCode);
13605                         if (pi.versionName != null) {
13606                             sb.append(" (").append(pi.versionName).append(")");
13607                         }
13608                     }
13609                 } catch (RemoteException e) {
13610                     Slog.e(TAG, "Error getting package info: " + pkg, e);
13611                 }
13612                 sb.append("\n");
13613             }
13614         }
13615     }
13616
13617     private static String processClass(ProcessRecord process) {
13618         if (process == null || process.pid == MY_PID) {
13619             return "system_server";
13620         } else if ((process.info.flags & ApplicationInfo.FLAG_SYSTEM) != 0) {
13621             return "system_app";
13622         } else {
13623             return "data_app";
13624         }
13625     }
13626
13627     private volatile long mWtfClusterStart;
13628     private volatile int mWtfClusterCount;
13629
13630     /**
13631      * Write a description of an error (crash, WTF, ANR) to the drop box.
13632      * @param eventType to include in the drop box tag ("crash", "wtf", etc.)
13633      * @param process which caused the error, null means the system server
13634      * @param activity which triggered the error, null if unknown
13635      * @param parent activity related to the error, null if unknown
13636      * @param subject line related to the error, null if absent
13637      * @param report in long form describing the error, null if absent
13638      * @param dataFile text file to include in the report, null if none
13639      * @param crashInfo giving an application stack trace, null if absent
13640      */
13641     public void addErrorToDropBox(String eventType,
13642             ProcessRecord process, String processName, ActivityRecord activity,
13643             ActivityRecord parent, String subject,
13644             final String report, final File dataFile,
13645             final ApplicationErrorReport.CrashInfo crashInfo) {
13646         // NOTE -- this must never acquire the ActivityManagerService lock,
13647         // otherwise the watchdog may be prevented from resetting the system.
13648
13649         final String dropboxTag = processClass(process) + "_" + eventType;
13650         final DropBoxManager dbox = (DropBoxManager)
13651                 mContext.getSystemService(Context.DROPBOX_SERVICE);
13652
13653         // Exit early if the dropbox isn't configured to accept this report type.
13654         if (dbox == null || !dbox.isTagEnabled(dropboxTag)) return;
13655
13656         // Rate-limit how often we're willing to do the heavy lifting below to
13657         // collect and record logs; currently 5 logs per 10 second period.
13658         final long now = SystemClock.elapsedRealtime();
13659         if (now - mWtfClusterStart > 10 * DateUtils.SECOND_IN_MILLIS) {
13660             mWtfClusterStart = now;
13661             mWtfClusterCount = 1;
13662         } else {
13663             if (mWtfClusterCount++ >= 5) return;
13664         }
13665
13666         final StringBuilder sb = new StringBuilder(1024);
13667         appendDropBoxProcessHeaders(process, processName, sb);
13668         if (process != null) {
13669             sb.append("Foreground: ")
13670                     .append(process.isInterestingToUserLocked() ? "Yes" : "No")
13671                     .append("\n");
13672         }
13673         if (activity != null) {
13674             sb.append("Activity: ").append(activity.shortComponentName).append("\n");
13675         }
13676         if (parent != null && parent.app != null && parent.app.pid != process.pid) {
13677             sb.append("Parent-Process: ").append(parent.app.processName).append("\n");
13678         }
13679         if (parent != null && parent != activity) {
13680             sb.append("Parent-Activity: ").append(parent.shortComponentName).append("\n");
13681         }
13682         if (subject != null) {
13683             sb.append("Subject: ").append(subject).append("\n");
13684         }
13685         sb.append("Build: ").append(Build.FINGERPRINT).append("\n");
13686         if (Debug.isDebuggerConnected()) {
13687             sb.append("Debugger: Connected\n");
13688         }
13689         sb.append("\n");
13690
13691         // Do the rest in a worker thread to avoid blocking the caller on I/O
13692         // (After this point, we shouldn't access AMS internal data structures.)
13693         Thread worker = new Thread("Error dump: " + dropboxTag) {
13694             @Override
13695             public void run() {
13696                 if (report != null) {
13697                     sb.append(report);
13698                 }
13699
13700                 String setting = Settings.Global.ERROR_LOGCAT_PREFIX + dropboxTag;
13701                 int lines = Settings.Global.getInt(mContext.getContentResolver(), setting, 0);
13702                 int maxDataFileSize = DROPBOX_MAX_SIZE - sb.length()
13703                         - lines * RESERVED_BYTES_PER_LOGCAT_LINE;
13704
13705                 if (dataFile != null && maxDataFileSize > 0) {
13706                     try {
13707                         sb.append(FileUtils.readTextFile(dataFile, maxDataFileSize,
13708                                     "\n\n[[TRUNCATED]]"));
13709                     } catch (IOException e) {
13710                         Slog.e(TAG, "Error reading " + dataFile, e);
13711                     }
13712                 }
13713                 if (crashInfo != null && crashInfo.stackTrace != null) {
13714                     sb.append(crashInfo.stackTrace);
13715                 }
13716
13717                 if (lines > 0) {
13718                     sb.append("\n");
13719
13720                     // Merge several logcat streams, and take the last N lines
13721                     InputStreamReader input = null;
13722                     try {
13723                         java.lang.Process logcat = new ProcessBuilder(
13724                                 "/system/bin/timeout", "-k", "15s", "10s",
13725                                 "/system/bin/logcat", "-v", "time", "-b", "events", "-b", "system",
13726                                 "-b", "main", "-b", "crash", "-t", String.valueOf(lines))
13727                                         .redirectErrorStream(true).start();
13728
13729                         try { logcat.getOutputStream().close(); } catch (IOException e) {}
13730                         try { logcat.getErrorStream().close(); } catch (IOException e) {}
13731                         input = new InputStreamReader(logcat.getInputStream());
13732
13733                         int num;
13734                         char[] buf = new char[8192];
13735                         while ((num = input.read(buf)) > 0) sb.append(buf, 0, num);
13736                     } catch (IOException e) {
13737                         Slog.e(TAG, "Error running logcat", e);
13738                     } finally {
13739                         if (input != null) try { input.close(); } catch (IOException e) {}
13740                     }
13741                 }
13742
13743                 dbox.addText(dropboxTag, sb.toString());
13744             }
13745         };
13746
13747         if (process == null) {
13748             // If process is null, we are being called from some internal code
13749             // and may be about to die -- run this synchronously.
13750             worker.run();
13751         } else {
13752             worker.start();
13753         }
13754     }
13755
13756     @Override
13757     public List<ActivityManager.ProcessErrorStateInfo> getProcessesInErrorState() {
13758         enforceNotIsolatedCaller("getProcessesInErrorState");
13759         // assume our apps are happy - lazy create the list
13760         List<ActivityManager.ProcessErrorStateInfo> errList = null;
13761
13762         final boolean allUsers = ActivityManager.checkUidPermission(INTERACT_ACROSS_USERS_FULL,
13763                 Binder.getCallingUid()) == PackageManager.PERMISSION_GRANTED;
13764         int userId = UserHandle.getUserId(Binder.getCallingUid());
13765
13766         synchronized (this) {
13767
13768             // iterate across all processes
13769             for (int i=mLruProcesses.size()-1; i>=0; i--) {
13770                 ProcessRecord app = mLruProcesses.get(i);
13771                 if (!allUsers && app.userId != userId) {
13772                     continue;
13773                 }
13774                 if ((app.thread != null) && (app.crashing || app.notResponding)) {
13775                     // This one's in trouble, so we'll generate a report for it
13776                     // crashes are higher priority (in case there's a crash *and* an anr)
13777                     ActivityManager.ProcessErrorStateInfo report = null;
13778                     if (app.crashing) {
13779                         report = app.crashingReport;
13780                     } else if (app.notResponding) {
13781                         report = app.notRespondingReport;
13782                     }
13783
13784                     if (report != null) {
13785                         if (errList == null) {
13786                             errList = new ArrayList<ActivityManager.ProcessErrorStateInfo>(1);
13787                         }
13788                         errList.add(report);
13789                     } else {
13790                         Slog.w(TAG, "Missing app error report, app = " + app.processName +
13791                                 " crashing = " + app.crashing +
13792                                 " notResponding = " + app.notResponding);
13793                     }
13794                 }
13795             }
13796         }
13797
13798         return errList;
13799     }
13800
13801     static int procStateToImportance(int procState, int memAdj,
13802             ActivityManager.RunningAppProcessInfo currApp) {
13803         int imp = ActivityManager.RunningAppProcessInfo.procStateToImportance(procState);
13804         if (imp == ActivityManager.RunningAppProcessInfo.IMPORTANCE_BACKGROUND) {
13805             currApp.lru = memAdj;
13806         } else {
13807             currApp.lru = 0;
13808         }
13809         return imp;
13810     }
13811
13812     private void fillInProcMemInfo(ProcessRecord app,
13813             ActivityManager.RunningAppProcessInfo outInfo) {
13814         outInfo.pid = app.pid;
13815         outInfo.uid = app.info.uid;
13816         if (mHeavyWeightProcess == app) {
13817             outInfo.flags |= ActivityManager.RunningAppProcessInfo.FLAG_CANT_SAVE_STATE;
13818         }
13819         if (app.persistent) {
13820             outInfo.flags |= ActivityManager.RunningAppProcessInfo.FLAG_PERSISTENT;
13821         }
13822         if (app.activities.size() > 0) {
13823             outInfo.flags |= ActivityManager.RunningAppProcessInfo.FLAG_HAS_ACTIVITIES;
13824         }
13825         outInfo.lastTrimLevel = app.trimMemoryLevel;
13826         int adj = app.curAdj;
13827         int procState = app.curProcState;
13828         outInfo.importance = procStateToImportance(procState, adj, outInfo);
13829         outInfo.importanceReasonCode = app.adjTypeCode;
13830         outInfo.processState = app.curProcState;
13831     }
13832
13833     @Override
13834     public List<ActivityManager.RunningAppProcessInfo> getRunningAppProcesses() {
13835         enforceNotIsolatedCaller("getRunningAppProcesses");
13836
13837         final int callingUid = Binder.getCallingUid();
13838
13839         // Lazy instantiation of list
13840         List<ActivityManager.RunningAppProcessInfo> runList = null;
13841         final boolean allUsers = ActivityManager.checkUidPermission(INTERACT_ACROSS_USERS_FULL,
13842                 callingUid) == PackageManager.PERMISSION_GRANTED;
13843         final int userId = UserHandle.getUserId(callingUid);
13844         final boolean allUids = isGetTasksAllowed(
13845                 "getRunningAppProcesses", Binder.getCallingPid(), callingUid);
13846
13847         synchronized (this) {
13848             // Iterate across all processes
13849             for (int i = mLruProcesses.size() - 1; i >= 0; i--) {
13850                 ProcessRecord app = mLruProcesses.get(i);
13851                 if ((!allUsers && app.userId != userId)
13852                         || (!allUids && app.uid != callingUid)) {
13853                     continue;
13854                 }
13855                 if ((app.thread != null) && (!app.crashing && !app.notResponding)) {
13856                     // Generate process state info for running application
13857                     ActivityManager.RunningAppProcessInfo currApp =
13858                         new ActivityManager.RunningAppProcessInfo(app.processName,
13859                                 app.pid, app.getPackageList());
13860                     fillInProcMemInfo(app, currApp);
13861                     if (app.adjSource instanceof ProcessRecord) {
13862                         currApp.importanceReasonPid = ((ProcessRecord)app.adjSource).pid;
13863                         currApp.importanceReasonImportance =
13864                                 ActivityManager.RunningAppProcessInfo.procStateToImportance(
13865                                         app.adjSourceProcState);
13866                     } else if (app.adjSource instanceof ActivityRecord) {
13867                         ActivityRecord r = (ActivityRecord)app.adjSource;
13868                         if (r.app != null) currApp.importanceReasonPid = r.app.pid;
13869                     }
13870                     if (app.adjTarget instanceof ComponentName) {
13871                         currApp.importanceReasonComponent = (ComponentName)app.adjTarget;
13872                     }
13873                     //Slog.v(TAG, "Proc " + app.processName + ": imp=" + currApp.importance
13874                     //        + " lru=" + currApp.lru);
13875                     if (runList == null) {
13876                         runList = new ArrayList<>();
13877                     }
13878                     runList.add(currApp);
13879                 }
13880             }
13881         }
13882         return runList;
13883     }
13884
13885     @Override
13886     public List<ApplicationInfo> getRunningExternalApplications() {
13887         enforceNotIsolatedCaller("getRunningExternalApplications");
13888         List<ActivityManager.RunningAppProcessInfo> runningApps = getRunningAppProcesses();
13889         List<ApplicationInfo> retList = new ArrayList<ApplicationInfo>();
13890         if (runningApps != null && runningApps.size() > 0) {
13891             Set<String> extList = new HashSet<String>();
13892             for (ActivityManager.RunningAppProcessInfo app : runningApps) {
13893                 if (app.pkgList != null) {
13894                     for (String pkg : app.pkgList) {
13895                         extList.add(pkg);
13896                     }
13897                 }
13898             }
13899             IPackageManager pm = AppGlobals.getPackageManager();
13900             for (String pkg : extList) {
13901                 try {
13902                     ApplicationInfo info = pm.getApplicationInfo(pkg, 0, UserHandle.getCallingUserId());
13903                     if ((info.flags & ApplicationInfo.FLAG_EXTERNAL_STORAGE) != 0) {
13904                         retList.add(info);
13905                     }
13906                 } catch (RemoteException e) {
13907                 }
13908             }
13909         }
13910         return retList;
13911     }
13912
13913     @Override
13914     public void getMyMemoryState(ActivityManager.RunningAppProcessInfo outInfo) {
13915         enforceNotIsolatedCaller("getMyMemoryState");
13916         synchronized (this) {
13917             ProcessRecord proc;
13918             synchronized (mPidsSelfLocked) {
13919                 proc = mPidsSelfLocked.get(Binder.getCallingPid());
13920             }
13921             fillInProcMemInfo(proc, outInfo);
13922         }
13923     }
13924
13925     @Override
13926     public int getMemoryTrimLevel() {
13927         enforceNotIsolatedCaller("getMyMemoryState");
13928         synchronized (this) {
13929             return mLastMemoryLevel;
13930         }
13931     }
13932
13933     @Override
13934     public void onShellCommand(FileDescriptor in, FileDescriptor out,
13935             FileDescriptor err, String[] args, ResultReceiver resultReceiver) {
13936         (new ActivityManagerShellCommand(this, false)).exec(
13937                 this, in, out, err, args, resultReceiver);
13938     }
13939
13940     @Override
13941     protected void dump(FileDescriptor fd, PrintWriter pw, String[] args) {
13942         if (checkCallingPermission(android.Manifest.permission.DUMP)
13943                 != PackageManager.PERMISSION_GRANTED) {
13944             pw.println("Permission Denial: can't dump ActivityManager from from pid="
13945                     + Binder.getCallingPid()
13946                     + ", uid=" + Binder.getCallingUid()
13947                     + " without permission "
13948                     + android.Manifest.permission.DUMP);
13949             return;
13950         }
13951
13952         boolean dumpAll = false;
13953         boolean dumpClient = false;
13954         boolean dumpCheckin = false;
13955         boolean dumpCheckinFormat = false;
13956         String dumpPackage = null;
13957
13958         int opti = 0;
13959         while (opti < args.length) {
13960             String opt = args[opti];
13961             if (opt == null || opt.length() <= 0 || opt.charAt(0) != '-') {
13962                 break;
13963             }
13964             opti++;
13965             if ("-a".equals(opt)) {
13966                 dumpAll = true;
13967             } else if ("-c".equals(opt)) {
13968                 dumpClient = true;
13969             } else if ("-p".equals(opt)) {
13970                 if (opti < args.length) {
13971                     dumpPackage = args[opti];
13972                     opti++;
13973                 } else {
13974                     pw.println("Error: -p option requires package argument");
13975                     return;
13976                 }
13977                 dumpClient = true;
13978             } else if ("--checkin".equals(opt)) {
13979                 dumpCheckin = dumpCheckinFormat = true;
13980             } else if ("-C".equals(opt)) {
13981                 dumpCheckinFormat = true;
13982             } else if ("-h".equals(opt)) {
13983                 ActivityManagerShellCommand.dumpHelp(pw, true);
13984                 return;
13985             } else {
13986                 pw.println("Unknown argument: " + opt + "; use -h for help");
13987             }
13988         }
13989
13990         long origId = Binder.clearCallingIdentity();
13991         boolean more = false;
13992         // Is the caller requesting to dump a particular piece of data?
13993         if (opti < args.length) {
13994             String cmd = args[opti];
13995             opti++;
13996             if ("activities".equals(cmd) || "a".equals(cmd)) {
13997                 synchronized (this) {
13998                     dumpActivitiesLocked(fd, pw, args, opti, true, dumpClient, dumpPackage);
13999                 }
14000             } else if ("recents".equals(cmd) || "r".equals(cmd)) {
14001                 synchronized (this) {
14002                     dumpRecentsLocked(fd, pw, args, opti, true, dumpPackage);
14003                 }
14004             } else if ("broadcasts".equals(cmd) || "b".equals(cmd)) {
14005                 String[] newArgs;
14006                 String name;
14007                 if (opti >= args.length) {
14008                     name = null;
14009                     newArgs = EMPTY_STRING_ARRAY;
14010                 } else {
14011                     dumpPackage = args[opti];
14012                     opti++;
14013                     newArgs = new String[args.length - opti];
14014                     if (args.length > 2) System.arraycopy(args, opti, newArgs, 0,
14015                             args.length - opti);
14016                 }
14017                 synchronized (this) {
14018                     dumpBroadcastsLocked(fd, pw, args, opti, true, dumpPackage);
14019                 }
14020             } else if ("broadcast-stats".equals(cmd)) {
14021                 String[] newArgs;
14022                 String name;
14023                 if (opti >= args.length) {
14024                     name = null;
14025                     newArgs = EMPTY_STRING_ARRAY;
14026                 } else {
14027                     dumpPackage = args[opti];
14028                     opti++;
14029                     newArgs = new String[args.length - opti];
14030                     if (args.length > 2) System.arraycopy(args, opti, newArgs, 0,
14031                             args.length - opti);
14032                 }
14033                 synchronized (this) {
14034                     if (dumpCheckinFormat) {
14035                         dumpBroadcastStatsCheckinLocked(fd, pw, args, opti, dumpCheckin,
14036                                 dumpPackage);
14037                     } else {
14038                         dumpBroadcastStatsLocked(fd, pw, args, opti, true, dumpPackage);
14039                     }
14040                 }
14041             } else if ("intents".equals(cmd) || "i".equals(cmd)) {
14042                 String[] newArgs;
14043                 String name;
14044                 if (opti >= args.length) {
14045                     name = null;
14046                     newArgs = EMPTY_STRING_ARRAY;
14047                 } else {
14048                     dumpPackage = args[opti];
14049                     opti++;
14050                     newArgs = new String[args.length - opti];
14051                     if (args.length > 2) System.arraycopy(args, opti, newArgs, 0,
14052                             args.length - opti);
14053                 }
14054                 synchronized (this) {
14055                     dumpPendingIntentsLocked(fd, pw, args, opti, true, dumpPackage);
14056                 }
14057             } else if ("processes".equals(cmd) || "p".equals(cmd)) {
14058                 String[] newArgs;
14059                 String name;
14060                 if (opti >= args.length) {
14061                     name = null;
14062                     newArgs = EMPTY_STRING_ARRAY;
14063                 } else {
14064                     dumpPackage = args[opti];
14065                     opti++;
14066                     newArgs = new String[args.length - opti];
14067                     if (args.length > 2) System.arraycopy(args, opti, newArgs, 0,
14068                             args.length - opti);
14069                 }
14070                 synchronized (this) {
14071                     dumpProcessesLocked(fd, pw, args, opti, true, dumpPackage);
14072                 }
14073             } else if ("oom".equals(cmd) || "o".equals(cmd)) {
14074                 synchronized (this) {
14075                     dumpOomLocked(fd, pw, args, opti, true);
14076                 }
14077             } else if ("permissions".equals(cmd) || "perm".equals(cmd)) {
14078                 synchronized (this) {
14079                     dumpPermissionsLocked(fd, pw, args, opti, true, null);
14080                 }
14081             } else if ("provider".equals(cmd)) {
14082                 String[] newArgs;
14083                 String name;
14084                 if (opti >= args.length) {
14085                     name = null;
14086                     newArgs = EMPTY_STRING_ARRAY;
14087                 } else {
14088                     name = args[opti];
14089                     opti++;
14090                     newArgs = new String[args.length - opti];
14091                     if (args.length > 2) System.arraycopy(args, opti, newArgs, 0, args.length - opti);
14092                 }
14093                 if (!dumpProvider(fd, pw, name, newArgs, 0, dumpAll)) {
14094                     pw.println("No providers match: " + name);
14095                     pw.println("Use -h for help.");
14096                 }
14097             } else if ("providers".equals(cmd) || "prov".equals(cmd)) {
14098                 synchronized (this) {
14099                     dumpProvidersLocked(fd, pw, args, opti, true, null);
14100                 }
14101             } else if ("service".equals(cmd)) {
14102                 String[] newArgs;
14103                 String name;
14104                 if (opti >= args.length) {
14105                     name = null;
14106                     newArgs = EMPTY_STRING_ARRAY;
14107                 } else {
14108                     name = args[opti];
14109                     opti++;
14110                     newArgs = new String[args.length - opti];
14111                     if (args.length > 2) System.arraycopy(args, opti, newArgs, 0,
14112                             args.length - opti);
14113                 }
14114                 if (!mServices.dumpService(fd, pw, name, newArgs, 0, dumpAll)) {
14115                     pw.println("No services match: " + name);
14116                     pw.println("Use -h for help.");
14117                 }
14118             } else if ("package".equals(cmd)) {
14119                 String[] newArgs;
14120                 if (opti >= args.length) {
14121                     pw.println("package: no package name specified");
14122                     pw.println("Use -h for help.");
14123                 } else {
14124                     dumpPackage = args[opti];
14125                     opti++;
14126                     newArgs = new String[args.length - opti];
14127                     if (args.length > 2) System.arraycopy(args, opti, newArgs, 0,
14128                             args.length - opti);
14129                     args = newArgs;
14130                     opti = 0;
14131                     more = true;
14132                 }
14133             } else if ("associations".equals(cmd) || "as".equals(cmd)) {
14134                 synchronized (this) {
14135                     dumpAssociationsLocked(fd, pw, args, opti, true, dumpClient, dumpPackage);
14136                 }
14137             } else if ("services".equals(cmd) || "s".equals(cmd)) {
14138                 if (dumpClient) {
14139                     ActiveServices.ServiceDumper dumper;
14140                     synchronized (this) {
14141                         dumper = mServices.newServiceDumperLocked(fd, pw, args, opti, true,
14142                                 dumpPackage);
14143                     }
14144                     dumper.dumpWithClient();
14145                 } else {
14146                     synchronized (this) {
14147                         mServices.newServiceDumperLocked(fd, pw, args, opti, true,
14148                                 dumpPackage).dumpLocked();
14149                     }
14150                 }
14151             } else if ("locks".equals(cmd)) {
14152                 LockGuard.dump(fd, pw, args);
14153             } else {
14154                 // Dumping a single activity?
14155                 if (!dumpActivity(fd, pw, cmd, args, opti, dumpAll)) {
14156                     ActivityManagerShellCommand shell = new ActivityManagerShellCommand(this, true);
14157                     int res = shell.exec(this, null, fd, null, args, new ResultReceiver(null));
14158                     if (res < 0) {
14159                         pw.println("Bad activity command, or no activities match: " + cmd);
14160                         pw.println("Use -h for help.");
14161                     }
14162                 }
14163             }
14164             if (!more) {
14165                 Binder.restoreCallingIdentity(origId);
14166                 return;
14167             }
14168         }
14169
14170         // No piece of data specified, dump everything.
14171         if (dumpCheckinFormat) {
14172             dumpBroadcastStatsCheckinLocked(fd, pw, args, opti, dumpCheckin, dumpPackage);
14173         } else if (dumpClient) {
14174             ActiveServices.ServiceDumper sdumper;
14175             synchronized (this) {
14176                 dumpPendingIntentsLocked(fd, pw, args, opti, dumpAll, dumpPackage);
14177                 pw.println();
14178                 if (dumpAll) {
14179                     pw.println("-------------------------------------------------------------------------------");
14180                 }
14181                 dumpBroadcastsLocked(fd, pw, args, opti, dumpAll, dumpPackage);
14182                 pw.println();
14183                 if (dumpAll) {
14184                     pw.println("-------------------------------------------------------------------------------");
14185                 }
14186                 if (dumpAll || dumpPackage != null) {
14187                     dumpBroadcastStatsLocked(fd, pw, args, opti, dumpAll, dumpPackage);
14188                     pw.println();
14189                     if (dumpAll) {
14190                         pw.println("-------------------------------------------------------------------------------");
14191                     }
14192                 }
14193                 dumpProvidersLocked(fd, pw, args, opti, dumpAll, dumpPackage);
14194                 pw.println();
14195                 if (dumpAll) {
14196                     pw.println("-------------------------------------------------------------------------------");
14197                 }
14198                 dumpPermissionsLocked(fd, pw, args, opti, dumpAll, dumpPackage);
14199                 pw.println();
14200                 if (dumpAll) {
14201                     pw.println("-------------------------------------------------------------------------------");
14202                 }
14203                 sdumper = mServices.newServiceDumperLocked(fd, pw, args, opti, dumpAll,
14204                         dumpPackage);
14205             }
14206             sdumper.dumpWithClient();
14207             pw.println();
14208             synchronized (this) {
14209                 if (dumpAll) {
14210                     pw.println("-------------------------------------------------------------------------------");
14211                 }
14212                 dumpRecentsLocked(fd, pw, args, opti, dumpAll, dumpPackage);
14213                 pw.println();
14214                 if (dumpAll) {
14215                     pw.println("-------------------------------------------------------------------------------");
14216                 }
14217                 dumpActivitiesLocked(fd, pw, args, opti, dumpAll, dumpClient, dumpPackage);
14218                 if (mAssociations.size() > 0) {
14219                     pw.println();
14220                     if (dumpAll) {
14221                         pw.println("-------------------------------------------------------------------------------");
14222                     }
14223                     dumpAssociationsLocked(fd, pw, args, opti, dumpAll, dumpClient, dumpPackage);
14224                 }
14225                 pw.println();
14226                 if (dumpAll) {
14227                     pw.println("-------------------------------------------------------------------------------");
14228                 }
14229                 dumpProcessesLocked(fd, pw, args, opti, dumpAll, dumpPackage);
14230             }
14231
14232         } else {
14233             synchronized (this) {
14234                 dumpPendingIntentsLocked(fd, pw, args, opti, dumpAll, dumpPackage);
14235                 pw.println();
14236                 if (dumpAll) {
14237                     pw.println("-------------------------------------------------------------------------------");
14238                 }
14239                 dumpBroadcastsLocked(fd, pw, args, opti, dumpAll, dumpPackage);
14240                 pw.println();
14241                 if (dumpAll) {
14242                     pw.println("-------------------------------------------------------------------------------");
14243                 }
14244                 if (dumpAll || dumpPackage != null) {
14245                     dumpBroadcastStatsLocked(fd, pw, args, opti, dumpAll, dumpPackage);
14246                     pw.println();
14247                     if (dumpAll) {
14248                         pw.println("-------------------------------------------------------------------------------");
14249                     }
14250                 }
14251                 dumpProvidersLocked(fd, pw, args, opti, dumpAll, dumpPackage);
14252                 pw.println();
14253                 if (dumpAll) {
14254                     pw.println("-------------------------------------------------------------------------------");
14255                 }
14256                 dumpPermissionsLocked(fd, pw, args, opti, dumpAll, dumpPackage);
14257                 pw.println();
14258                 if (dumpAll) {
14259                     pw.println("-------------------------------------------------------------------------------");
14260                 }
14261                 mServices.newServiceDumperLocked(fd, pw, args, opti, dumpAll, dumpPackage)
14262                         .dumpLocked();
14263                 pw.println();
14264                 if (dumpAll) {
14265                     pw.println("-------------------------------------------------------------------------------");
14266                 }
14267                 dumpRecentsLocked(fd, pw, args, opti, dumpAll, dumpPackage);
14268                 pw.println();
14269                 if (dumpAll) {
14270                     pw.println("-------------------------------------------------------------------------------");
14271                 }
14272                 dumpActivitiesLocked(fd, pw, args, opti, dumpAll, dumpClient, dumpPackage);
14273                 if (mAssociations.size() > 0) {
14274                     pw.println();
14275                     if (dumpAll) {
14276                         pw.println("-------------------------------------------------------------------------------");
14277                     }
14278                     dumpAssociationsLocked(fd, pw, args, opti, dumpAll, dumpClient, dumpPackage);
14279                 }
14280                 pw.println();
14281                 if (dumpAll) {
14282                     pw.println("-------------------------------------------------------------------------------");
14283                 }
14284                 dumpProcessesLocked(fd, pw, args, opti, dumpAll, dumpPackage);
14285             }
14286         }
14287         Binder.restoreCallingIdentity(origId);
14288     }
14289
14290     void dumpActivitiesLocked(FileDescriptor fd, PrintWriter pw, String[] args,
14291             int opti, boolean dumpAll, boolean dumpClient, String dumpPackage) {
14292         pw.println("ACTIVITY MANAGER ACTIVITIES (dumpsys activity activities)");
14293
14294         boolean printedAnything = mStackSupervisor.dumpActivitiesLocked(fd, pw, dumpAll, dumpClient,
14295                 dumpPackage);
14296         boolean needSep = printedAnything;
14297
14298         boolean printed = ActivityStackSupervisor.printThisActivity(pw, mFocusedActivity,
14299                 dumpPackage, needSep, "  mFocusedActivity: ");
14300         if (printed) {
14301             printedAnything = true;
14302             needSep = false;
14303         }
14304
14305         if (dumpPackage == null) {
14306             if (needSep) {
14307                 pw.println();
14308             }
14309             needSep = true;
14310             printedAnything = true;
14311             mStackSupervisor.dump(pw, "  ");
14312         }
14313
14314         if (!printedAnything) {
14315             pw.println("  (nothing)");
14316         }
14317     }
14318
14319     void dumpRecentsLocked(FileDescriptor fd, PrintWriter pw, String[] args,
14320             int opti, boolean dumpAll, String dumpPackage) {
14321         pw.println("ACTIVITY MANAGER RECENT TASKS (dumpsys activity recents)");
14322
14323         boolean printedAnything = false;
14324
14325         if (mRecentTasks != null && mRecentTasks.size() > 0) {
14326             boolean printedHeader = false;
14327
14328             final int N = mRecentTasks.size();
14329             for (int i=0; i<N; i++) {
14330                 TaskRecord tr = mRecentTasks.get(i);
14331                 if (dumpPackage != null) {
14332                     if (tr.realActivity == null ||
14333                             !dumpPackage.equals(tr.realActivity)) {
14334                         continue;
14335                     }
14336                 }
14337                 if (!printedHeader) {
14338                     pw.println("  Recent tasks:");
14339                     printedHeader = true;
14340                     printedAnything = true;
14341                 }
14342                 pw.print("  * Recent #"); pw.print(i); pw.print(": ");
14343                         pw.println(tr);
14344                 if (dumpAll) {
14345                     mRecentTasks.get(i).dump(pw, "    ");
14346                 }
14347             }
14348         }
14349
14350         if (!printedAnything) {
14351             pw.println("  (nothing)");
14352         }
14353     }
14354
14355     void dumpAssociationsLocked(FileDescriptor fd, PrintWriter pw, String[] args,
14356             int opti, boolean dumpAll, boolean dumpClient, String dumpPackage) {
14357         pw.println("ACTIVITY MANAGER ASSOCIATIONS (dumpsys activity associations)");
14358
14359         int dumpUid = 0;
14360         if (dumpPackage != null) {
14361             IPackageManager pm = AppGlobals.getPackageManager();
14362             try {
14363                 dumpUid = pm.getPackageUid(dumpPackage, MATCH_UNINSTALLED_PACKAGES, 0);
14364             } catch (RemoteException e) {
14365             }
14366         }
14367
14368         boolean printedAnything = false;
14369
14370         final long now = SystemClock.uptimeMillis();
14371
14372         for (int i1=0, N1=mAssociations.size(); i1<N1; i1++) {
14373             ArrayMap<ComponentName, SparseArray<ArrayMap<String, Association>>> targetComponents
14374                     = mAssociations.valueAt(i1);
14375             for (int i2=0, N2=targetComponents.size(); i2<N2; i2++) {
14376                 SparseArray<ArrayMap<String, Association>> sourceUids
14377                         = targetComponents.valueAt(i2);
14378                 for (int i3=0, N3=sourceUids.size(); i3<N3; i3++) {
14379                     ArrayMap<String, Association> sourceProcesses = sourceUids.valueAt(i3);
14380                     for (int i4=0, N4=sourceProcesses.size(); i4<N4; i4++) {
14381                         Association ass = sourceProcesses.valueAt(i4);
14382                         if (dumpPackage != null) {
14383                             if (!ass.mTargetComponent.getPackageName().equals(dumpPackage)
14384                                     && UserHandle.getAppId(ass.mSourceUid) != dumpUid) {
14385                                 continue;
14386                             }
14387                         }
14388                         printedAnything = true;
14389                         pw.print("  ");
14390                         pw.print(ass.mTargetProcess);
14391                         pw.print("/");
14392                         UserHandle.formatUid(pw, ass.mTargetUid);
14393                         pw.print(" <- ");
14394                         pw.print(ass.mSourceProcess);
14395                         pw.print("/");
14396                         UserHandle.formatUid(pw, ass.mSourceUid);
14397                         pw.println();
14398                         pw.print("    via ");
14399                         pw.print(ass.mTargetComponent.flattenToShortString());
14400                         pw.println();
14401                         pw.print("    ");
14402                         long dur = ass.mTime;
14403                         if (ass.mNesting > 0) {
14404                             dur += now - ass.mStartTime;
14405                         }
14406                         TimeUtils.formatDuration(dur, pw);
14407                         pw.print(" (");
14408                         pw.print(ass.mCount);
14409                         pw.print(" times)");
14410                         pw.print("  ");
14411                         for (int i=0; i<ass.mStateTimes.length; i++) {
14412                             long amt = ass.mStateTimes[i];
14413                             if (ass.mLastState-ActivityManager.MIN_PROCESS_STATE == i) {
14414                                 amt += now - ass.mLastStateUptime;
14415                             }
14416                             if (amt != 0) {
14417                                 pw.print(" ");
14418                                 pw.print(ProcessList.makeProcStateString(
14419                                             i + ActivityManager.MIN_PROCESS_STATE));
14420                                 pw.print("=");
14421                                 TimeUtils.formatDuration(amt, pw);
14422                                 if (ass.mLastState-ActivityManager.MIN_PROCESS_STATE == i) {
14423                                     pw.print("*");
14424                                 }
14425                             }
14426                         }
14427                         pw.println();
14428                         if (ass.mNesting > 0) {
14429                             pw.print("    Currently active: ");
14430                             TimeUtils.formatDuration(now - ass.mStartTime, pw);
14431                             pw.println();
14432                         }
14433                     }
14434                 }
14435             }
14436
14437         }
14438
14439         if (!printedAnything) {
14440             pw.println("  (nothing)");
14441         }
14442     }
14443
14444     boolean dumpUids(PrintWriter pw, String dumpPackage, SparseArray<UidRecord> uids,
14445             String header, boolean needSep) {
14446         boolean printed = false;
14447         int whichAppId = -1;
14448         if (dumpPackage != null) {
14449             try {
14450                 ApplicationInfo info = mContext.getPackageManager().getApplicationInfo(
14451                         dumpPackage, 0);
14452                 whichAppId = UserHandle.getAppId(info.uid);
14453             } catch (NameNotFoundException e) {
14454                 e.printStackTrace();
14455             }
14456         }
14457         for (int i=0; i<uids.size(); i++) {
14458             UidRecord uidRec = uids.valueAt(i);
14459             if (dumpPackage != null && UserHandle.getAppId(uidRec.uid) != whichAppId) {
14460                 continue;
14461             }
14462             if (!printed) {
14463                 printed = true;
14464                 if (needSep) {
14465                     pw.println();
14466                 }
14467                 pw.print("  ");
14468                 pw.println(header);
14469                 needSep = true;
14470             }
14471             pw.print("    UID "); UserHandle.formatUid(pw, uidRec.uid);
14472             pw.print(": "); pw.println(uidRec);
14473         }
14474         return printed;
14475     }
14476
14477     void dumpProcessesLocked(FileDescriptor fd, PrintWriter pw, String[] args,
14478             int opti, boolean dumpAll, String dumpPackage) {
14479         boolean needSep = false;
14480         boolean printedAnything = false;
14481         int numPers = 0;
14482
14483         pw.println("ACTIVITY MANAGER RUNNING PROCESSES (dumpsys activity processes)");
14484
14485         if (dumpAll) {
14486             final int NP = mProcessNames.getMap().size();
14487             for (int ip=0; ip<NP; ip++) {
14488                 SparseArray<ProcessRecord> procs = mProcessNames.getMap().valueAt(ip);
14489                 final int NA = procs.size();
14490                 for (int ia=0; ia<NA; ia++) {
14491                     ProcessRecord r = procs.valueAt(ia);
14492                     if (dumpPackage != null && !r.pkgList.containsKey(dumpPackage)) {
14493                         continue;
14494                     }
14495                     if (!needSep) {
14496                         pw.println("  All known processes:");
14497                         needSep = true;
14498                         printedAnything = true;
14499                     }
14500                     pw.print(r.persistent ? "  *PERS*" : "  *APP*");
14501                         pw.print(" UID "); pw.print(procs.keyAt(ia));
14502                         pw.print(" "); pw.println(r);
14503                     r.dump(pw, "    ");
14504                     if (r.persistent) {
14505                         numPers++;
14506                     }
14507                 }
14508             }
14509         }
14510
14511         if (mIsolatedProcesses.size() > 0) {
14512             boolean printed = false;
14513             for (int i=0; i<mIsolatedProcesses.size(); i++) {
14514                 ProcessRecord r = mIsolatedProcesses.valueAt(i);
14515                 if (dumpPackage != null && !r.pkgList.containsKey(dumpPackage)) {
14516                     continue;
14517                 }
14518                 if (!printed) {
14519                     if (needSep) {
14520                         pw.println();
14521                     }
14522                     pw.println("  Isolated process list (sorted by uid):");
14523                     printedAnything = true;
14524                     printed = true;
14525                     needSep = true;
14526                 }
14527                 pw.println(String.format("%sIsolated #%2d: %s",
14528                         "    ", i, r.toString()));
14529             }
14530         }
14531
14532         if (mActiveUids.size() > 0) {
14533             if (dumpUids(pw, dumpPackage, mActiveUids, "UID states:", needSep)) {
14534                 printedAnything = needSep = true;
14535             }
14536         }
14537         if (mValidateUids.size() > 0) {
14538             if (dumpUids(pw, dumpPackage, mValidateUids, "UID validation:", needSep)) {
14539                 printedAnything = needSep = true;
14540             }
14541         }
14542
14543         if (mLruProcesses.size() > 0) {
14544             if (needSep) {
14545                 pw.println();
14546             }
14547             pw.print("  Process LRU list (sorted by oom_adj, "); pw.print(mLruProcesses.size());
14548                     pw.print(" total, non-act at ");
14549                     pw.print(mLruProcesses.size()-mLruProcessActivityStart);
14550                     pw.print(", non-svc at ");
14551                     pw.print(mLruProcesses.size()-mLruProcessServiceStart);
14552                     pw.println("):");
14553             dumpProcessOomList(pw, this, mLruProcesses, "    ", "Proc", "PERS", false, dumpPackage);
14554             needSep = true;
14555             printedAnything = true;
14556         }
14557
14558         if (dumpAll || dumpPackage != null) {
14559             synchronized (mPidsSelfLocked) {
14560                 boolean printed = false;
14561                 for (int i=0; i<mPidsSelfLocked.size(); i++) {
14562                     ProcessRecord r = mPidsSelfLocked.valueAt(i);
14563                     if (dumpPackage != null && !r.pkgList.containsKey(dumpPackage)) {
14564                         continue;
14565                     }
14566                     if (!printed) {
14567                         if (needSep) pw.println();
14568                         needSep = true;
14569                         pw.println("  PID mappings:");
14570                         printed = true;
14571                         printedAnything = true;
14572                     }
14573                     pw.print("    PID #"); pw.print(mPidsSelfLocked.keyAt(i));
14574                         pw.print(": "); pw.println(mPidsSelfLocked.valueAt(i));
14575                 }
14576             }
14577         }
14578
14579         if (mForegroundProcesses.size() > 0) {
14580             synchronized (mPidsSelfLocked) {
14581                 boolean printed = false;
14582                 for (int i=0; i<mForegroundProcesses.size(); i++) {
14583                     ProcessRecord r = mPidsSelfLocked.get(
14584                             mForegroundProcesses.valueAt(i).pid);
14585                     if (dumpPackage != null && (r == null
14586                             || !r.pkgList.containsKey(dumpPackage))) {
14587                         continue;
14588                     }
14589                     if (!printed) {
14590                         if (needSep) pw.println();
14591                         needSep = true;
14592                         pw.println("  Foreground Processes:");
14593                         printed = true;
14594                         printedAnything = true;
14595                     }
14596                     pw.print("    PID #"); pw.print(mForegroundProcesses.keyAt(i));
14597                             pw.print(": "); pw.println(mForegroundProcesses.valueAt(i));
14598                 }
14599             }
14600         }
14601
14602         if (mPersistentStartingProcesses.size() > 0) {
14603             if (needSep) pw.println();
14604             needSep = true;
14605             printedAnything = true;
14606             pw.println("  Persisent processes that are starting:");
14607             dumpProcessList(pw, this, mPersistentStartingProcesses, "    ",
14608                     "Starting Norm", "Restarting PERS", dumpPackage);
14609         }
14610
14611         if (mRemovedProcesses.size() > 0) {
14612             if (needSep) pw.println();
14613             needSep = true;
14614             printedAnything = true;
14615             pw.println("  Processes that are being removed:");
14616             dumpProcessList(pw, this, mRemovedProcesses, "    ",
14617                     "Removed Norm", "Removed PERS", dumpPackage);
14618         }
14619
14620         if (mProcessesOnHold.size() > 0) {
14621             if (needSep) pw.println();
14622             needSep = true;
14623             printedAnything = true;
14624             pw.println("  Processes that are on old until the system is ready:");
14625             dumpProcessList(pw, this, mProcessesOnHold, "    ",
14626                     "OnHold Norm", "OnHold PERS", dumpPackage);
14627         }
14628
14629         needSep = dumpProcessesToGc(fd, pw, args, opti, needSep, dumpAll, dumpPackage);
14630
14631         needSep = mAppErrors.dumpLocked(fd, pw, needSep, dumpPackage);
14632         if (needSep) {
14633             printedAnything = true;
14634         }
14635
14636         if (dumpPackage == null) {
14637             pw.println();
14638             needSep = false;
14639             mUserController.dump(pw, dumpAll);
14640         }
14641         if (mHomeProcess != null && (dumpPackage == null
14642                 || mHomeProcess.pkgList.containsKey(dumpPackage))) {
14643             if (needSep) {
14644                 pw.println();
14645                 needSep = false;
14646             }
14647             pw.println("  mHomeProcess: " + mHomeProcess);
14648         }
14649         if (mPreviousProcess != null && (dumpPackage == null
14650                 || mPreviousProcess.pkgList.containsKey(dumpPackage))) {
14651             if (needSep) {
14652                 pw.println();
14653                 needSep = false;
14654             }
14655             pw.println("  mPreviousProcess: " + mPreviousProcess);
14656         }
14657         if (dumpAll) {
14658             StringBuilder sb = new StringBuilder(128);
14659             sb.append("  mPreviousProcessVisibleTime: ");
14660             TimeUtils.formatDuration(mPreviousProcessVisibleTime, sb);
14661             pw.println(sb);
14662         }
14663         if (mHeavyWeightProcess != null && (dumpPackage == null
14664                 || mHeavyWeightProcess.pkgList.containsKey(dumpPackage))) {
14665             if (needSep) {
14666                 pw.println();
14667                 needSep = false;
14668             }
14669             pw.println("  mHeavyWeightProcess: " + mHeavyWeightProcess);
14670         }
14671         if (dumpPackage == null) {
14672             pw.println("  mConfiguration: " + mConfiguration);
14673         }
14674         if (dumpAll) {
14675             pw.println("  mConfigWillChange: " + getFocusedStack().mConfigWillChange);
14676             if (mCompatModePackages.getPackages().size() > 0) {
14677                 boolean printed = false;
14678                 for (Map.Entry<String, Integer> entry
14679                         : mCompatModePackages.getPackages().entrySet()) {
14680                     String pkg = entry.getKey();
14681                     int mode = entry.getValue();
14682                     if (dumpPackage != null && !dumpPackage.equals(pkg)) {
14683                         continue;
14684                     }
14685                     if (!printed) {
14686                         pw.println("  mScreenCompatPackages:");
14687                         printed = true;
14688                     }
14689                     pw.print("    "); pw.print(pkg); pw.print(": ");
14690                             pw.print(mode); pw.println();
14691                 }
14692             }
14693         }
14694         if (dumpPackage == null) {
14695             pw.println("  mWakefulness="
14696                     + PowerManagerInternal.wakefulnessToString(mWakefulness));
14697             pw.println("  mSleepTokens=" + mSleepTokens);
14698             pw.println("  mSleeping=" + mSleeping + " mLockScreenShown="
14699                     + lockScreenShownToString());
14700             pw.println("  mShuttingDown=" + mShuttingDown + " mTestPssMode=" + mTestPssMode);
14701             if (mRunningVoice != null) {
14702                 pw.println("  mRunningVoice=" + mRunningVoice);
14703                 pw.println("  mVoiceWakeLock" + mVoiceWakeLock);
14704             }
14705         }
14706         if (mDebugApp != null || mOrigDebugApp != null || mDebugTransient
14707                 || mOrigWaitForDebugger) {
14708             if (dumpPackage == null || dumpPackage.equals(mDebugApp)
14709                     || dumpPackage.equals(mOrigDebugApp)) {
14710                 if (needSep) {
14711                     pw.println();
14712                     needSep = false;
14713                 }
14714                 pw.println("  mDebugApp=" + mDebugApp + "/orig=" + mOrigDebugApp
14715                         + " mDebugTransient=" + mDebugTransient
14716                         + " mOrigWaitForDebugger=" + mOrigWaitForDebugger);
14717             }
14718         }
14719         if (mCurAppTimeTracker != null) {
14720             mCurAppTimeTracker.dumpWithHeader(pw, "  ", true);
14721         }
14722         if (mMemWatchProcesses.getMap().size() > 0) {
14723             pw.println("  Mem watch processes:");
14724             final ArrayMap<String, SparseArray<Pair<Long, String>>> procs
14725                     = mMemWatchProcesses.getMap();
14726             for (int i=0; i<procs.size(); i++) {
14727                 final String proc = procs.keyAt(i);
14728                 final SparseArray<Pair<Long, String>> uids = procs.valueAt(i);
14729                 for (int j=0; j<uids.size(); j++) {
14730                     if (needSep) {
14731                         pw.println();
14732                         needSep = false;
14733                     }
14734                     StringBuilder sb = new StringBuilder();
14735                     sb.append("    ").append(proc).append('/');
14736                     UserHandle.formatUid(sb, uids.keyAt(j));
14737                     Pair<Long, String> val = uids.valueAt(j);
14738                     sb.append(": "); DebugUtils.sizeValueToString(val.first, sb);
14739                     if (val.second != null) {
14740                         sb.append(", report to ").append(val.second);
14741                     }
14742                     pw.println(sb.toString());
14743                 }
14744             }
14745             pw.print("  mMemWatchDumpProcName="); pw.println(mMemWatchDumpProcName);
14746             pw.print("  mMemWatchDumpFile="); pw.println(mMemWatchDumpFile);
14747             pw.print("  mMemWatchDumpPid="); pw.print(mMemWatchDumpPid);
14748                     pw.print(" mMemWatchDumpUid="); pw.println(mMemWatchDumpUid);
14749         }
14750         if (mTrackAllocationApp != null) {
14751             if (dumpPackage == null || dumpPackage.equals(mTrackAllocationApp)) {
14752                 if (needSep) {
14753                     pw.println();
14754                     needSep = false;
14755                 }
14756                 pw.println("  mTrackAllocationApp=" + mTrackAllocationApp);
14757             }
14758         }
14759         if (mProfileApp != null || mProfileProc != null || mProfileFile != null
14760                 || mProfileFd != null) {
14761             if (dumpPackage == null || dumpPackage.equals(mProfileApp)) {
14762                 if (needSep) {
14763                     pw.println();
14764                     needSep = false;
14765                 }
14766                 pw.println("  mProfileApp=" + mProfileApp + " mProfileProc=" + mProfileProc);
14767                 pw.println("  mProfileFile=" + mProfileFile + " mProfileFd=" + mProfileFd);
14768                 pw.println("  mSamplingInterval=" + mSamplingInterval + " mAutoStopProfiler="
14769                         + mAutoStopProfiler);
14770                 pw.println("  mProfileType=" + mProfileType);
14771             }
14772         }
14773         if (mNativeDebuggingApp != null) {
14774             if (dumpPackage == null || dumpPackage.equals(mNativeDebuggingApp)) {
14775                 if (needSep) {
14776                     pw.println();
14777                     needSep = false;
14778                 }
14779                 pw.println("  mNativeDebuggingApp=" + mNativeDebuggingApp);
14780             }
14781         }
14782         if (dumpPackage == null) {
14783             if (mAlwaysFinishActivities || mLenientBackgroundCheck) {
14784                 pw.println("  mAlwaysFinishActivities=" + mAlwaysFinishActivities
14785                         + " mLenientBackgroundCheck=" + mLenientBackgroundCheck);
14786             }
14787             if (mController != null) {
14788                 pw.println("  mController=" + mController
14789                         + " mControllerIsAMonkey=" + mControllerIsAMonkey);
14790             }
14791             if (dumpAll) {
14792                 pw.println("  Total persistent processes: " + numPers);
14793                 pw.println("  mProcessesReady=" + mProcessesReady
14794                         + " mSystemReady=" + mSystemReady
14795                         + " mBooted=" + mBooted
14796                         + " mFactoryTest=" + mFactoryTest);
14797                 pw.println("  mBooting=" + mBooting
14798                         + " mCallFinishBooting=" + mCallFinishBooting
14799                         + " mBootAnimationComplete=" + mBootAnimationComplete);
14800                 pw.print("  mLastPowerCheckRealtime=");
14801                         TimeUtils.formatDuration(mLastPowerCheckRealtime, pw);
14802                         pw.println("");
14803                 pw.print("  mLastPowerCheckUptime=");
14804                         TimeUtils.formatDuration(mLastPowerCheckUptime, pw);
14805                         pw.println("");
14806                 pw.println("  mGoingToSleep=" + mStackSupervisor.mGoingToSleep);
14807                 pw.println("  mLaunchingActivity=" + mStackSupervisor.mLaunchingActivity);
14808                 pw.println("  mAdjSeq=" + mAdjSeq + " mLruSeq=" + mLruSeq);
14809                 pw.println("  mNumNonCachedProcs=" + mNumNonCachedProcs
14810                         + " (" + mLruProcesses.size() + " total)"
14811                         + " mNumCachedHiddenProcs=" + mNumCachedHiddenProcs
14812                         + " mNumServiceProcs=" + mNumServiceProcs
14813                         + " mNewNumServiceProcs=" + mNewNumServiceProcs);
14814                 pw.println("  mAllowLowerMemLevel=" + mAllowLowerMemLevel
14815                         + " mLastMemoryLevel=" + mLastMemoryLevel
14816                         + " mLastNumProcesses=" + mLastNumProcesses);
14817                 long now = SystemClock.uptimeMillis();
14818                 pw.print("  mLastIdleTime=");
14819                         TimeUtils.formatDuration(now, mLastIdleTime, pw);
14820                         pw.print(" mLowRamSinceLastIdle=");
14821                         TimeUtils.formatDuration(getLowRamTimeSinceIdle(now), pw);
14822                         pw.println();
14823             }
14824         }
14825
14826         if (!printedAnything) {
14827             pw.println("  (nothing)");
14828         }
14829     }
14830
14831     boolean dumpProcessesToGc(FileDescriptor fd, PrintWriter pw, String[] args,
14832             int opti, boolean needSep, boolean dumpAll, String dumpPackage) {
14833         if (mProcessesToGc.size() > 0) {
14834             boolean printed = false;
14835             long now = SystemClock.uptimeMillis();
14836             for (int i=0; i<mProcessesToGc.size(); i++) {
14837                 ProcessRecord proc = mProcessesToGc.get(i);
14838                 if (dumpPackage != null && !dumpPackage.equals(proc.info.packageName)) {
14839                     continue;
14840                 }
14841                 if (!printed) {
14842                     if (needSep) pw.println();
14843                     needSep = true;
14844                     pw.println("  Processes that are waiting to GC:");
14845                     printed = true;
14846                 }
14847                 pw.print("    Process "); pw.println(proc);
14848                 pw.print("      lowMem="); pw.print(proc.reportLowMemory);
14849                         pw.print(", last gced=");
14850                         pw.print(now-proc.lastRequestedGc);
14851                         pw.print(" ms ago, last lowMem=");
14852                         pw.print(now-proc.lastLowMemory);
14853                         pw.println(" ms ago");
14854
14855             }
14856         }
14857         return needSep;
14858     }
14859
14860     void printOomLevel(PrintWriter pw, String name, int adj) {
14861         pw.print("    ");
14862         if (adj >= 0) {
14863             pw.print(' ');
14864             if (adj < 10) pw.print(' ');
14865         } else {
14866             if (adj > -10) pw.print(' ');
14867         }
14868         pw.print(adj);
14869         pw.print(": ");
14870         pw.print(name);
14871         pw.print(" (");
14872         pw.print(stringifySize(mProcessList.getMemLevel(adj), 1024));
14873         pw.println(")");
14874     }
14875
14876     boolean dumpOomLocked(FileDescriptor fd, PrintWriter pw, String[] args,
14877             int opti, boolean dumpAll) {
14878         boolean needSep = false;
14879
14880         if (mLruProcesses.size() > 0) {
14881             if (needSep) pw.println();
14882             needSep = true;
14883             pw.println("  OOM levels:");
14884             printOomLevel(pw, "SYSTEM_ADJ", ProcessList.SYSTEM_ADJ);
14885             printOomLevel(pw, "PERSISTENT_PROC_ADJ", ProcessList.PERSISTENT_PROC_ADJ);
14886             printOomLevel(pw, "PERSISTENT_SERVICE_ADJ", ProcessList.PERSISTENT_SERVICE_ADJ);
14887             printOomLevel(pw, "FOREGROUND_APP_ADJ", ProcessList.FOREGROUND_APP_ADJ);
14888             printOomLevel(pw, "VISIBLE_APP_ADJ", ProcessList.VISIBLE_APP_ADJ);
14889             printOomLevel(pw, "PERCEPTIBLE_APP_ADJ", ProcessList.PERCEPTIBLE_APP_ADJ);
14890             printOomLevel(pw, "BACKUP_APP_ADJ", ProcessList.BACKUP_APP_ADJ);
14891             printOomLevel(pw, "HEAVY_WEIGHT_APP_ADJ", ProcessList.HEAVY_WEIGHT_APP_ADJ);
14892             printOomLevel(pw, "SERVICE_ADJ", ProcessList.SERVICE_ADJ);
14893             printOomLevel(pw, "HOME_APP_ADJ", ProcessList.HOME_APP_ADJ);
14894             printOomLevel(pw, "PREVIOUS_APP_ADJ", ProcessList.PREVIOUS_APP_ADJ);
14895             printOomLevel(pw, "SERVICE_B_ADJ", ProcessList.SERVICE_B_ADJ);
14896             printOomLevel(pw, "CACHED_APP_MIN_ADJ", ProcessList.CACHED_APP_MIN_ADJ);
14897             printOomLevel(pw, "CACHED_APP_MAX_ADJ", ProcessList.CACHED_APP_MAX_ADJ);
14898
14899             if (needSep) pw.println();
14900             pw.print("  Process OOM control ("); pw.print(mLruProcesses.size());
14901                     pw.print(" total, non-act at ");
14902                     pw.print(mLruProcesses.size()-mLruProcessActivityStart);
14903                     pw.print(", non-svc at ");
14904                     pw.print(mLruProcesses.size()-mLruProcessServiceStart);
14905                     pw.println("):");
14906             dumpProcessOomList(pw, this, mLruProcesses, "    ", "Proc", "PERS", true, null);
14907             needSep = true;
14908         }
14909
14910         dumpProcessesToGc(fd, pw, args, opti, needSep, dumpAll, null);
14911
14912         pw.println();
14913         pw.println("  mHomeProcess: " + mHomeProcess);
14914         pw.println("  mPreviousProcess: " + mPreviousProcess);
14915         if (mHeavyWeightProcess != null) {
14916             pw.println("  mHeavyWeightProcess: " + mHeavyWeightProcess);
14917         }
14918
14919         return true;
14920     }
14921
14922     /**
14923      * There are three ways to call this:
14924      *  - no provider specified: dump all the providers
14925      *  - a flattened component name that matched an existing provider was specified as the
14926      *    first arg: dump that one provider
14927      *  - the first arg isn't the flattened component name of an existing provider:
14928      *    dump all providers whose component contains the first arg as a substring
14929      */
14930     protected boolean dumpProvider(FileDescriptor fd, PrintWriter pw, String name, String[] args,
14931             int opti, boolean dumpAll) {
14932         return mProviderMap.dumpProvider(fd, pw, name, args, opti, dumpAll);
14933     }
14934
14935     static class ItemMatcher {
14936         ArrayList<ComponentName> components;
14937         ArrayList<String> strings;
14938         ArrayList<Integer> objects;
14939         boolean all;
14940
14941         ItemMatcher() {
14942             all = true;
14943         }
14944
14945         void build(String name) {
14946             ComponentName componentName = ComponentName.unflattenFromString(name);
14947             if (componentName != null) {
14948                 if (components == null) {
14949                     components = new ArrayList<ComponentName>();
14950                 }
14951                 components.add(componentName);
14952                 all = false;
14953             } else {
14954                 int objectId = 0;
14955                 // Not a '/' separated full component name; maybe an object ID?
14956                 try {
14957                     objectId = Integer.parseInt(name, 16);
14958                     if (objects == null) {
14959                         objects = new ArrayList<Integer>();
14960                     }
14961                     objects.add(objectId);
14962                     all = false;
14963                 } catch (RuntimeException e) {
14964                     // Not an integer; just do string match.
14965                     if (strings == null) {
14966                         strings = new ArrayList<String>();
14967                     }
14968                     strings.add(name);
14969                     all = false;
14970                 }
14971             }
14972         }
14973
14974         int build(String[] args, int opti) {
14975             for (; opti<args.length; opti++) {
14976                 String name = args[opti];
14977                 if ("--".equals(name)) {
14978                     return opti+1;
14979                 }
14980                 build(name);
14981             }
14982             return opti;
14983         }
14984
14985         boolean match(Object object, ComponentName comp) {
14986             if (all) {
14987                 return true;
14988             }
14989             if (components != null) {
14990                 for (int i=0; i<components.size(); i++) {
14991                     if (components.get(i).equals(comp)) {
14992                         return true;
14993                     }
14994                 }
14995             }
14996             if (objects != null) {
14997                 for (int i=0; i<objects.size(); i++) {
14998                     if (System.identityHashCode(object) == objects.get(i)) {
14999                         return true;
15000                     }
15001                 }
15002             }
15003             if (strings != null) {
15004                 String flat = comp.flattenToString();
15005                 for (int i=0; i<strings.size(); i++) {
15006                     if (flat.contains(strings.get(i))) {
15007                         return true;
15008                     }
15009                 }
15010             }
15011             return false;
15012         }
15013     }
15014
15015     /**
15016      * There are three things that cmd can be:
15017      *  - a flattened component name that matches an existing activity
15018      *  - the cmd arg isn't the flattened component name of an existing activity:
15019      *    dump all activity whose component contains the cmd as a substring
15020      *  - A hex number of the ActivityRecord object instance.
15021      */
15022     protected boolean dumpActivity(FileDescriptor fd, PrintWriter pw, String name, String[] args,
15023             int opti, boolean dumpAll) {
15024         ArrayList<ActivityRecord> activities;
15025
15026         synchronized (this) {
15027             activities = mStackSupervisor.getDumpActivitiesLocked(name);
15028         }
15029
15030         if (activities.size() <= 0) {
15031             return false;
15032         }
15033
15034         String[] newArgs = new String[args.length - opti];
15035         System.arraycopy(args, opti, newArgs, 0, args.length - opti);
15036
15037         TaskRecord lastTask = null;
15038         boolean needSep = false;
15039         for (int i=activities.size()-1; i>=0; i--) {
15040             ActivityRecord r = activities.get(i);
15041             if (needSep) {
15042                 pw.println();
15043             }
15044             needSep = true;
15045             synchronized (this) {
15046                 if (lastTask != r.task) {
15047                     lastTask = r.task;
15048                     pw.print("TASK "); pw.print(lastTask.affinity);
15049                             pw.print(" id="); pw.println(lastTask.taskId);
15050                     if (dumpAll) {
15051                         lastTask.dump(pw, "  ");
15052                     }
15053                 }
15054             }
15055             dumpActivity("  ", fd, pw, activities.get(i), newArgs, dumpAll);
15056         }
15057         return true;
15058     }
15059
15060     /**
15061      * Invokes IApplicationThread.dumpActivity() on the thread of the specified activity if
15062      * there is a thread associated with the activity.
15063      */
15064     private void dumpActivity(String prefix, FileDescriptor fd, PrintWriter pw,
15065             final ActivityRecord r, String[] args, boolean dumpAll) {
15066         String innerPrefix = prefix + "  ";
15067         synchronized (this) {
15068             pw.print(prefix); pw.print("ACTIVITY "); pw.print(r.shortComponentName);
15069                     pw.print(" "); pw.print(Integer.toHexString(System.identityHashCode(r)));
15070                     pw.print(" pid=");
15071                     if (r.app != null) pw.println(r.app.pid);
15072                     else pw.println("(not running)");
15073             if (dumpAll) {
15074                 r.dump(pw, innerPrefix);
15075             }
15076         }
15077         if (r.app != null && r.app.thread != null) {
15078             // flush anything that is already in the PrintWriter since the thread is going
15079             // to write to the file descriptor directly
15080             pw.flush();
15081             try {
15082                 TransferPipe tp = new TransferPipe();
15083                 try {
15084                     r.app.thread.dumpActivity(tp.getWriteFd().getFileDescriptor(),
15085                             r.appToken, innerPrefix, args);
15086                     tp.go(fd);
15087                 } finally {
15088                     tp.kill();
15089                 }
15090             } catch (IOException e) {
15091                 pw.println(innerPrefix + "Failure while dumping the activity: " + e);
15092             } catch (RemoteException e) {
15093                 pw.println(innerPrefix + "Got a RemoteException while dumping the activity");
15094             }
15095         }
15096     }
15097
15098     void dumpBroadcastsLocked(FileDescriptor fd, PrintWriter pw, String[] args,
15099             int opti, boolean dumpAll, String dumpPackage) {
15100         boolean needSep = false;
15101         boolean onlyHistory = false;
15102         boolean printedAnything = false;
15103
15104         if ("history".equals(dumpPackage)) {
15105             if (opti < args.length && "-s".equals(args[opti])) {
15106                 dumpAll = false;
15107             }
15108             onlyHistory = true;
15109             dumpPackage = null;
15110         }
15111
15112         pw.println("ACTIVITY MANAGER BROADCAST STATE (dumpsys activity broadcasts)");
15113         if (!onlyHistory && dumpAll) {
15114             if (mRegisteredReceivers.size() > 0) {
15115                 boolean printed = false;
15116                 Iterator it = mRegisteredReceivers.values().iterator();
15117                 while (it.hasNext()) {
15118                     ReceiverList r = (ReceiverList)it.next();
15119                     if (dumpPackage != null && (r.app == null ||
15120                             !dumpPackage.equals(r.app.info.packageName))) {
15121                         continue;
15122                     }
15123                     if (!printed) {
15124                         pw.println("  Registered Receivers:");
15125                         needSep = true;
15126                         printed = true;
15127                         printedAnything = true;
15128                     }
15129                     pw.print("  * "); pw.println(r);
15130                     r.dump(pw, "    ");
15131                 }
15132             }
15133
15134             if (mReceiverResolver.dump(pw, needSep ?
15135                     "\n  Receiver Resolver Table:" : "  Receiver Resolver Table:",
15136                     "    ", dumpPackage, false, false)) {
15137                 needSep = true;
15138                 printedAnything = true;
15139             }
15140         }
15141
15142         for (BroadcastQueue q : mBroadcastQueues) {
15143             needSep = q.dumpLocked(fd, pw, args, opti, dumpAll, dumpPackage, needSep);
15144             printedAnything |= needSep;
15145         }
15146
15147         needSep = true;
15148
15149         if (!onlyHistory && mStickyBroadcasts != null && dumpPackage == null) {
15150             for (int user=0; user<mStickyBroadcasts.size(); user++) {
15151                 if (needSep) {
15152                     pw.println();
15153                 }
15154                 needSep = true;
15155                 printedAnything = true;
15156                 pw.print("  Sticky broadcasts for user ");
15157                         pw.print(mStickyBroadcasts.keyAt(user)); pw.println(":");
15158                 StringBuilder sb = new StringBuilder(128);
15159                 for (Map.Entry<String, ArrayList<Intent>> ent
15160                         : mStickyBroadcasts.valueAt(user).entrySet()) {
15161                     pw.print("  * Sticky action "); pw.print(ent.getKey());
15162                     if (dumpAll) {
15163                         pw.println(":");
15164                         ArrayList<Intent> intents = ent.getValue();
15165                         final int N = intents.size();
15166                         for (int i=0; i<N; i++) {
15167                             sb.setLength(0);
15168                             sb.append("    Intent: ");
15169                             intents.get(i).toShortString(sb, false, true, false, false);
15170                             pw.println(sb.toString());
15171                             Bundle bundle = intents.get(i).getExtras();
15172                             if (bundle != null) {
15173                                 pw.print("      ");
15174                                 pw.println(bundle.toString());
15175                             }
15176                         }
15177                     } else {
15178                         pw.println("");
15179                     }
15180                 }
15181             }
15182         }
15183
15184         if (!onlyHistory && dumpAll) {
15185             pw.println();
15186             for (BroadcastQueue queue : mBroadcastQueues) {
15187                 pw.println("  mBroadcastsScheduled [" + queue.mQueueName + "]="
15188                         + queue.mBroadcastsScheduled);
15189             }
15190             pw.println("  mHandler:");
15191             mHandler.dump(new PrintWriterPrinter(pw), "    ");
15192             needSep = true;
15193             printedAnything = true;
15194         }
15195
15196         if (!printedAnything) {
15197             pw.println("  (nothing)");
15198         }
15199     }
15200
15201     void dumpBroadcastStatsLocked(FileDescriptor fd, PrintWriter pw, String[] args,
15202             int opti, boolean dumpAll, String dumpPackage) {
15203         if (mCurBroadcastStats == null) {
15204             return;
15205         }
15206
15207         pw.println("ACTIVITY MANAGER BROADCAST STATS STATE (dumpsys activity broadcast-stats)");
15208         final long now = SystemClock.elapsedRealtime();
15209         if (mLastBroadcastStats != null) {
15210             pw.print("  Last stats (from ");
15211             TimeUtils.formatDuration(mLastBroadcastStats.mStartRealtime, now, pw);
15212             pw.print(" to ");
15213             TimeUtils.formatDuration(mLastBroadcastStats.mEndRealtime, now, pw);
15214             pw.print(", ");
15215             TimeUtils.formatDuration(mLastBroadcastStats.mEndUptime
15216                     - mLastBroadcastStats.mStartUptime, pw);
15217             pw.println(" uptime):");
15218             if (!mLastBroadcastStats.dumpStats(pw, "    ", dumpPackage)) {
15219                 pw.println("    (nothing)");
15220             }
15221             pw.println();
15222         }
15223         pw.print("  Current stats (from ");
15224         TimeUtils.formatDuration(mCurBroadcastStats.mStartRealtime, now, pw);
15225         pw.print(" to now, ");
15226         TimeUtils.formatDuration(SystemClock.uptimeMillis()
15227                 - mCurBroadcastStats.mStartUptime, pw);
15228         pw.println(" uptime):");
15229         if (!mCurBroadcastStats.dumpStats(pw, "    ", dumpPackage)) {
15230             pw.println("    (nothing)");
15231         }
15232     }
15233
15234     void dumpBroadcastStatsCheckinLocked(FileDescriptor fd, PrintWriter pw, String[] args,
15235             int opti, boolean fullCheckin, String dumpPackage) {
15236         if (mCurBroadcastStats == null) {
15237             return;
15238         }
15239
15240         if (mLastBroadcastStats != null) {
15241             mLastBroadcastStats.dumpCheckinStats(pw, dumpPackage);
15242             if (fullCheckin) {
15243                 mLastBroadcastStats = null;
15244                 return;
15245             }
15246         }
15247         mCurBroadcastStats.dumpCheckinStats(pw, dumpPackage);
15248         if (fullCheckin) {
15249             mCurBroadcastStats = null;
15250         }
15251     }
15252
15253     void dumpProvidersLocked(FileDescriptor fd, PrintWriter pw, String[] args,
15254             int opti, boolean dumpAll, String dumpPackage) {
15255         boolean needSep;
15256         boolean printedAnything = false;
15257
15258         ItemMatcher matcher = new ItemMatcher();
15259         matcher.build(args, opti);
15260
15261         pw.println("ACTIVITY MANAGER CONTENT PROVIDERS (dumpsys activity providers)");
15262
15263         needSep = mProviderMap.dumpProvidersLocked(pw, dumpAll, dumpPackage);
15264         printedAnything |= needSep;
15265
15266         if (mLaunchingProviders.size() > 0) {
15267             boolean printed = false;
15268             for (int i=mLaunchingProviders.size()-1; i>=0; i--) {
15269                 ContentProviderRecord r = mLaunchingProviders.get(i);
15270                 if (dumpPackage != null && !dumpPackage.equals(r.name.getPackageName())) {
15271                     continue;
15272                 }
15273                 if (!printed) {
15274                     if (needSep) pw.println();
15275                     needSep = true;
15276                     pw.println("  Launching content providers:");
15277                     printed = true;
15278                     printedAnything = true;
15279                 }
15280                 pw.print("  Launching #"); pw.print(i); pw.print(": ");
15281                         pw.println(r);
15282             }
15283         }
15284
15285         if (!printedAnything) {
15286             pw.println("  (nothing)");
15287         }
15288     }
15289
15290     void dumpPermissionsLocked(FileDescriptor fd, PrintWriter pw, String[] args,
15291             int opti, boolean dumpAll, String dumpPackage) {
15292         boolean needSep = false;
15293         boolean printedAnything = false;
15294
15295         pw.println("ACTIVITY MANAGER URI PERMISSIONS (dumpsys activity permissions)");
15296
15297         if (mGrantedUriPermissions.size() > 0) {
15298             boolean printed = false;
15299             int dumpUid = -2;
15300             if (dumpPackage != null) {
15301                 try {
15302                     dumpUid = mContext.getPackageManager().getPackageUidAsUser(dumpPackage,
15303                             MATCH_UNINSTALLED_PACKAGES, 0);
15304                 } catch (NameNotFoundException e) {
15305                     dumpUid = -1;
15306                 }
15307             }
15308             for (int i=0; i<mGrantedUriPermissions.size(); i++) {
15309                 int uid = mGrantedUriPermissions.keyAt(i);
15310                 if (dumpUid >= -1 && UserHandle.getAppId(uid) != dumpUid) {
15311                     continue;
15312                 }
15313                 final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.valueAt(i);
15314                 if (!printed) {
15315                     if (needSep) pw.println();
15316                     needSep = true;
15317                     pw.println("  Granted Uri Permissions:");
15318                     printed = true;
15319                     printedAnything = true;
15320                 }
15321                 pw.print("  * UID "); pw.print(uid); pw.println(" holds:");
15322                 for (UriPermission perm : perms.values()) {
15323                     pw.print("    "); pw.println(perm);
15324                     if (dumpAll) {
15325                         perm.dump(pw, "      ");
15326                     }
15327                 }
15328             }
15329         }
15330
15331         if (!printedAnything) {
15332             pw.println("  (nothing)");
15333         }
15334     }
15335
15336     void dumpPendingIntentsLocked(FileDescriptor fd, PrintWriter pw, String[] args,
15337             int opti, boolean dumpAll, String dumpPackage) {
15338         boolean printed = false;
15339
15340         pw.println("ACTIVITY MANAGER PENDING INTENTS (dumpsys activity intents)");
15341
15342         if (mIntentSenderRecords.size() > 0) {
15343             Iterator<WeakReference<PendingIntentRecord>> it
15344                     = mIntentSenderRecords.values().iterator();
15345             while (it.hasNext()) {
15346                 WeakReference<PendingIntentRecord> ref = it.next();
15347                 PendingIntentRecord rec = ref != null ? ref.get(): null;
15348                 if (dumpPackage != null && (rec == null
15349                         || !dumpPackage.equals(rec.key.packageName))) {
15350                     continue;
15351                 }
15352                 printed = true;
15353                 if (rec != null) {
15354                     pw.print("  * "); pw.println(rec);
15355                     if (dumpAll) {
15356                         rec.dump(pw, "    ");
15357                     }
15358                 } else {
15359                     pw.print("  * "); pw.println(ref);
15360                 }
15361             }
15362         }
15363
15364         if (!printed) {
15365             pw.println("  (nothing)");
15366         }
15367     }
15368
15369     private static final int dumpProcessList(PrintWriter pw,
15370             ActivityManagerService service, List list,
15371             String prefix, String normalLabel, String persistentLabel,
15372             String dumpPackage) {
15373         int numPers = 0;
15374         final int N = list.size()-1;
15375         for (int i=N; i>=0; i--) {
15376             ProcessRecord r = (ProcessRecord)list.get(i);
15377             if (dumpPackage != null && !dumpPackage.equals(r.info.packageName)) {
15378                 continue;
15379             }
15380             pw.println(String.format("%s%s #%2d: %s",
15381                     prefix, (r.persistent ? persistentLabel : normalLabel),
15382                     i, r.toString()));
15383             if (r.persistent) {
15384                 numPers++;
15385             }
15386         }
15387         return numPers;
15388     }
15389
15390     private static final boolean dumpProcessOomList(PrintWriter pw,
15391             ActivityManagerService service, List<ProcessRecord> origList,
15392             String prefix, String normalLabel, String persistentLabel,
15393             boolean inclDetails, String dumpPackage) {
15394
15395         ArrayList<Pair<ProcessRecord, Integer>> list
15396                 = new ArrayList<Pair<ProcessRecord, Integer>>(origList.size());
15397         for (int i=0; i<origList.size(); i++) {
15398             ProcessRecord r = origList.get(i);
15399             if (dumpPackage != null && !r.pkgList.containsKey(dumpPackage)) {
15400                 continue;
15401             }
15402             list.add(new Pair<ProcessRecord, Integer>(origList.get(i), i));
15403         }
15404
15405         if (list.size() <= 0) {
15406             return false;
15407         }
15408
15409         Comparator<Pair<ProcessRecord, Integer>> comparator
15410                 = new Comparator<Pair<ProcessRecord, Integer>>() {
15411             @Override
15412             public int compare(Pair<ProcessRecord, Integer> object1,
15413                     Pair<ProcessRecord, Integer> object2) {
15414                 if (object1.first.setAdj != object2.first.setAdj) {
15415                     return object1.first.setAdj > object2.first.setAdj ? -1 : 1;
15416                 }
15417                 if (object1.first.setProcState != object2.first.setProcState) {
15418                     return object1.first.setProcState > object2.first.setProcState ? -1 : 1;
15419                 }
15420                 if (object1.second.intValue() != object2.second.intValue()) {
15421                     return object1.second.intValue() > object2.second.intValue() ? -1 : 1;
15422                 }
15423                 return 0;
15424             }
15425         };
15426
15427         Collections.sort(list, comparator);
15428
15429         final long curRealtime = SystemClock.elapsedRealtime();
15430         final long realtimeSince = curRealtime - service.mLastPowerCheckRealtime;
15431         final long curUptime = SystemClock.uptimeMillis();
15432         final long uptimeSince = curUptime - service.mLastPowerCheckUptime;
15433
15434         for (int i=list.size()-1; i>=0; i--) {
15435             ProcessRecord r = list.get(i).first;
15436             String oomAdj = ProcessList.makeOomAdjString(r.setAdj);
15437             char schedGroup;
15438             switch (r.setSchedGroup) {
15439                 case ProcessList.SCHED_GROUP_BACKGROUND:
15440                     schedGroup = 'B';
15441                     break;
15442                 case ProcessList.SCHED_GROUP_DEFAULT:
15443                     schedGroup = 'F';
15444                     break;
15445                 case ProcessList.SCHED_GROUP_TOP_APP:
15446                     schedGroup = 'T';
15447                     break;
15448                 default:
15449                     schedGroup = '?';
15450                     break;
15451             }
15452             char foreground;
15453             if (r.foregroundActivities) {
15454                 foreground = 'A';
15455             } else if (r.foregroundServices) {
15456                 foreground = 'S';
15457             } else {
15458                 foreground = ' ';
15459             }
15460             String procState = ProcessList.makeProcStateString(r.curProcState);
15461             pw.print(prefix);
15462             pw.print(r.persistent ? persistentLabel : normalLabel);
15463             pw.print(" #");
15464             int num = (origList.size()-1)-list.get(i).second;
15465             if (num < 10) pw.print(' ');
15466             pw.print(num);
15467             pw.print(": ");
15468             pw.print(oomAdj);
15469             pw.print(' ');
15470             pw.print(schedGroup);
15471             pw.print('/');
15472             pw.print(foreground);
15473             pw.print('/');
15474             pw.print(procState);
15475             pw.print(" trm:");
15476             if (r.trimMemoryLevel < 10) pw.print(' ');
15477             pw.print(r.trimMemoryLevel);
15478             pw.print(' ');
15479             pw.print(r.toShortString());
15480             pw.print(" (");
15481             pw.print(r.adjType);
15482             pw.println(')');
15483             if (r.adjSource != null || r.adjTarget != null) {
15484                 pw.print(prefix);
15485                 pw.print("    ");
15486                 if (r.adjTarget instanceof ComponentName) {
15487                     pw.print(((ComponentName)r.adjTarget).flattenToShortString());
15488                 } else if (r.adjTarget != null) {
15489                     pw.print(r.adjTarget.toString());
15490                 } else {
15491                     pw.print("{null}");
15492                 }
15493                 pw.print("<=");
15494                 if (r.adjSource instanceof ProcessRecord) {
15495                     pw.print("Proc{");
15496                     pw.print(((ProcessRecord)r.adjSource).toShortString());
15497                     pw.println("}");
15498                 } else if (r.adjSource != null) {
15499                     pw.println(r.adjSource.toString());
15500                 } else {
15501                     pw.println("{null}");
15502                 }
15503             }
15504             if (inclDetails) {
15505                 pw.print(prefix);
15506                 pw.print("    ");
15507                 pw.print("oom: max="); pw.print(r.maxAdj);
15508                 pw.print(" curRaw="); pw.print(r.curRawAdj);
15509                 pw.print(" setRaw="); pw.print(r.setRawAdj);
15510                 pw.print(" cur="); pw.print(r.curAdj);
15511                 pw.print(" set="); pw.println(r.setAdj);
15512                 pw.print(prefix);
15513                 pw.print("    ");
15514                 pw.print("state: cur="); pw.print(ProcessList.makeProcStateString(r.curProcState));
15515                 pw.print(" set="); pw.print(ProcessList.makeProcStateString(r.setProcState));
15516                 pw.print(" lastPss="); DebugUtils.printSizeValue(pw, r.lastPss*1024);
15517                 pw.print(" lastSwapPss="); DebugUtils.printSizeValue(pw, r.lastSwapPss*1024);
15518                 pw.print(" lastCachedPss="); DebugUtils.printSizeValue(pw, r.lastCachedPss*1024);
15519                 pw.println();
15520                 pw.print(prefix);
15521                 pw.print("    ");
15522                 pw.print("cached="); pw.print(r.cached);
15523                 pw.print(" empty="); pw.print(r.empty);
15524                 pw.print(" hasAboveClient="); pw.println(r.hasAboveClient);
15525
15526                 if (r.setProcState >= ActivityManager.PROCESS_STATE_SERVICE) {
15527                     if (r.lastWakeTime != 0) {
15528                         long wtime;
15529                         BatteryStatsImpl stats = service.mBatteryStatsService.getActiveStatistics();
15530                         synchronized (stats) {
15531                             wtime = stats.getProcessWakeTime(r.info.uid,
15532                                     r.pid, curRealtime);
15533                         }
15534                         long timeUsed = wtime - r.lastWakeTime;
15535                         pw.print(prefix);
15536                         pw.print("    ");
15537                         pw.print("keep awake over ");
15538                         TimeUtils.formatDuration(realtimeSince, pw);
15539                         pw.print(" used ");
15540                         TimeUtils.formatDuration(timeUsed, pw);
15541                         pw.print(" (");
15542                         pw.print((timeUsed*100)/realtimeSince);
15543                         pw.println("%)");
15544                     }
15545                     if (r.lastCpuTime != 0) {
15546                         long timeUsed = r.curCpuTime - r.lastCpuTime;
15547                         pw.print(prefix);
15548                         pw.print("    ");
15549                         pw.print("run cpu over ");
15550                         TimeUtils.formatDuration(uptimeSince, pw);
15551                         pw.print(" used ");
15552                         TimeUtils.formatDuration(timeUsed, pw);
15553                         pw.print(" (");
15554                         pw.print((timeUsed*100)/uptimeSince);
15555                         pw.println("%)");
15556                     }
15557                 }
15558             }
15559         }
15560         return true;
15561     }
15562
15563     ArrayList<ProcessRecord> collectProcesses(PrintWriter pw, int start, boolean allPkgs,
15564             String[] args) {
15565         ArrayList<ProcessRecord> procs;
15566         synchronized (this) {
15567             if (args != null && args.length > start
15568                     && args[start].charAt(0) != '-') {
15569                 procs = new ArrayList<ProcessRecord>();
15570                 int pid = -1;
15571                 try {
15572                     pid = Integer.parseInt(args[start]);
15573                 } catch (NumberFormatException e) {
15574                 }
15575                 for (int i=mLruProcesses.size()-1; i>=0; i--) {
15576                     ProcessRecord proc = mLruProcesses.get(i);
15577                     if (proc.pid == pid) {
15578                         procs.add(proc);
15579                     } else if (allPkgs && proc.pkgList != null
15580                             && proc.pkgList.containsKey(args[start])) {
15581                         procs.add(proc);
15582                     } else if (proc.processName.equals(args[start])) {
15583                         procs.add(proc);
15584                     }
15585                 }
15586                 if (procs.size() <= 0) {
15587                     return null;
15588                 }
15589             } else {
15590                 procs = new ArrayList<ProcessRecord>(mLruProcesses);
15591             }
15592         }
15593         return procs;
15594     }
15595
15596     final void dumpGraphicsHardwareUsage(FileDescriptor fd,
15597             PrintWriter pw, String[] args) {
15598         ArrayList<ProcessRecord> procs = collectProcesses(pw, 0, false, args);
15599         if (procs == null) {
15600             pw.println("No process found for: " + args[0]);
15601             return;
15602         }
15603
15604         long uptime = SystemClock.uptimeMillis();
15605         long realtime = SystemClock.elapsedRealtime();
15606         pw.println("Applications Graphics Acceleration Info:");
15607         pw.println("Uptime: " + uptime + " Realtime: " + realtime);
15608
15609         for (int i = procs.size() - 1 ; i >= 0 ; i--) {
15610             ProcessRecord r = procs.get(i);
15611             if (r.thread != null) {
15612                 pw.println("\n** Graphics info for pid " + r.pid + " [" + r.processName + "] **");
15613                 pw.flush();
15614                 try {
15615                     TransferPipe tp = new TransferPipe();
15616                     try {
15617                         r.thread.dumpGfxInfo(tp.getWriteFd().getFileDescriptor(), args);
15618                         tp.go(fd);
15619                     } finally {
15620                         tp.kill();
15621                     }
15622                 } catch (IOException e) {
15623                     pw.println("Failure while dumping the app: " + r);
15624                     pw.flush();
15625                 } catch (RemoteException e) {
15626                     pw.println("Got a RemoteException while dumping the app " + r);
15627                     pw.flush();
15628                 }
15629             }
15630         }
15631     }
15632
15633     final void dumpDbInfo(FileDescriptor fd, PrintWriter pw, String[] args) {
15634         ArrayList<ProcessRecord> procs = collectProcesses(pw, 0, false, args);
15635         if (procs == null) {
15636             pw.println("No process found for: " + args[0]);
15637             return;
15638         }
15639
15640         pw.println("Applications Database Info:");
15641
15642         for (int i = procs.size() - 1 ; i >= 0 ; i--) {
15643             ProcessRecord r = procs.get(i);
15644             if (r.thread != null) {
15645                 pw.println("\n** Database info for pid " + r.pid + " [" + r.processName + "] **");
15646                 pw.flush();
15647                 try {
15648                     TransferPipe tp = new TransferPipe();
15649                     try {
15650                         r.thread.dumpDbInfo(tp.getWriteFd().getFileDescriptor(), args);
15651                         tp.go(fd);
15652                     } finally {
15653                         tp.kill();
15654                     }
15655                 } catch (IOException e) {
15656                     pw.println("Failure while dumping the app: " + r);
15657                     pw.flush();
15658                 } catch (RemoteException e) {
15659                     pw.println("Got a RemoteException while dumping the app " + r);
15660                     pw.flush();
15661                 }
15662             }
15663         }
15664     }
15665
15666     final static class MemItem {
15667         final boolean isProc;
15668         final String label;
15669         final String shortLabel;
15670         final long pss;
15671         final long swapPss;
15672         final int id;
15673         final boolean hasActivities;
15674         ArrayList<MemItem> subitems;
15675
15676         public MemItem(String _label, String _shortLabel, long _pss, long _swapPss, int _id,
15677                 boolean _hasActivities) {
15678             isProc = true;
15679             label = _label;
15680             shortLabel = _shortLabel;
15681             pss = _pss;
15682             swapPss = _swapPss;
15683             id = _id;
15684             hasActivities = _hasActivities;
15685         }
15686
15687         public MemItem(String _label, String _shortLabel, long _pss, long _swapPss, int _id) {
15688             isProc = false;
15689             label = _label;
15690             shortLabel = _shortLabel;
15691             pss = _pss;
15692             swapPss = _swapPss;
15693             id = _id;
15694             hasActivities = false;
15695         }
15696     }
15697
15698     static final void dumpMemItems(PrintWriter pw, String prefix, String tag,
15699             ArrayList<MemItem> items, boolean sort, boolean isCompact, boolean dumpSwapPss) {
15700         if (sort && !isCompact) {
15701             Collections.sort(items, new Comparator<MemItem>() {
15702                 @Override
15703                 public int compare(MemItem lhs, MemItem rhs) {
15704                     if (lhs.pss < rhs.pss) {
15705                         return 1;
15706                     } else if (lhs.pss > rhs.pss) {
15707                         return -1;
15708                     }
15709                     return 0;
15710                 }
15711             });
15712         }
15713
15714         for (int i=0; i<items.size(); i++) {
15715             MemItem mi = items.get(i);
15716             if (!isCompact) {
15717                 if (dumpSwapPss) {
15718                     pw.printf("%s%s: %-60s (%s in swap)\n", prefix, stringifyKBSize(mi.pss),
15719                             mi.label, stringifyKBSize(mi.swapPss));
15720                 } else {
15721                     pw.printf("%s%s: %s\n", prefix, stringifyKBSize(mi.pss), mi.label);
15722                 }
15723             } else if (mi.isProc) {
15724                 pw.print("proc,"); pw.print(tag); pw.print(","); pw.print(mi.shortLabel);
15725                 pw.print(","); pw.print(mi.id); pw.print(","); pw.print(mi.pss); pw.print(",");
15726                 pw.print(dumpSwapPss ? mi.swapPss : "N/A");
15727                 pw.println(mi.hasActivities ? ",a" : ",e");
15728             } else {
15729                 pw.print(tag); pw.print(","); pw.print(mi.shortLabel); pw.print(",");
15730                 pw.print(mi.pss); pw.print(","); pw.println(dumpSwapPss ? mi.swapPss : "N/A");
15731             }
15732             if (mi.subitems != null) {
15733                 dumpMemItems(pw, prefix + "    ", mi.shortLabel, mi.subitems,
15734                         true, isCompact, dumpSwapPss);
15735             }
15736         }
15737     }
15738
15739     // These are in KB.
15740     static final long[] DUMP_MEM_BUCKETS = new long[] {
15741         5*1024, 7*1024, 10*1024, 15*1024, 20*1024, 30*1024, 40*1024, 80*1024,
15742         120*1024, 160*1024, 200*1024,
15743         250*1024, 300*1024, 350*1024, 400*1024, 500*1024, 600*1024, 800*1024,
15744         1*1024*1024, 2*1024*1024, 5*1024*1024, 10*1024*1024, 20*1024*1024
15745     };
15746
15747     static final void appendMemBucket(StringBuilder out, long memKB, String label,
15748             boolean stackLike) {
15749         int start = label.lastIndexOf('.');
15750         if (start >= 0) start++;
15751         else start = 0;
15752         int end = label.length();
15753         for (int i=0; i<DUMP_MEM_BUCKETS.length; i++) {
15754             if (DUMP_MEM_BUCKETS[i] >= memKB) {
15755                 long bucket = DUMP_MEM_BUCKETS[i]/1024;
15756                 out.append(bucket);
15757                 out.append(stackLike ? "MB." : "MB ");
15758                 out.append(label, start, end);
15759                 return;
15760             }
15761         }
15762         out.append(memKB/1024);
15763         out.append(stackLike ? "MB." : "MB ");
15764         out.append(label, start, end);
15765     }
15766
15767     static final int[] DUMP_MEM_OOM_ADJ = new int[] {
15768             ProcessList.NATIVE_ADJ,
15769             ProcessList.SYSTEM_ADJ, ProcessList.PERSISTENT_PROC_ADJ,
15770             ProcessList.PERSISTENT_SERVICE_ADJ, ProcessList.FOREGROUND_APP_ADJ,
15771             ProcessList.VISIBLE_APP_ADJ, ProcessList.PERCEPTIBLE_APP_ADJ,
15772             ProcessList.BACKUP_APP_ADJ, ProcessList.HEAVY_WEIGHT_APP_ADJ,
15773             ProcessList.SERVICE_ADJ, ProcessList.HOME_APP_ADJ,
15774             ProcessList.PREVIOUS_APP_ADJ, ProcessList.SERVICE_B_ADJ, ProcessList.CACHED_APP_MIN_ADJ
15775     };
15776     static final String[] DUMP_MEM_OOM_LABEL = new String[] {
15777             "Native",
15778             "System", "Persistent", "Persistent Service", "Foreground",
15779             "Visible", "Perceptible",
15780             "Heavy Weight", "Backup",
15781             "A Services", "Home",
15782             "Previous", "B Services", "Cached"
15783     };
15784     static final String[] DUMP_MEM_OOM_COMPACT_LABEL = new String[] {
15785             "native",
15786             "sys", "pers", "persvc", "fore",
15787             "vis", "percept",
15788             "heavy", "backup",
15789             "servicea", "home",
15790             "prev", "serviceb", "cached"
15791     };
15792
15793     private final void dumpApplicationMemoryUsageHeader(PrintWriter pw, long uptime,
15794             long realtime, boolean isCheckinRequest, boolean isCompact) {
15795         if (isCompact) {
15796             pw.print("version,"); pw.println(MEMINFO_COMPACT_VERSION);
15797         }
15798         if (isCheckinRequest || isCompact) {
15799             // short checkin version
15800             pw.print("time,"); pw.print(uptime); pw.print(","); pw.println(realtime);
15801         } else {
15802             pw.println("Applications Memory Usage (in Kilobytes):");
15803             pw.println("Uptime: " + uptime + " Realtime: " + realtime);
15804         }
15805     }
15806
15807     private static final int KSM_SHARED = 0;
15808     private static final int KSM_SHARING = 1;
15809     private static final int KSM_UNSHARED = 2;
15810     private static final int KSM_VOLATILE = 3;
15811
15812     private final long[] getKsmInfo() {
15813         long[] longOut = new long[4];
15814         final int[] SINGLE_LONG_FORMAT = new int[] {
15815             Process.PROC_SPACE_TERM|Process.PROC_OUT_LONG
15816         };
15817         long[] longTmp = new long[1];
15818         Process.readProcFile("/sys/kernel/mm/ksm/pages_shared",
15819                 SINGLE_LONG_FORMAT, null, longTmp, null);
15820         longOut[KSM_SHARED] = longTmp[0] * ProcessList.PAGE_SIZE / 1024;
15821         longTmp[0] = 0;
15822         Process.readProcFile("/sys/kernel/mm/ksm/pages_sharing",
15823                 SINGLE_LONG_FORMAT, null, longTmp, null);
15824         longOut[KSM_SHARING] = longTmp[0] * ProcessList.PAGE_SIZE / 1024;
15825         longTmp[0] = 0;
15826         Process.readProcFile("/sys/kernel/mm/ksm/pages_unshared",
15827                 SINGLE_LONG_FORMAT, null, longTmp, null);
15828         longOut[KSM_UNSHARED] = longTmp[0] * ProcessList.PAGE_SIZE / 1024;
15829         longTmp[0] = 0;
15830         Process.readProcFile("/sys/kernel/mm/ksm/pages_volatile",
15831                 SINGLE_LONG_FORMAT, null, longTmp, null);
15832         longOut[KSM_VOLATILE] = longTmp[0] * ProcessList.PAGE_SIZE / 1024;
15833         return longOut;
15834     }
15835
15836     private static String stringifySize(long size, int order) {
15837         Locale locale = Locale.US;
15838         switch (order) {
15839             case 1:
15840                 return String.format(locale, "%,13d", size);
15841             case 1024:
15842                 return String.format(locale, "%,9dK", size / 1024);
15843             case 1024 * 1024:
15844                 return String.format(locale, "%,5dM", size / 1024 / 1024);
15845             case 1024 * 1024 * 1024:
15846                 return String.format(locale, "%,1dG", size / 1024 / 1024 / 1024);
15847             default:
15848                 throw new IllegalArgumentException("Invalid size order");
15849         }
15850     }
15851
15852     private static String stringifyKBSize(long size) {
15853         return stringifySize(size * 1024, 1024);
15854     }
15855
15856     // Update this version number in case you change the 'compact' format
15857     private static final int MEMINFO_COMPACT_VERSION = 1;
15858
15859     final void dumpApplicationMemoryUsage(FileDescriptor fd,
15860             PrintWriter pw, String prefix, String[] args, boolean brief, PrintWriter categoryPw) {
15861         boolean dumpDetails = false;
15862         boolean dumpFullDetails = false;
15863         boolean dumpDalvik = false;
15864         boolean dumpSummaryOnly = false;
15865         boolean dumpUnreachable = false;
15866         boolean oomOnly = false;
15867         boolean isCompact = false;
15868         boolean localOnly = false;
15869         boolean packages = false;
15870         boolean isCheckinRequest = false;
15871         boolean dumpSwapPss = false;
15872
15873         int opti = 0;
15874         while (opti < args.length) {
15875             String opt = args[opti];
15876             if (opt == null || opt.length() <= 0 || opt.charAt(0) != '-') {
15877                 break;
15878             }
15879             opti++;
15880             if ("-a".equals(opt)) {
15881                 dumpDetails = true;
15882                 dumpFullDetails = true;
15883                 dumpDalvik = true;
15884                 dumpSwapPss = true;
15885             } else if ("-d".equals(opt)) {
15886                 dumpDalvik = true;
15887             } else if ("-c".equals(opt)) {
15888                 isCompact = true;
15889             } else if ("-s".equals(opt)) {
15890                 dumpDetails = true;
15891                 dumpSummaryOnly = true;
15892             } else if ("-S".equals(opt)) {
15893                 dumpSwapPss = true;
15894             } else if ("--unreachable".equals(opt)) {
15895                 dumpUnreachable = true;
15896             } else if ("--oom".equals(opt)) {
15897                 oomOnly = true;
15898             } else if ("--local".equals(opt)) {
15899                 localOnly = true;
15900             } else if ("--package".equals(opt)) {
15901                 packages = true;
15902             } else if ("--checkin".equals(opt)) {
15903                 isCheckinRequest = true;
15904
15905             } else if ("-h".equals(opt)) {
15906                 pw.println("meminfo dump options: [-a] [-d] [-c] [-s] [--oom] [process]");
15907                 pw.println("  -a: include all available information for each process.");
15908                 pw.println("  -d: include dalvik details.");
15909                 pw.println("  -c: dump in a compact machine-parseable representation.");
15910                 pw.println("  -s: dump only summary of application memory usage.");
15911                 pw.println("  -S: dump also SwapPss.");
15912                 pw.println("  --oom: only show processes organized by oom adj.");
15913                 pw.println("  --local: only collect details locally, don't call process.");
15914                 pw.println("  --package: interpret process arg as package, dumping all");
15915                 pw.println("             processes that have loaded that package.");
15916                 pw.println("  --checkin: dump data for a checkin");
15917                 pw.println("If [process] is specified it can be the name or ");
15918                 pw.println("pid of a specific process to dump.");
15919                 return;
15920             } else {
15921                 pw.println("Unknown argument: " + opt + "; use -h for help");
15922             }
15923         }
15924
15925         long uptime = SystemClock.uptimeMillis();
15926         long realtime = SystemClock.elapsedRealtime();
15927         final long[] tmpLong = new long[1];
15928
15929         ArrayList<ProcessRecord> procs = collectProcesses(pw, opti, packages, args);
15930         if (procs == null) {
15931             // No Java processes.  Maybe they want to print a native process.
15932             if (args != null && args.length > opti
15933                     && args[opti].charAt(0) != '-') {
15934                 ArrayList<ProcessCpuTracker.Stats> nativeProcs
15935                         = new ArrayList<ProcessCpuTracker.Stats>();
15936                 updateCpuStatsNow();
15937                 int findPid = -1;
15938                 try {
15939                     findPid = Integer.parseInt(args[opti]);
15940                 } catch (NumberFormatException e) {
15941                 }
15942                 synchronized (mProcessCpuTracker) {
15943                     final int N = mProcessCpuTracker.countStats();
15944                     for (int i=0; i<N; i++) {
15945                         ProcessCpuTracker.Stats st = mProcessCpuTracker.getStats(i);
15946                         if (st.pid == findPid || (st.baseName != null
15947                                 && st.baseName.equals(args[opti]))) {
15948                             nativeProcs.add(st);
15949                         }
15950                     }
15951                 }
15952                 if (nativeProcs.size() > 0) {
15953                     dumpApplicationMemoryUsageHeader(pw, uptime, realtime, isCheckinRequest,
15954                             isCompact);
15955                     Debug.MemoryInfo mi = null;
15956                     for (int i = nativeProcs.size() - 1 ; i >= 0 ; i--) {
15957                         final ProcessCpuTracker.Stats r = nativeProcs.get(i);
15958                         final int pid = r.pid;
15959                         if (!isCheckinRequest && dumpDetails) {
15960                             pw.println("\n** MEMINFO in pid " + pid + " [" + r.baseName + "] **");
15961                         }
15962                         if (mi == null) {
15963                             mi = new Debug.MemoryInfo();
15964                         }
15965                         if (dumpDetails || (!brief && !oomOnly)) {
15966                             Debug.getMemoryInfo(pid, mi);
15967                         } else {
15968                             mi.dalvikPss = (int)Debug.getPss(pid, tmpLong, null);
15969                             mi.dalvikPrivateDirty = (int)tmpLong[0];
15970                         }
15971                         ActivityThread.dumpMemInfoTable(pw, mi, isCheckinRequest, dumpFullDetails,
15972                                 dumpDalvik, dumpSummaryOnly, pid, r.baseName, 0, 0, 0, 0, 0, 0);
15973                         if (isCheckinRequest) {
15974                             pw.println();
15975                         }
15976                     }
15977                     return;
15978                 }
15979             }
15980             pw.println("No process found for: " + args[opti]);
15981             return;
15982         }
15983
15984         if (!brief && !oomOnly && (procs.size() == 1 || isCheckinRequest || packages)) {
15985             dumpDetails = true;
15986         }
15987
15988         dumpApplicationMemoryUsageHeader(pw, uptime, realtime, isCheckinRequest, isCompact);
15989
15990         String[] innerArgs = new String[args.length-opti];
15991         System.arraycopy(args, opti, innerArgs, 0, args.length-opti);
15992
15993         ArrayList<MemItem> procMems = new ArrayList<MemItem>();
15994         final SparseArray<MemItem> procMemsMap = new SparseArray<MemItem>();
15995         long nativePss = 0;
15996         long nativeSwapPss = 0;
15997         long dalvikPss = 0;
15998         long dalvikSwapPss = 0;
15999         long[] dalvikSubitemPss = dumpDalvik ? new long[Debug.MemoryInfo.NUM_DVK_STATS] :
16000                 EmptyArray.LONG;
16001         long[] dalvikSubitemSwapPss = dumpDalvik ? new long[Debug.MemoryInfo.NUM_DVK_STATS] :
16002                 EmptyArray.LONG;
16003         long otherPss = 0;
16004         long otherSwapPss = 0;
16005         long[] miscPss = new long[Debug.MemoryInfo.NUM_OTHER_STATS];
16006         long[] miscSwapPss = new long[Debug.MemoryInfo.NUM_OTHER_STATS];
16007
16008         long oomPss[] = new long[DUMP_MEM_OOM_LABEL.length];
16009         long oomSwapPss[] = new long[DUMP_MEM_OOM_LABEL.length];
16010         ArrayList<MemItem>[] oomProcs = (ArrayList<MemItem>[])
16011                 new ArrayList[DUMP_MEM_OOM_LABEL.length];
16012
16013         long totalPss = 0;
16014         long totalSwapPss = 0;
16015         long cachedPss = 0;
16016         long cachedSwapPss = 0;
16017         boolean hasSwapPss = false;
16018
16019         Debug.MemoryInfo mi = null;
16020         for (int i = procs.size() - 1 ; i >= 0 ; i--) {
16021             final ProcessRecord r = procs.get(i);
16022             final IApplicationThread thread;
16023             final int pid;
16024             final int oomAdj;
16025             final boolean hasActivities;
16026             synchronized (this) {
16027                 thread = r.thread;
16028                 pid = r.pid;
16029                 oomAdj = r.getSetAdjWithServices();
16030                 hasActivities = r.activities.size() > 0;
16031             }
16032             if (thread != null) {
16033                 if (!isCheckinRequest && dumpDetails) {
16034                     pw.println("\n** MEMINFO in pid " + pid + " [" + r.processName + "] **");
16035                 }
16036                 if (mi == null) {
16037                     mi = new Debug.MemoryInfo();
16038                 }
16039                 if (dumpDetails || (!brief && !oomOnly)) {
16040                     Debug.getMemoryInfo(pid, mi);
16041                     hasSwapPss = mi.hasSwappedOutPss;
16042                 } else {
16043                     mi.dalvikPss = (int)Debug.getPss(pid, tmpLong, null);
16044                     mi.dalvikPrivateDirty = (int)tmpLong[0];
16045                 }
16046                 if (dumpDetails) {
16047                     if (localOnly) {
16048                         ActivityThread.dumpMemInfoTable(pw, mi, isCheckinRequest, dumpFullDetails,
16049                                 dumpDalvik, dumpSummaryOnly, pid, r.processName, 0, 0, 0, 0, 0, 0);
16050                         if (isCheckinRequest) {
16051                             pw.println();
16052                         }
16053                     } else {
16054                         try {
16055                             pw.flush();
16056                             thread.dumpMemInfo(fd, mi, isCheckinRequest, dumpFullDetails,
16057                                     dumpDalvik, dumpSummaryOnly, dumpUnreachable, innerArgs);
16058                         } catch (RemoteException e) {
16059                             if (!isCheckinRequest) {
16060                                 pw.println("Got RemoteException!");
16061                                 pw.flush();
16062                             }
16063                         }
16064                     }
16065                 }
16066
16067                 final long myTotalPss = mi.getTotalPss();
16068                 final long myTotalUss = mi.getTotalUss();
16069                 final long myTotalSwapPss = mi.getTotalSwappedOutPss();
16070
16071                 synchronized (this) {
16072                     if (r.thread != null && oomAdj == r.getSetAdjWithServices()) {
16073                         // Record this for posterity if the process has been stable.
16074                         r.baseProcessTracker.addPss(myTotalPss, myTotalUss, true, r.pkgList);
16075                     }
16076                 }
16077
16078                 if (!isCheckinRequest && mi != null) {
16079                     totalPss += myTotalPss;
16080                     totalSwapPss += myTotalSwapPss;
16081                     MemItem pssItem = new MemItem(r.processName + " (pid " + pid +
16082                             (hasActivities ? " / activities)" : ")"), r.processName, myTotalPss,
16083                             myTotalSwapPss, pid, hasActivities);
16084                     procMems.add(pssItem);
16085                     procMemsMap.put(pid, pssItem);
16086
16087                     nativePss += mi.nativePss;
16088                     nativeSwapPss += mi.nativeSwappedOutPss;
16089                     dalvikPss += mi.dalvikPss;
16090                     dalvikSwapPss += mi.dalvikSwappedOutPss;
16091                     for (int j=0; j<dalvikSubitemPss.length; j++) {
16092                         dalvikSubitemPss[j] += mi.getOtherPss(Debug.MemoryInfo.NUM_OTHER_STATS + j);
16093                         dalvikSubitemSwapPss[j] +=
16094                                 mi.getOtherSwappedOutPss(Debug.MemoryInfo.NUM_OTHER_STATS + j);
16095                     }
16096                     otherPss += mi.otherPss;
16097                     otherSwapPss += mi.otherSwappedOutPss;
16098                     for (int j=0; j<Debug.MemoryInfo.NUM_OTHER_STATS; j++) {
16099                         long mem = mi.getOtherPss(j);
16100                         miscPss[j] += mem;
16101                         otherPss -= mem;
16102                         mem = mi.getOtherSwappedOutPss(j);
16103                         miscSwapPss[j] += mem;
16104                         otherSwapPss -= mem;
16105                     }
16106
16107                     if (oomAdj >= ProcessList.CACHED_APP_MIN_ADJ) {
16108                         cachedPss += myTotalPss;
16109                         cachedSwapPss += myTotalSwapPss;
16110                     }
16111
16112                     for (int oomIndex=0; oomIndex<oomPss.length; oomIndex++) {
16113                         if (oomIndex == (oomPss.length - 1)
16114                                 || (oomAdj >= DUMP_MEM_OOM_ADJ[oomIndex]
16115                                         && oomAdj < DUMP_MEM_OOM_ADJ[oomIndex + 1])) {
16116                             oomPss[oomIndex] += myTotalPss;
16117                             oomSwapPss[oomIndex] += myTotalSwapPss;
16118                             if (oomProcs[oomIndex] == null) {
16119                                 oomProcs[oomIndex] = new ArrayList<MemItem>();
16120                             }
16121                             oomProcs[oomIndex].add(pssItem);
16122                             break;
16123                         }
16124                     }
16125                 }
16126             }
16127         }
16128
16129         long nativeProcTotalPss = 0;
16130
16131         if (!isCheckinRequest && procs.size() > 1 && !packages) {
16132             // If we are showing aggregations, also look for native processes to
16133             // include so that our aggregations are more accurate.
16134             updateCpuStatsNow();
16135             mi = null;
16136             synchronized (mProcessCpuTracker) {
16137                 final int N = mProcessCpuTracker.countStats();
16138                 for (int i=0; i<N; i++) {
16139                     ProcessCpuTracker.Stats st = mProcessCpuTracker.getStats(i);
16140                     if (st.vsize > 0 && procMemsMap.indexOfKey(st.pid) < 0) {
16141                         if (mi == null) {
16142                             mi = new Debug.MemoryInfo();
16143                         }
16144                         if (!brief && !oomOnly) {
16145                             Debug.getMemoryInfo(st.pid, mi);
16146                         } else {
16147                             mi.nativePss = (int)Debug.getPss(st.pid, tmpLong, null);
16148                             mi.nativePrivateDirty = (int)tmpLong[0];
16149                         }
16150
16151                         final long myTotalPss = mi.getTotalPss();
16152                         final long myTotalSwapPss = mi.getTotalSwappedOutPss();
16153                         totalPss += myTotalPss;
16154                         nativeProcTotalPss += myTotalPss;
16155
16156                         MemItem pssItem = new MemItem(st.name + " (pid " + st.pid + ")",
16157                                 st.name, myTotalPss, mi.getSummaryTotalSwapPss(), st.pid, false);
16158                         procMems.add(pssItem);
16159
16160                         nativePss += mi.nativePss;
16161                         nativeSwapPss += mi.nativeSwappedOutPss;
16162                         dalvikPss += mi.dalvikPss;
16163                         dalvikSwapPss += mi.dalvikSwappedOutPss;
16164                         for (int j=0; j<dalvikSubitemPss.length; j++) {
16165                             dalvikSubitemPss[j] += mi.getOtherPss(Debug.MemoryInfo.NUM_OTHER_STATS + j);
16166                             dalvikSubitemSwapPss[j] +=
16167                                     mi.getOtherSwappedOutPss(Debug.MemoryInfo.NUM_OTHER_STATS + j);
16168                         }
16169                         otherPss += mi.otherPss;
16170                         otherSwapPss += mi.otherSwappedOutPss;
16171                         for (int j=0; j<Debug.MemoryInfo.NUM_OTHER_STATS; j++) {
16172                             long mem = mi.getOtherPss(j);
16173                             miscPss[j] += mem;
16174                             otherPss -= mem;
16175                             mem = mi.getOtherSwappedOutPss(j);
16176                             miscSwapPss[j] += mem;
16177                             otherSwapPss -= mem;
16178                         }
16179                         oomPss[0] += myTotalPss;
16180                         oomSwapPss[0] += myTotalSwapPss;
16181                         if (oomProcs[0] == null) {
16182                             oomProcs[0] = new ArrayList<MemItem>();
16183                         }
16184                         oomProcs[0].add(pssItem);
16185                     }
16186                 }
16187             }
16188
16189             ArrayList<MemItem> catMems = new ArrayList<MemItem>();
16190
16191             catMems.add(new MemItem("Native", "Native", nativePss, nativeSwapPss, -1));
16192             final MemItem dalvikItem =
16193                     new MemItem("Dalvik", "Dalvik", dalvikPss, dalvikSwapPss, -2);
16194             if (dalvikSubitemPss.length > 0) {
16195                 dalvikItem.subitems = new ArrayList<MemItem>();
16196                 for (int j=0; j<dalvikSubitemPss.length; j++) {
16197                     final String name = Debug.MemoryInfo.getOtherLabel(
16198                             Debug.MemoryInfo.NUM_OTHER_STATS + j);
16199                     dalvikItem.subitems.add(new MemItem(name, name, dalvikSubitemPss[j],
16200                                     dalvikSubitemSwapPss[j], j));
16201                 }
16202             }
16203             catMems.add(dalvikItem);
16204             catMems.add(new MemItem("Unknown", "Unknown", otherPss, otherSwapPss, -3));
16205             for (int j=0; j<Debug.MemoryInfo.NUM_OTHER_STATS; j++) {
16206                 String label = Debug.MemoryInfo.getOtherLabel(j);
16207                 catMems.add(new MemItem(label, label, miscPss[j], miscSwapPss[j], j));
16208             }
16209
16210             ArrayList<MemItem> oomMems = new ArrayList<MemItem>();
16211             for (int j=0; j<oomPss.length; j++) {
16212                 if (oomPss[j] != 0) {
16213                     String label = isCompact ? DUMP_MEM_OOM_COMPACT_LABEL[j]
16214                             : DUMP_MEM_OOM_LABEL[j];
16215                     MemItem item = new MemItem(label, label, oomPss[j], oomSwapPss[j],
16216                             DUMP_MEM_OOM_ADJ[j]);
16217                     item.subitems = oomProcs[j];
16218                     oomMems.add(item);
16219                 }
16220             }
16221
16222             dumpSwapPss = dumpSwapPss && hasSwapPss && totalSwapPss != 0;
16223             if (!brief && !oomOnly && !isCompact) {
16224                 pw.println();
16225                 pw.println("Total PSS by process:");
16226                 dumpMemItems(pw, "  ", "proc", procMems, true, isCompact, dumpSwapPss);
16227                 pw.println();
16228             }
16229             if (!isCompact) {
16230                 pw.println("Total PSS by OOM adjustment:");
16231             }
16232             dumpMemItems(pw, "  ", "oom", oomMems, false, isCompact, dumpSwapPss);
16233             if (!brief && !oomOnly) {
16234                 PrintWriter out = categoryPw != null ? categoryPw : pw;
16235                 if (!isCompact) {
16236                     out.println();
16237                     out.println("Total PSS by category:");
16238                 }
16239                 dumpMemItems(out, "  ", "cat", catMems, true, isCompact, dumpSwapPss);
16240             }
16241             if (!isCompact) {
16242                 pw.println();
16243             }
16244             MemInfoReader memInfo = new MemInfoReader();
16245             memInfo.readMemInfo();
16246             if (nativeProcTotalPss > 0) {
16247                 synchronized (this) {
16248                     final long cachedKb = memInfo.getCachedSizeKb();
16249                     final long freeKb = memInfo.getFreeSizeKb();
16250                     final long zramKb = memInfo.getZramTotalSizeKb();
16251                     final long kernelKb = memInfo.getKernelUsedSizeKb();
16252                     EventLogTags.writeAmMeminfo(cachedKb*1024, freeKb*1024, zramKb*1024,
16253                             kernelKb*1024, nativeProcTotalPss*1024);
16254                     mProcessStats.addSysMemUsageLocked(cachedKb, freeKb, zramKb, kernelKb,
16255                             nativeProcTotalPss);
16256                 }
16257             }
16258             if (!brief) {
16259                 if (!isCompact) {
16260                     pw.print("Total RAM: "); pw.print(stringifyKBSize(memInfo.getTotalSizeKb()));
16261                     pw.print(" (status ");
16262                     switch (mLastMemoryLevel) {
16263                         case ProcessStats.ADJ_MEM_FACTOR_NORMAL:
16264                             pw.println("normal)");
16265                             break;
16266                         case ProcessStats.ADJ_MEM_FACTOR_MODERATE:
16267                             pw.println("moderate)");
16268                             break;
16269                         case ProcessStats.ADJ_MEM_FACTOR_LOW:
16270                             pw.println("low)");
16271                             break;
16272                         case ProcessStats.ADJ_MEM_FACTOR_CRITICAL:
16273                             pw.println("critical)");
16274                             break;
16275                         default:
16276                             pw.print(mLastMemoryLevel);
16277                             pw.println(")");
16278                             break;
16279                     }
16280                     pw.print(" Free RAM: ");
16281                     pw.print(stringifyKBSize(cachedPss + memInfo.getCachedSizeKb()
16282                             + memInfo.getFreeSizeKb()));
16283                     pw.print(" (");
16284                     pw.print(stringifyKBSize(cachedPss));
16285                     pw.print(" cached pss + ");
16286                     pw.print(stringifyKBSize(memInfo.getCachedSizeKb()));
16287                     pw.print(" cached kernel + ");
16288                     pw.print(stringifyKBSize(memInfo.getFreeSizeKb()));
16289                     pw.println(" free)");
16290                 } else {
16291                     pw.print("ram,"); pw.print(memInfo.getTotalSizeKb()); pw.print(",");
16292                     pw.print(cachedPss + memInfo.getCachedSizeKb()
16293                             + memInfo.getFreeSizeKb()); pw.print(",");
16294                     pw.println(totalPss - cachedPss);
16295                 }
16296             }
16297             long lostRAM = memInfo.getTotalSizeKb() - (totalPss - totalSwapPss)
16298                     - memInfo.getFreeSizeKb() - memInfo.getCachedSizeKb()
16299                     - memInfo.getKernelUsedSizeKb() - memInfo.getZramTotalSizeKb();
16300             if (!isCompact) {
16301                 pw.print(" Used RAM: "); pw.print(stringifyKBSize(totalPss - cachedPss
16302                         + memInfo.getKernelUsedSizeKb())); pw.print(" (");
16303                 pw.print(stringifyKBSize(totalPss - cachedPss)); pw.print(" used pss + ");
16304                 pw.print(stringifyKBSize(memInfo.getKernelUsedSizeKb())); pw.print(" kernel)\n");
16305                 pw.print(" Lost RAM: "); pw.println(stringifyKBSize(lostRAM));
16306             } else {
16307                 pw.print("lostram,"); pw.println(lostRAM);
16308             }
16309             if (!brief) {
16310                 if (memInfo.getZramTotalSizeKb() != 0) {
16311                     if (!isCompact) {
16312                         pw.print("     ZRAM: ");
16313                         pw.print(stringifyKBSize(memInfo.getZramTotalSizeKb()));
16314                                 pw.print(" physical used for ");
16315                                 pw.print(stringifyKBSize(memInfo.getSwapTotalSizeKb()
16316                                         - memInfo.getSwapFreeSizeKb()));
16317                                 pw.print(" in swap (");
16318                                 pw.print(stringifyKBSize(memInfo.getSwapTotalSizeKb()));
16319                                 pw.println(" total swap)");
16320                     } else {
16321                         pw.print("zram,"); pw.print(memInfo.getZramTotalSizeKb()); pw.print(",");
16322                                 pw.print(memInfo.getSwapTotalSizeKb()); pw.print(",");
16323                                 pw.println(memInfo.getSwapFreeSizeKb());
16324                     }
16325                 }
16326                 final long[] ksm = getKsmInfo();
16327                 if (!isCompact) {
16328                     if (ksm[KSM_SHARING] != 0 || ksm[KSM_SHARED] != 0 || ksm[KSM_UNSHARED] != 0
16329                             || ksm[KSM_VOLATILE] != 0) {
16330                         pw.print("      KSM: "); pw.print(stringifyKBSize(ksm[KSM_SHARING]));
16331                                 pw.print(" saved from shared ");
16332                                 pw.print(stringifyKBSize(ksm[KSM_SHARED]));
16333                         pw.print("           "); pw.print(stringifyKBSize(ksm[KSM_UNSHARED]));
16334                                 pw.print(" unshared; ");
16335                                 pw.print(stringifyKBSize(
16336                                              ksm[KSM_VOLATILE])); pw.println(" volatile");
16337                     }
16338                     pw.print("   Tuning: ");
16339                     pw.print(ActivityManager.staticGetMemoryClass());
16340                     pw.print(" (large ");
16341                     pw.print(ActivityManager.staticGetLargeMemoryClass());
16342                     pw.print("), oom ");
16343                     pw.print(stringifySize(
16344                                 mProcessList.getMemLevel(ProcessList.CACHED_APP_MAX_ADJ), 1024));
16345                     pw.print(", restore limit ");
16346                     pw.print(stringifyKBSize(mProcessList.getCachedRestoreThresholdKb()));
16347                     if (ActivityManager.isLowRamDeviceStatic()) {
16348                         pw.print(" (low-ram)");
16349                     }
16350                     if (ActivityManager.isHighEndGfx()) {
16351                         pw.print(" (high-end-gfx)");
16352                     }
16353                     pw.println();
16354                 } else {
16355                     pw.print("ksm,"); pw.print(ksm[KSM_SHARING]); pw.print(",");
16356                     pw.print(ksm[KSM_SHARED]); pw.print(","); pw.print(ksm[KSM_UNSHARED]);
16357                     pw.print(","); pw.println(ksm[KSM_VOLATILE]);
16358                     pw.print("tuning,");
16359                     pw.print(ActivityManager.staticGetMemoryClass());
16360                     pw.print(',');
16361                     pw.print(ActivityManager.staticGetLargeMemoryClass());
16362                     pw.print(',');
16363                     pw.print(mProcessList.getMemLevel(ProcessList.CACHED_APP_MAX_ADJ)/1024);
16364                     if (ActivityManager.isLowRamDeviceStatic()) {
16365                         pw.print(",low-ram");
16366                     }
16367                     if (ActivityManager.isHighEndGfx()) {
16368                         pw.print(",high-end-gfx");
16369                     }
16370                     pw.println();
16371                 }
16372             }
16373         }
16374     }
16375
16376     private void appendBasicMemEntry(StringBuilder sb, int oomAdj, int procState, long pss,
16377             long memtrack, String name) {
16378         sb.append("  ");
16379         sb.append(ProcessList.makeOomAdjString(oomAdj));
16380         sb.append(' ');
16381         sb.append(ProcessList.makeProcStateString(procState));
16382         sb.append(' ');
16383         ProcessList.appendRamKb(sb, pss);
16384         sb.append(": ");
16385         sb.append(name);
16386         if (memtrack > 0) {
16387             sb.append(" (");
16388             sb.append(stringifyKBSize(memtrack));
16389             sb.append(" memtrack)");
16390         }
16391     }
16392
16393     private void appendMemInfo(StringBuilder sb, ProcessMemInfo mi) {
16394         appendBasicMemEntry(sb, mi.oomAdj, mi.procState, mi.pss, mi.memtrack, mi.name);
16395         sb.append(" (pid ");
16396         sb.append(mi.pid);
16397         sb.append(") ");
16398         sb.append(mi.adjType);
16399         sb.append('\n');
16400         if (mi.adjReason != null) {
16401             sb.append("                      ");
16402             sb.append(mi.adjReason);
16403             sb.append('\n');
16404         }
16405     }
16406
16407     void reportMemUsage(ArrayList<ProcessMemInfo> memInfos) {
16408         final SparseArray<ProcessMemInfo> infoMap = new SparseArray<>(memInfos.size());
16409         for (int i=0, N=memInfos.size(); i<N; i++) {
16410             ProcessMemInfo mi = memInfos.get(i);
16411             infoMap.put(mi.pid, mi);
16412         }
16413         updateCpuStatsNow();
16414         long[] memtrackTmp = new long[1];
16415         synchronized (mProcessCpuTracker) {
16416             final int N = mProcessCpuTracker.countStats();
16417             for (int i=0; i<N; i++) {
16418                 ProcessCpuTracker.Stats st = mProcessCpuTracker.getStats(i);
16419                 if (st.vsize > 0) {
16420                     long pss = Debug.getPss(st.pid, null, memtrackTmp);
16421                     if (pss > 0) {
16422                         if (infoMap.indexOfKey(st.pid) < 0) {
16423                             ProcessMemInfo mi = new ProcessMemInfo(st.name, st.pid,
16424                                     ProcessList.NATIVE_ADJ, -1, "native", null);
16425                             mi.pss = pss;
16426                             mi.memtrack = memtrackTmp[0];
16427                             memInfos.add(mi);
16428                         }
16429                     }
16430                 }
16431             }
16432         }
16433
16434         long totalPss = 0;
16435         long totalMemtrack = 0;
16436         for (int i=0, N=memInfos.size(); i<N; i++) {
16437             ProcessMemInfo mi = memInfos.get(i);
16438             if (mi.pss == 0) {
16439                 mi.pss = Debug.getPss(mi.pid, null, memtrackTmp);
16440                 mi.memtrack = memtrackTmp[0];
16441             }
16442             totalPss += mi.pss;
16443             totalMemtrack += mi.memtrack;
16444         }
16445         Collections.sort(memInfos, new Comparator<ProcessMemInfo>() {
16446             @Override public int compare(ProcessMemInfo lhs, ProcessMemInfo rhs) {
16447                 if (lhs.oomAdj != rhs.oomAdj) {
16448                     return lhs.oomAdj < rhs.oomAdj ? -1 : 1;
16449                 }
16450                 if (lhs.pss != rhs.pss) {
16451                     return lhs.pss < rhs.pss ? 1 : -1;
16452                 }
16453                 return 0;
16454             }
16455         });
16456
16457         StringBuilder tag = new StringBuilder(128);
16458         StringBuilder stack = new StringBuilder(128);
16459         tag.append("Low on memory -- ");
16460         appendMemBucket(tag, totalPss, "total", false);
16461         appendMemBucket(stack, totalPss, "total", true);
16462
16463         StringBuilder fullNativeBuilder = new StringBuilder(1024);
16464         StringBuilder shortNativeBuilder = new StringBuilder(1024);
16465         StringBuilder fullJavaBuilder = new StringBuilder(1024);
16466
16467         boolean firstLine = true;
16468         int lastOomAdj = Integer.MIN_VALUE;
16469         long extraNativeRam = 0;
16470         long extraNativeMemtrack = 0;
16471         long cachedPss = 0;
16472         for (int i=0, N=memInfos.size(); i<N; i++) {
16473             ProcessMemInfo mi = memInfos.get(i);
16474
16475             if (mi.oomAdj >= ProcessList.CACHED_APP_MIN_ADJ) {
16476                 cachedPss += mi.pss;
16477             }
16478
16479             if (mi.oomAdj != ProcessList.NATIVE_ADJ
16480                     && (mi.oomAdj < ProcessList.SERVICE_ADJ
16481                             || mi.oomAdj == ProcessList.HOME_APP_ADJ
16482                             || mi.oomAdj == ProcessList.PREVIOUS_APP_ADJ)) {
16483                 if (lastOomAdj != mi.oomAdj) {
16484                     lastOomAdj = mi.oomAdj;
16485                     if (mi.oomAdj <= ProcessList.FOREGROUND_APP_ADJ) {
16486                         tag.append(" / ");
16487                     }
16488                     if (mi.oomAdj >= ProcessList.FOREGROUND_APP_ADJ) {
16489                         if (firstLine) {
16490                             stack.append(":");
16491                             firstLine = false;
16492                         }
16493                         stack.append("\n\t at ");
16494                     } else {
16495                         stack.append("$");
16496                     }
16497                 } else {
16498                     tag.append(" ");
16499                     stack.append("$");
16500                 }
16501                 if (mi.oomAdj <= ProcessList.FOREGROUND_APP_ADJ) {
16502                     appendMemBucket(tag, mi.pss, mi.name, false);
16503                 }
16504                 appendMemBucket(stack, mi.pss, mi.name, true);
16505                 if (mi.oomAdj >= ProcessList.FOREGROUND_APP_ADJ
16506                         && ((i+1) >= N || memInfos.get(i+1).oomAdj != lastOomAdj)) {
16507                     stack.append("(");
16508                     for (int k=0; k<DUMP_MEM_OOM_ADJ.length; k++) {
16509                         if (DUMP_MEM_OOM_ADJ[k] == mi.oomAdj) {
16510                             stack.append(DUMP_MEM_OOM_LABEL[k]);
16511                             stack.append(":");
16512                             stack.append(DUMP_MEM_OOM_ADJ[k]);
16513                         }
16514                     }
16515                     stack.append(")");
16516                 }
16517             }
16518
16519             appendMemInfo(fullNativeBuilder, mi);
16520             if (mi.oomAdj == ProcessList.NATIVE_ADJ) {
16521                 // The short form only has native processes that are >= 512K.
16522                 if (mi.pss >= 512) {
16523                     appendMemInfo(shortNativeBuilder, mi);
16524                 } else {
16525                     extraNativeRam += mi.pss;
16526                     extraNativeMemtrack += mi.memtrack;
16527                 }
16528             } else {
16529                 // Short form has all other details, but if we have collected RAM
16530                 // from smaller native processes let's dump a summary of that.
16531                 if (extraNativeRam > 0) {
16532                     appendBasicMemEntry(shortNativeBuilder, ProcessList.NATIVE_ADJ,
16533                             -1, extraNativeRam, extraNativeMemtrack, "(Other native)");
16534                     shortNativeBuilder.append('\n');
16535                     extraNativeRam = 0;
16536                 }
16537                 appendMemInfo(fullJavaBuilder, mi);
16538             }
16539         }
16540
16541         fullJavaBuilder.append("           ");
16542         ProcessList.appendRamKb(fullJavaBuilder, totalPss);
16543         fullJavaBuilder.append(": TOTAL");
16544         if (totalMemtrack > 0) {
16545             fullJavaBuilder.append(" (");
16546             fullJavaBuilder.append(stringifyKBSize(totalMemtrack));
16547             fullJavaBuilder.append(" memtrack)");
16548         } else {
16549         }
16550         fullJavaBuilder.append("\n");
16551
16552         MemInfoReader memInfo = new MemInfoReader();
16553         memInfo.readMemInfo();
16554         final long[] infos = memInfo.getRawInfo();
16555
16556         StringBuilder memInfoBuilder = new StringBuilder(1024);
16557         Debug.getMemInfo(infos);
16558         memInfoBuilder.append("  MemInfo: ");
16559         memInfoBuilder.append(stringifyKBSize(infos[Debug.MEMINFO_SLAB])).append(" slab, ");
16560         memInfoBuilder.append(stringifyKBSize(infos[Debug.MEMINFO_SHMEM])).append(" shmem, ");
16561         memInfoBuilder.append(stringifyKBSize(
16562                                   infos[Debug.MEMINFO_VM_ALLOC_USED])).append(" vm alloc, ");
16563         memInfoBuilder.append(stringifyKBSize(
16564                                   infos[Debug.MEMINFO_PAGE_TABLES])).append(" page tables ");
16565         memInfoBuilder.append(stringifyKBSize(
16566                                   infos[Debug.MEMINFO_KERNEL_STACK])).append(" kernel stack\n");
16567         memInfoBuilder.append("           ");
16568         memInfoBuilder.append(stringifyKBSize(infos[Debug.MEMINFO_BUFFERS])).append(" buffers, ");
16569         memInfoBuilder.append(stringifyKBSize(infos[Debug.MEMINFO_CACHED])).append(" cached, ");
16570         memInfoBuilder.append(stringifyKBSize(infos[Debug.MEMINFO_MAPPED])).append(" mapped, ");
16571         memInfoBuilder.append(stringifyKBSize(infos[Debug.MEMINFO_FREE])).append(" free\n");
16572         if (infos[Debug.MEMINFO_ZRAM_TOTAL] != 0) {
16573             memInfoBuilder.append("  ZRAM: ");
16574             memInfoBuilder.append(stringifyKBSize(infos[Debug.MEMINFO_ZRAM_TOTAL]));
16575             memInfoBuilder.append(" RAM, ");
16576             memInfoBuilder.append(stringifyKBSize(infos[Debug.MEMINFO_SWAP_TOTAL]));
16577             memInfoBuilder.append(" swap total, ");
16578             memInfoBuilder.append(stringifyKBSize(infos[Debug.MEMINFO_SWAP_FREE]));
16579             memInfoBuilder.append(" swap free\n");
16580         }
16581         final long[] ksm = getKsmInfo();
16582         if (ksm[KSM_SHARING] != 0 || ksm[KSM_SHARED] != 0 || ksm[KSM_UNSHARED] != 0
16583                 || ksm[KSM_VOLATILE] != 0) {
16584             memInfoBuilder.append("  KSM: ");
16585             memInfoBuilder.append(stringifyKBSize(ksm[KSM_SHARING]));
16586             memInfoBuilder.append(" saved from shared ");
16587             memInfoBuilder.append(stringifyKBSize(ksm[KSM_SHARED]));
16588             memInfoBuilder.append("\n       ");
16589             memInfoBuilder.append(stringifyKBSize(ksm[KSM_UNSHARED]));
16590             memInfoBuilder.append(" unshared; ");
16591             memInfoBuilder.append(stringifyKBSize(ksm[KSM_VOLATILE]));
16592             memInfoBuilder.append(" volatile\n");
16593         }
16594         memInfoBuilder.append("  Free RAM: ");
16595         memInfoBuilder.append(stringifyKBSize(cachedPss + memInfo.getCachedSizeKb()
16596                 + memInfo.getFreeSizeKb()));
16597         memInfoBuilder.append("\n");
16598         memInfoBuilder.append("  Used RAM: ");
16599         memInfoBuilder.append(stringifyKBSize(
16600                                   totalPss - cachedPss + memInfo.getKernelUsedSizeKb()));
16601         memInfoBuilder.append("\n");
16602         memInfoBuilder.append("  Lost RAM: ");
16603         memInfoBuilder.append(stringifyKBSize(memInfo.getTotalSizeKb()
16604                 - totalPss - memInfo.getFreeSizeKb() - memInfo.getCachedSizeKb()
16605                 - memInfo.getKernelUsedSizeKb() - memInfo.getZramTotalSizeKb()));
16606         memInfoBuilder.append("\n");
16607         Slog.i(TAG, "Low on memory:");
16608         Slog.i(TAG, shortNativeBuilder.toString());
16609         Slog.i(TAG, fullJavaBuilder.toString());
16610         Slog.i(TAG, memInfoBuilder.toString());
16611
16612         StringBuilder dropBuilder = new StringBuilder(1024);
16613         /*
16614         StringWriter oomSw = new StringWriter();
16615         PrintWriter oomPw = new FastPrintWriter(oomSw, false, 256);
16616         StringWriter catSw = new StringWriter();
16617         PrintWriter catPw = new FastPrintWriter(catSw, false, 256);
16618         String[] emptyArgs = new String[] { };
16619         dumpApplicationMemoryUsage(null, oomPw, "  ", emptyArgs, true, catPw);
16620         oomPw.flush();
16621         String oomString = oomSw.toString();
16622         */
16623         dropBuilder.append("Low on memory:");
16624         dropBuilder.append(stack);
16625         dropBuilder.append('\n');
16626         dropBuilder.append(fullNativeBuilder);
16627         dropBuilder.append(fullJavaBuilder);
16628         dropBuilder.append('\n');
16629         dropBuilder.append(memInfoBuilder);
16630         dropBuilder.append('\n');
16631         /*
16632         dropBuilder.append(oomString);
16633         dropBuilder.append('\n');
16634         */
16635         StringWriter catSw = new StringWriter();
16636         synchronized (ActivityManagerService.this) {
16637             PrintWriter catPw = new FastPrintWriter(catSw, false, 256);
16638             String[] emptyArgs = new String[] { };
16639             catPw.println();
16640             dumpProcessesLocked(null, catPw, emptyArgs, 0, false, null);
16641             catPw.println();
16642             mServices.newServiceDumperLocked(null, catPw, emptyArgs, 0,
16643                     false, null).dumpLocked();
16644             catPw.println();
16645             dumpActivitiesLocked(null, catPw, emptyArgs, 0, false, false, null);
16646             catPw.flush();
16647         }
16648         dropBuilder.append(catSw.toString());
16649         addErrorToDropBox("lowmem", null, "system_server", null,
16650                 null, tag.toString(), dropBuilder.toString(), null, null);
16651         //Slog.i(TAG, "Sent to dropbox:");
16652         //Slog.i(TAG, dropBuilder.toString());
16653         synchronized (ActivityManagerService.this) {
16654             long now = SystemClock.uptimeMillis();
16655             if (mLastMemUsageReportTime < now) {
16656                 mLastMemUsageReportTime = now;
16657             }
16658         }
16659     }
16660
16661     /**
16662      * Searches array of arguments for the specified string
16663      * @param args array of argument strings
16664      * @param value value to search for
16665      * @return true if the value is contained in the array
16666      */
16667     private static boolean scanArgs(String[] args, String value) {
16668         if (args != null) {
16669             for (String arg : args) {
16670                 if (value.equals(arg)) {
16671                     return true;
16672                 }
16673             }
16674         }
16675         return false;
16676     }
16677
16678     private final boolean removeDyingProviderLocked(ProcessRecord proc,
16679             ContentProviderRecord cpr, boolean always) {
16680         final boolean inLaunching = mLaunchingProviders.contains(cpr);
16681
16682         if (!inLaunching || always) {
16683             synchronized (cpr) {
16684                 cpr.launchingApp = null;
16685                 cpr.notifyAll();
16686             }
16687             mProviderMap.removeProviderByClass(cpr.name, UserHandle.getUserId(cpr.uid));
16688             String names[] = cpr.info.authority.split(";");
16689             for (int j = 0; j < names.length; j++) {
16690                 mProviderMap.removeProviderByName(names[j], UserHandle.getUserId(cpr.uid));
16691             }
16692         }
16693
16694         for (int i = cpr.connections.size() - 1; i >= 0; i--) {
16695             ContentProviderConnection conn = cpr.connections.get(i);
16696             if (conn.waiting) {
16697                 // If this connection is waiting for the provider, then we don't
16698                 // need to mess with its process unless we are always removing
16699                 // or for some reason the provider is not currently launching.
16700                 if (inLaunching && !always) {
16701                     continue;
16702                 }
16703             }
16704             ProcessRecord capp = conn.client;
16705             conn.dead = true;
16706             if (conn.stableCount > 0) {
16707                 if (!capp.persistent && capp.thread != null
16708                         && capp.pid != 0
16709                         && capp.pid != MY_PID) {
16710                     capp.kill("depends on provider "
16711                             + cpr.name.flattenToShortString()
16712                             + " in dying proc " + (proc != null ? proc.processName : "??")
16713                             + " (adj " + (proc != null ? proc.setAdj : "??") + ")", true);
16714                 }
16715             } else if (capp.thread != null && conn.provider.provider != null) {
16716                 try {
16717                     capp.thread.unstableProviderDied(conn.provider.provider.asBinder());
16718                 } catch (RemoteException e) {
16719                 }
16720                 // In the protocol here, we don't expect the client to correctly
16721                 // clean up this connection, we'll just remove it.
16722                 cpr.connections.remove(i);
16723                 if (conn.client.conProviders.remove(conn)) {
16724                     stopAssociationLocked(capp.uid, capp.processName, cpr.uid, cpr.name);
16725                 }
16726             }
16727         }
16728
16729         if (inLaunching && always) {
16730             mLaunchingProviders.remove(cpr);
16731         }
16732         return inLaunching;
16733     }
16734
16735     /**
16736      * Main code for cleaning up a process when it has gone away.  This is
16737      * called both as a result of the process dying, or directly when stopping
16738      * a process when running in single process mode.
16739      *
16740      * @return Returns true if the given process has been restarted, so the
16741      * app that was passed in must remain on the process lists.
16742      */
16743     private final boolean cleanUpApplicationRecordLocked(ProcessRecord app,
16744             boolean restarting, boolean allowRestart, int index, boolean replacingPid) {
16745         Slog.d(TAG, "cleanUpApplicationRecord -- " + app.pid);
16746         if (index >= 0) {
16747             removeLruProcessLocked(app);
16748             ProcessList.remove(app.pid);
16749         }
16750
16751         mProcessesToGc.remove(app);
16752         mPendingPssProcesses.remove(app);
16753
16754         // Dismiss any open dialogs.
16755         if (app.crashDialog != null && !app.forceCrashReport) {
16756             app.crashDialog.dismiss();
16757             app.crashDialog = null;
16758         }
16759         if (app.anrDialog != null) {
16760             app.anrDialog.dismiss();
16761             app.anrDialog = null;
16762         }
16763         if (app.waitDialog != null) {
16764             app.waitDialog.dismiss();
16765             app.waitDialog = null;
16766         }
16767
16768         app.crashing = false;
16769         app.notResponding = false;
16770
16771         app.resetPackageList(mProcessStats);
16772         app.unlinkDeathRecipient();
16773         app.makeInactive(mProcessStats);
16774         app.waitingToKill = null;
16775         app.forcingToForeground = null;
16776         updateProcessForegroundLocked(app, false, false);
16777         app.foregroundActivities = false;
16778         app.hasShownUi = false;
16779         app.treatLikeActivity = false;
16780         app.hasAboveClient = false;
16781         app.hasClientActivities = false;
16782
16783         mServices.killServicesLocked(app, allowRestart);
16784
16785         boolean restart = false;
16786
16787         // Remove published content providers.
16788         for (int i = app.pubProviders.size() - 1; i >= 0; i--) {
16789             ContentProviderRecord cpr = app.pubProviders.valueAt(i);
16790             final boolean always = app.bad || !allowRestart;
16791             boolean inLaunching = removeDyingProviderLocked(app, cpr, always);
16792             if ((inLaunching || always) && cpr.hasConnectionOrHandle()) {
16793                 // We left the provider in the launching list, need to
16794                 // restart it.
16795                 restart = true;
16796             }
16797
16798             cpr.provider = null;
16799             cpr.proc = null;
16800         }
16801         app.pubProviders.clear();
16802
16803         // Take care of any launching providers waiting for this process.
16804         if (cleanupAppInLaunchingProvidersLocked(app, false)) {
16805             restart = true;
16806         }
16807
16808         // Unregister from connected content providers.
16809         if (!app.conProviders.isEmpty()) {
16810             for (int i = app.conProviders.size() - 1; i >= 0; i--) {
16811                 ContentProviderConnection conn = app.conProviders.get(i);
16812                 conn.provider.connections.remove(conn);
16813                 stopAssociationLocked(app.uid, app.processName, conn.provider.uid,
16814                         conn.provider.name);
16815             }
16816             app.conProviders.clear();
16817         }
16818
16819         // At this point there may be remaining entries in mLaunchingProviders
16820         // where we were the only one waiting, so they are no longer of use.
16821         // Look for these and clean up if found.
16822         // XXX Commented out for now.  Trying to figure out a way to reproduce
16823         // the actual situation to identify what is actually going on.
16824         if (false) {
16825             for (int i = mLaunchingProviders.size() - 1; i >= 0; i--) {
16826                 ContentProviderRecord cpr = mLaunchingProviders.get(i);
16827                 if (cpr.connections.size() <= 0 && !cpr.hasExternalProcessHandles()) {
16828                     synchronized (cpr) {
16829                         cpr.launchingApp = null;
16830                         cpr.notifyAll();
16831                     }
16832                 }
16833             }
16834         }
16835
16836         skipCurrentReceiverLocked(app);
16837
16838         // Unregister any receivers.
16839         for (int i = app.receivers.size() - 1; i >= 0; i--) {
16840             removeReceiverLocked(app.receivers.valueAt(i));
16841         }
16842         app.receivers.clear();
16843
16844         // If the app is undergoing backup, tell the backup manager about it
16845         if (mBackupTarget != null && app.pid == mBackupTarget.app.pid) {
16846             if (DEBUG_BACKUP || DEBUG_CLEANUP) Slog.d(TAG_CLEANUP, "App "
16847                     + mBackupTarget.appInfo + " died during backup");
16848             try {
16849                 IBackupManager bm = IBackupManager.Stub.asInterface(
16850                         ServiceManager.getService(Context.BACKUP_SERVICE));
16851                 bm.agentDisconnected(app.info.packageName);
16852             } catch (RemoteException e) {
16853                 // can't happen; backup manager is local
16854             }
16855         }
16856
16857         for (int i = mPendingProcessChanges.size() - 1; i >= 0; i--) {
16858             ProcessChangeItem item = mPendingProcessChanges.get(i);
16859             if (item.pid == app.pid) {
16860                 mPendingProcessChanges.remove(i);
16861                 mAvailProcessChanges.add(item);
16862             }
16863         }
16864         mUiHandler.obtainMessage(DISPATCH_PROCESS_DIED_UI_MSG, app.pid, app.info.uid,
16865                 null).sendToTarget();
16866
16867         // If the caller is restarting this app, then leave it in its
16868         // current lists and let the caller take care of it.
16869         if (restarting) {
16870             return false;
16871         }
16872
16873         if (!app.persistent || app.isolated) {
16874             if (DEBUG_PROCESSES || DEBUG_CLEANUP) Slog.v(TAG_CLEANUP,
16875                     "Removing non-persistent process during cleanup: " + app);
16876             if (!replacingPid) {
16877                 removeProcessNameLocked(app.processName, app.uid);
16878             }
16879             if (mHeavyWeightProcess == app) {
16880                 mHandler.sendMessage(mHandler.obtainMessage(CANCEL_HEAVY_NOTIFICATION_MSG,
16881                         mHeavyWeightProcess.userId, 0));
16882                 mHeavyWeightProcess = null;
16883             }
16884         } else if (!app.removed) {
16885             // This app is persistent, so we need to keep its record around.
16886             // If it is not already on the pending app list, add it there
16887             // and start a new process for it.
16888             if (mPersistentStartingProcesses.indexOf(app) < 0) {
16889                 mPersistentStartingProcesses.add(app);
16890                 restart = true;
16891             }
16892         }
16893         if ((DEBUG_PROCESSES || DEBUG_CLEANUP) && mProcessesOnHold.contains(app)) Slog.v(
16894                 TAG_CLEANUP, "Clean-up removing on hold: " + app);
16895         mProcessesOnHold.remove(app);
16896
16897         if (app == mHomeProcess) {
16898             mHomeProcess = null;
16899         }
16900         if (app == mPreviousProcess) {
16901             mPreviousProcess = null;
16902         }
16903
16904         if (restart && !app.isolated) {
16905             // We have components that still need to be running in the
16906             // process, so re-launch it.
16907             if (index < 0) {
16908                 ProcessList.remove(app.pid);
16909             }
16910             addProcessNameLocked(app);
16911             startProcessLocked(app, "restart", app.processName);
16912             return true;
16913         } else if (app.pid > 0 && app.pid != MY_PID) {
16914             // Goodbye!
16915             boolean removed;
16916             synchronized (mPidsSelfLocked) {
16917                 mPidsSelfLocked.remove(app.pid);
16918                 mHandler.removeMessages(PROC_START_TIMEOUT_MSG, app);
16919             }
16920             mBatteryStatsService.noteProcessFinish(app.processName, app.info.uid);
16921             if (app.isolated) {
16922                 mBatteryStatsService.removeIsolatedUid(app.uid, app.info.uid);
16923             }
16924             app.setPid(0);
16925         }
16926         return false;
16927     }
16928
16929     boolean checkAppInLaunchingProvidersLocked(ProcessRecord app) {
16930         for (int i = mLaunchingProviders.size() - 1; i >= 0; i--) {
16931             ContentProviderRecord cpr = mLaunchingProviders.get(i);
16932             if (cpr.launchingApp == app) {
16933                 return true;
16934             }
16935         }
16936         return false;
16937     }
16938
16939     boolean cleanupAppInLaunchingProvidersLocked(ProcessRecord app, boolean alwaysBad) {
16940         // Look through the content providers we are waiting to have launched,
16941         // and if any run in this process then either schedule a restart of
16942         // the process or kill the client waiting for it if this process has
16943         // gone bad.
16944         boolean restart = false;
16945         for (int i = mLaunchingProviders.size() - 1; i >= 0; i--) {
16946             ContentProviderRecord cpr = mLaunchingProviders.get(i);
16947             if (cpr.launchingApp == app) {
16948                 if (!alwaysBad && !app.bad && cpr.hasConnectionOrHandle()) {
16949                     restart = true;
16950                 } else {
16951                     removeDyingProviderLocked(app, cpr, true);
16952                 }
16953             }
16954         }
16955         return restart;
16956     }
16957
16958     // =========================================================
16959     // SERVICES
16960     // =========================================================
16961
16962     @Override
16963     public List<ActivityManager.RunningServiceInfo> getServices(int maxNum,
16964             int flags) {
16965         enforceNotIsolatedCaller("getServices");
16966         synchronized (this) {
16967             return mServices.getRunningServiceInfoLocked(maxNum, flags);
16968         }
16969     }
16970
16971     @Override
16972     public PendingIntent getRunningServiceControlPanel(ComponentName name) {
16973         enforceNotIsolatedCaller("getRunningServiceControlPanel");
16974         synchronized (this) {
16975             return mServices.getRunningServiceControlPanelLocked(name);
16976         }
16977     }
16978
16979     @Override
16980     public ComponentName startService(IApplicationThread caller, Intent service,
16981             String resolvedType, String callingPackage, int userId)
16982             throws TransactionTooLargeException {
16983         enforceNotIsolatedCaller("startService");
16984         // Refuse possible leaked file descriptors
16985         if (service != null && service.hasFileDescriptors() == true) {
16986             throw new IllegalArgumentException("File descriptors passed in Intent");
16987         }
16988
16989         if (callingPackage == null) {
16990             throw new IllegalArgumentException("callingPackage cannot be null");
16991         }
16992
16993         if (DEBUG_SERVICE) Slog.v(TAG_SERVICE,
16994                 "startService: " + service + " type=" + resolvedType);
16995         synchronized(this) {
16996             final int callingPid = Binder.getCallingPid();
16997             final int callingUid = Binder.getCallingUid();
16998             final long origId = Binder.clearCallingIdentity();
16999             ComponentName res = mServices.startServiceLocked(caller, service,
17000                     resolvedType, callingPid, callingUid, callingPackage, userId);
17001             Binder.restoreCallingIdentity(origId);
17002             return res;
17003         }
17004     }
17005
17006     ComponentName startServiceInPackage(int uid, Intent service, String resolvedType,
17007             String callingPackage, int userId)
17008             throws TransactionTooLargeException {
17009         synchronized(this) {
17010             if (DEBUG_SERVICE) Slog.v(TAG_SERVICE,
17011                     "startServiceInPackage: " + service + " type=" + resolvedType);
17012             final long origId = Binder.clearCallingIdentity();
17013             ComponentName res = mServices.startServiceLocked(null, service,
17014                     resolvedType, -1, uid, callingPackage, userId);
17015             Binder.restoreCallingIdentity(origId);
17016             return res;
17017         }
17018     }
17019
17020     @Override
17021     public int stopService(IApplicationThread caller, Intent service,
17022             String resolvedType, int userId) {
17023         enforceNotIsolatedCaller("stopService");
17024         // Refuse possible leaked file descriptors
17025         if (service != null && service.hasFileDescriptors() == true) {
17026             throw new IllegalArgumentException("File descriptors passed in Intent");
17027         }
17028
17029         synchronized(this) {
17030             return mServices.stopServiceLocked(caller, service, resolvedType, userId);
17031         }
17032     }
17033
17034     @Override
17035     public IBinder peekService(Intent service, String resolvedType, String callingPackage) {
17036         enforceNotIsolatedCaller("peekService");
17037         // Refuse possible leaked file descriptors
17038         if (service != null && service.hasFileDescriptors() == true) {
17039             throw new IllegalArgumentException("File descriptors passed in Intent");
17040         }
17041
17042         if (callingPackage == null) {
17043             throw new IllegalArgumentException("callingPackage cannot be null");
17044         }
17045
17046         synchronized(this) {
17047             return mServices.peekServiceLocked(service, resolvedType, callingPackage);
17048         }
17049     }
17050
17051     @Override
17052     public boolean stopServiceToken(ComponentName className, IBinder token,
17053             int startId) {
17054         synchronized(this) {
17055             return mServices.stopServiceTokenLocked(className, token, startId);
17056         }
17057     }
17058
17059     @Override
17060     public void setServiceForeground(ComponentName className, IBinder token,
17061             int id, Notification notification, int flags) {
17062         synchronized(this) {
17063             mServices.setServiceForegroundLocked(className, token, id, notification, flags);
17064         }
17065     }
17066
17067     @Override
17068     public int handleIncomingUser(int callingPid, int callingUid, int userId, boolean allowAll,
17069             boolean requireFull, String name, String callerPackage) {
17070         return mUserController.handleIncomingUser(callingPid, callingUid, userId, allowAll,
17071                 requireFull ? ALLOW_FULL_ONLY : ALLOW_NON_FULL, name, callerPackage);
17072     }
17073
17074     boolean isSingleton(String componentProcessName, ApplicationInfo aInfo,
17075             String className, int flags) {
17076         boolean result = false;
17077         // For apps that don't have pre-defined UIDs, check for permission
17078         if (UserHandle.getAppId(aInfo.uid) >= Process.FIRST_APPLICATION_UID) {
17079             if ((flags & ServiceInfo.FLAG_SINGLE_USER) != 0) {
17080                 if (ActivityManager.checkUidPermission(
17081                         INTERACT_ACROSS_USERS,
17082                         aInfo.uid) != PackageManager.PERMISSION_GRANTED) {
17083                     ComponentName comp = new ComponentName(aInfo.packageName, className);
17084                     String msg = "Permission Denial: Component " + comp.flattenToShortString()
17085                             + " requests FLAG_SINGLE_USER, but app does not hold "
17086                             + INTERACT_ACROSS_USERS;
17087                     Slog.w(TAG, msg);
17088                     throw new SecurityException(msg);
17089                 }
17090                 // Permission passed
17091                 result = true;
17092             }
17093         } else if ("system".equals(componentProcessName)) {
17094             result = true;
17095         } else if ((flags & ServiceInfo.FLAG_SINGLE_USER) != 0) {
17096             // Phone app and persistent apps are allowed to export singleuser providers.
17097             result = UserHandle.isSameApp(aInfo.uid, Process.PHONE_UID)
17098                     || (aInfo.flags & ApplicationInfo.FLAG_PERSISTENT) != 0;
17099         }
17100         if (DEBUG_MU) Slog.v(TAG_MU,
17101                 "isSingleton(" + componentProcessName + ", " + aInfo + ", " + className + ", 0x"
17102                 + Integer.toHexString(flags) + ") = " + result);
17103         return result;
17104     }
17105
17106     /**
17107      * Checks to see if the caller is in the same app as the singleton
17108      * component, or the component is in a special app. It allows special apps
17109      * to export singleton components but prevents exporting singleton
17110      * components for regular apps.
17111      */
17112     boolean isValidSingletonCall(int callingUid, int componentUid) {
17113         int componentAppId = UserHandle.getAppId(componentUid);
17114         return UserHandle.isSameApp(callingUid, componentUid)
17115                 || componentAppId == Process.SYSTEM_UID
17116                 || componentAppId == Process.PHONE_UID
17117                 || ActivityManager.checkUidPermission(INTERACT_ACROSS_USERS_FULL, componentUid)
17118                         == PackageManager.PERMISSION_GRANTED;
17119     }
17120
17121     public int bindService(IApplicationThread caller, IBinder token, Intent service,
17122             String resolvedType, IServiceConnection connection, int flags, String callingPackage,
17123             int userId) throws TransactionTooLargeException {
17124         enforceNotIsolatedCaller("bindService");
17125
17126         // Refuse possible leaked file descriptors
17127         if (service != null && service.hasFileDescriptors() == true) {
17128             throw new IllegalArgumentException("File descriptors passed in Intent");
17129         }
17130
17131         if (callingPackage == null) {
17132             throw new IllegalArgumentException("callingPackage cannot be null");
17133         }
17134
17135         synchronized(this) {
17136             return mServices.bindServiceLocked(caller, token, service,
17137                     resolvedType, connection, flags, callingPackage, userId);
17138         }
17139     }
17140
17141     public boolean unbindService(IServiceConnection connection) {
17142         synchronized (this) {
17143             return mServices.unbindServiceLocked(connection);
17144         }
17145     }
17146
17147     public void publishService(IBinder token, Intent intent, IBinder service) {
17148         // Refuse possible leaked file descriptors
17149         if (intent != null && intent.hasFileDescriptors() == true) {
17150             throw new IllegalArgumentException("File descriptors passed in Intent");
17151         }
17152
17153         synchronized(this) {
17154             if (!(token instanceof ServiceRecord)) {
17155                 throw new IllegalArgumentException("Invalid service token");
17156             }
17157             mServices.publishServiceLocked((ServiceRecord)token, intent, service);
17158         }
17159     }
17160
17161     public void unbindFinished(IBinder token, Intent intent, boolean doRebind) {
17162         // Refuse possible leaked file descriptors
17163         if (intent != null && intent.hasFileDescriptors() == true) {
17164             throw new IllegalArgumentException("File descriptors passed in Intent");
17165         }
17166
17167         synchronized(this) {
17168             mServices.unbindFinishedLocked((ServiceRecord)token, intent, doRebind);
17169         }
17170     }
17171
17172     public void serviceDoneExecuting(IBinder token, int type, int startId, int res) {
17173         synchronized(this) {
17174             if (!(token instanceof ServiceRecord)) {
17175                 Slog.e(TAG, "serviceDoneExecuting: Invalid service token=" + token);
17176                 throw new IllegalArgumentException("Invalid service token");
17177             }
17178             mServices.serviceDoneExecutingLocked((ServiceRecord)token, type, startId, res);
17179         }
17180     }
17181
17182     // =========================================================
17183     // BACKUP AND RESTORE
17184     // =========================================================
17185
17186     // Cause the target app to be launched if necessary and its backup agent
17187     // instantiated.  The backup agent will invoke backupAgentCreated() on the
17188     // activity manager to announce its creation.
17189     public boolean bindBackupAgent(String packageName, int backupMode, int userId) {
17190         if (DEBUG_BACKUP) Slog.v(TAG, "bindBackupAgent: app=" + packageName + " mode=" + backupMode);
17191         enforceCallingPermission("android.permission.CONFIRM_FULL_BACKUP", "bindBackupAgent");
17192
17193         IPackageManager pm = AppGlobals.getPackageManager();
17194         ApplicationInfo app = null;
17195         try {
17196             app = pm.getApplicationInfo(packageName, 0, userId);
17197         } catch (RemoteException e) {
17198             // can't happen; package manager is process-local
17199         }
17200         if (app == null) {
17201             Slog.w(TAG, "Unable to bind backup agent for " + packageName);
17202             return false;
17203         }
17204
17205         synchronized(this) {
17206             // !!! TODO: currently no check here that we're already bound
17207             BatteryStatsImpl.Uid.Pkg.Serv ss = null;
17208             BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
17209             synchronized (stats) {
17210                 ss = stats.getServiceStatsLocked(app.uid, app.packageName, app.name);
17211             }
17212
17213             // Backup agent is now in use, its package can't be stopped.
17214             try {
17215                 AppGlobals.getPackageManager().setPackageStoppedState(
17216                         app.packageName, false, UserHandle.getUserId(app.uid));
17217             } catch (RemoteException e) {
17218             } catch (IllegalArgumentException e) {
17219                 Slog.w(TAG, "Failed trying to unstop package "
17220                         + app.packageName + ": " + e);
17221             }
17222
17223             BackupRecord r = new BackupRecord(ss, app, backupMode);
17224             ComponentName hostingName = (backupMode == IApplicationThread.BACKUP_MODE_INCREMENTAL)
17225                     ? new ComponentName(app.packageName, app.backupAgentName)
17226                     : new ComponentName("android", "FullBackupAgent");
17227             // startProcessLocked() returns existing proc's record if it's already running
17228             ProcessRecord proc = startProcessLocked(app.processName, app,
17229                     false, 0, "backup", hostingName, false, false, false);
17230             if (proc == null) {
17231                 Slog.e(TAG, "Unable to start backup agent process " + r);
17232                 return false;
17233             }
17234
17235             // If the app is a regular app (uid >= 10000) and not the system server or phone
17236             // process, etc, then mark it as being in full backup so that certain calls to the
17237             // process can be blocked. This is not reset to false anywhere because we kill the
17238             // process after the full backup is done and the ProcessRecord will vaporize anyway.
17239             if (UserHandle.isApp(app.uid) && backupMode == IApplicationThread.BACKUP_MODE_FULL) {
17240                 proc.inFullBackup = true;
17241             }
17242             r.app = proc;
17243             mBackupTarget = r;
17244             mBackupAppName = app.packageName;
17245
17246             // Try not to kill the process during backup
17247             updateOomAdjLocked(proc);
17248
17249             // If the process is already attached, schedule the creation of the backup agent now.
17250             // If it is not yet live, this will be done when it attaches to the framework.
17251             if (proc.thread != null) {
17252                 if (DEBUG_BACKUP) Slog.v(TAG_BACKUP, "Agent proc already running: " + proc);
17253                 try {
17254                     proc.thread.scheduleCreateBackupAgent(app,
17255                             compatibilityInfoForPackageLocked(app), backupMode);
17256                 } catch (RemoteException e) {
17257                     // Will time out on the backup manager side
17258                 }
17259             } else {
17260                 if (DEBUG_BACKUP) Slog.v(TAG_BACKUP, "Agent proc not running, waiting for attach");
17261             }
17262             // Invariants: at this point, the target app process exists and the application
17263             // is either already running or in the process of coming up.  mBackupTarget and
17264             // mBackupAppName describe the app, so that when it binds back to the AM we
17265             // know that it's scheduled for a backup-agent operation.
17266         }
17267
17268         return true;
17269     }
17270
17271     @Override
17272     public void clearPendingBackup() {
17273         if (DEBUG_BACKUP) Slog.v(TAG_BACKUP, "clearPendingBackup");
17274         enforceCallingPermission("android.permission.BACKUP", "clearPendingBackup");
17275
17276         synchronized (this) {
17277             mBackupTarget = null;
17278             mBackupAppName = null;
17279         }
17280     }
17281
17282     // A backup agent has just come up
17283     public void backupAgentCreated(String agentPackageName, IBinder agent) {
17284         if (DEBUG_BACKUP) Slog.v(TAG_BACKUP, "backupAgentCreated: " + agentPackageName
17285                 + " = " + agent);
17286
17287         synchronized(this) {
17288             if (!agentPackageName.equals(mBackupAppName)) {
17289                 Slog.e(TAG, "Backup agent created for " + agentPackageName + " but not requested!");
17290                 return;
17291             }
17292         }
17293
17294         long oldIdent = Binder.clearCallingIdentity();
17295         try {
17296             IBackupManager bm = IBackupManager.Stub.asInterface(
17297                     ServiceManager.getService(Context.BACKUP_SERVICE));
17298             bm.agentConnected(agentPackageName, agent);
17299         } catch (RemoteException e) {
17300             // can't happen; the backup manager service is local
17301         } catch (Exception e) {
17302             Slog.w(TAG, "Exception trying to deliver BackupAgent binding: ");
17303             e.printStackTrace();
17304         } finally {
17305             Binder.restoreCallingIdentity(oldIdent);
17306         }
17307     }
17308
17309     // done with this agent
17310     public void unbindBackupAgent(ApplicationInfo appInfo) {
17311         if (DEBUG_BACKUP) Slog.v(TAG_BACKUP, "unbindBackupAgent: " + appInfo);
17312         if (appInfo == null) {
17313             Slog.w(TAG, "unbind backup agent for null app");
17314             return;
17315         }
17316
17317         synchronized(this) {
17318             try {
17319                 if (mBackupAppName == null) {
17320                     Slog.w(TAG, "Unbinding backup agent with no active backup");
17321                     return;
17322                 }
17323
17324                 if (!mBackupAppName.equals(appInfo.packageName)) {
17325                     Slog.e(TAG, "Unbind of " + appInfo + " but is not the current backup target");
17326                     return;
17327                 }
17328
17329                 // Not backing this app up any more; reset its OOM adjustment
17330                 final ProcessRecord proc = mBackupTarget.app;
17331                 updateOomAdjLocked(proc);
17332
17333                 // If the app crashed during backup, 'thread' will be null here
17334                 if (proc.thread != null) {
17335                     try {
17336                         proc.thread.scheduleDestroyBackupAgent(appInfo,
17337                                 compatibilityInfoForPackageLocked(appInfo));
17338                     } catch (Exception e) {
17339                         Slog.e(TAG, "Exception when unbinding backup agent:");
17340                         e.printStackTrace();
17341                     }
17342                 }
17343             } finally {
17344                 mBackupTarget = null;
17345                 mBackupAppName = null;
17346             }
17347         }
17348     }
17349     // =========================================================
17350     // BROADCASTS
17351     // =========================================================
17352
17353     boolean isPendingBroadcastProcessLocked(int pid) {
17354         return mFgBroadcastQueue.isPendingBroadcastProcessLocked(pid)
17355                 || mBgBroadcastQueue.isPendingBroadcastProcessLocked(pid);
17356     }
17357
17358     void skipPendingBroadcastLocked(int pid) {
17359             Slog.w(TAG, "Unattached app died before broadcast acknowledged, skipping");
17360             for (BroadcastQueue queue : mBroadcastQueues) {
17361                 queue.skipPendingBroadcastLocked(pid);
17362             }
17363     }
17364
17365     // The app just attached; send any pending broadcasts that it should receive
17366     boolean sendPendingBroadcastsLocked(ProcessRecord app) {
17367         boolean didSomething = false;
17368         for (BroadcastQueue queue : mBroadcastQueues) {
17369             didSomething |= queue.sendPendingBroadcastsLocked(app);
17370         }
17371         return didSomething;
17372     }
17373
17374     public Intent registerReceiver(IApplicationThread caller, String callerPackage,
17375             IIntentReceiver receiver, IntentFilter filter, String permission, int userId) {
17376         enforceNotIsolatedCaller("registerReceiver");
17377         ArrayList<Intent> stickyIntents = null;
17378         ProcessRecord callerApp = null;
17379         int callingUid;
17380         int callingPid;
17381         synchronized(this) {
17382             if (caller != null) {
17383                 callerApp = getRecordForAppLocked(caller);
17384                 if (callerApp == null) {
17385                     throw new SecurityException(
17386                             "Unable to find app for caller " + caller
17387                             + " (pid=" + Binder.getCallingPid()
17388                             + ") when registering receiver " + receiver);
17389                 }
17390                 if (callerApp.info.uid != Process.SYSTEM_UID &&
17391                         !callerApp.pkgList.containsKey(callerPackage) &&
17392                         !"android".equals(callerPackage)) {
17393                     throw new SecurityException("Given caller package " + callerPackage
17394                             + " is not running in process " + callerApp);
17395                 }
17396                 callingUid = callerApp.info.uid;
17397                 callingPid = callerApp.pid;
17398             } else {
17399                 callerPackage = null;
17400                 callingUid = Binder.getCallingUid();
17401                 callingPid = Binder.getCallingPid();
17402             }
17403
17404             userId = mUserController.handleIncomingUser(callingPid, callingUid, userId, true,
17405                     ALLOW_FULL_ONLY, "registerReceiver", callerPackage);
17406
17407             Iterator<String> actions = filter.actionsIterator();
17408             if (actions == null) {
17409                 ArrayList<String> noAction = new ArrayList<String>(1);
17410                 noAction.add(null);
17411                 actions = noAction.iterator();
17412             }
17413
17414             // Collect stickies of users
17415             int[] userIds = { UserHandle.USER_ALL, UserHandle.getUserId(callingUid) };
17416             while (actions.hasNext()) {
17417                 String action = actions.next();
17418                 for (int id : userIds) {
17419                     ArrayMap<String, ArrayList<Intent>> stickies = mStickyBroadcasts.get(id);
17420                     if (stickies != null) {
17421                         ArrayList<Intent> intents = stickies.get(action);
17422                         if (intents != null) {
17423                             if (stickyIntents == null) {
17424                                 stickyIntents = new ArrayList<Intent>();
17425                             }
17426                             stickyIntents.addAll(intents);
17427                         }
17428                     }
17429                 }
17430             }
17431         }
17432
17433         ArrayList<Intent> allSticky = null;
17434         if (stickyIntents != null) {
17435             final ContentResolver resolver = mContext.getContentResolver();
17436             // Look for any matching sticky broadcasts...
17437             for (int i = 0, N = stickyIntents.size(); i < N; i++) {
17438                 Intent intent = stickyIntents.get(i);
17439                 // If intent has scheme "content", it will need to acccess
17440                 // provider that needs to lock mProviderMap in ActivityThread
17441                 // and also it may need to wait application response, so we
17442                 // cannot lock ActivityManagerService here.
17443                 if (filter.match(resolver, intent, true, TAG) >= 0) {
17444                     if (allSticky == null) {
17445                         allSticky = new ArrayList<Intent>();
17446                     }
17447                     allSticky.add(intent);
17448                 }
17449             }
17450         }
17451
17452         // The first sticky in the list is returned directly back to the client.
17453         Intent sticky = allSticky != null ? allSticky.get(0) : null;
17454         if (DEBUG_BROADCAST) Slog.v(TAG_BROADCAST, "Register receiver " + filter + ": " + sticky);
17455         if (receiver == null) {
17456             return sticky;
17457         }
17458
17459         synchronized (this) {
17460             if (callerApp != null && (callerApp.thread == null
17461                     || callerApp.thread.asBinder() != caller.asBinder())) {
17462                 // Original caller already died
17463                 return null;
17464             }
17465             ReceiverList rl = mRegisteredReceivers.get(receiver.asBinder());
17466             if (rl == null) {
17467                 rl = new ReceiverList(this, callerApp, callingPid, callingUid,
17468                         userId, receiver);
17469                 if (rl.app != null) {
17470                     rl.app.receivers.add(rl);
17471                 } else {
17472                     try {
17473                         receiver.asBinder().linkToDeath(rl, 0);
17474                     } catch (RemoteException e) {
17475                         return sticky;
17476                     }
17477                     rl.linkedToDeath = true;
17478                 }
17479                 mRegisteredReceivers.put(receiver.asBinder(), rl);
17480             } else if (rl.uid != callingUid) {
17481                 throw new IllegalArgumentException(
17482                         "Receiver requested to register for uid " + callingUid
17483                         + " was previously registered for uid " + rl.uid);
17484             } else if (rl.pid != callingPid) {
17485                 throw new IllegalArgumentException(
17486                         "Receiver requested to register for pid " + callingPid
17487                         + " was previously registered for pid " + rl.pid);
17488             } else if (rl.userId != userId) {
17489                 throw new IllegalArgumentException(
17490                         "Receiver requested to register for user " + userId
17491                         + " was previously registered for user " + rl.userId);
17492             }
17493             BroadcastFilter bf = new BroadcastFilter(filter, rl, callerPackage,
17494                     permission, callingUid, userId);
17495             rl.add(bf);
17496             if (!bf.debugCheck()) {
17497                 Slog.w(TAG, "==> For Dynamic broadcast");
17498             }
17499             mReceiverResolver.addFilter(bf);
17500
17501             // Enqueue broadcasts for all existing stickies that match
17502             // this filter.
17503             if (allSticky != null) {
17504                 ArrayList receivers = new ArrayList();
17505                 receivers.add(bf);
17506
17507                 final int stickyCount = allSticky.size();
17508                 for (int i = 0; i < stickyCount; i++) {
17509                     Intent intent = allSticky.get(i);
17510                     BroadcastQueue queue = broadcastQueueForIntent(intent);
17511                     BroadcastRecord r = new BroadcastRecord(queue, intent, null,
17512                             null, -1, -1, null, null, AppOpsManager.OP_NONE, null, receivers,
17513                             null, 0, null, null, false, true, true, -1);
17514                     queue.enqueueParallelBroadcastLocked(r);
17515                     queue.scheduleBroadcastsLocked();
17516                 }
17517             }
17518
17519             return sticky;
17520         }
17521     }
17522
17523     public void unregisterReceiver(IIntentReceiver receiver) {
17524         if (DEBUG_BROADCAST) Slog.v(TAG_BROADCAST, "Unregister receiver: " + receiver);
17525
17526         final long origId = Binder.clearCallingIdentity();
17527         try {
17528             boolean doTrim = false;
17529
17530             synchronized(this) {
17531                 ReceiverList rl = mRegisteredReceivers.get(receiver.asBinder());
17532                 if (rl != null) {
17533                     final BroadcastRecord r = rl.curBroadcast;
17534                     if (r != null && r == r.queue.getMatchingOrderedReceiver(r)) {
17535                         final boolean doNext = r.queue.finishReceiverLocked(
17536                                 r, r.resultCode, r.resultData, r.resultExtras,
17537                                 r.resultAbort, false);
17538                         if (doNext) {
17539                             doTrim = true;
17540                             r.queue.processNextBroadcast(false);
17541                         }
17542                     }
17543
17544                     if (rl.app != null) {
17545                         rl.app.receivers.remove(rl);
17546                     }
17547                     removeReceiverLocked(rl);
17548                     if (rl.linkedToDeath) {
17549                         rl.linkedToDeath = false;
17550                         rl.receiver.asBinder().unlinkToDeath(rl, 0);
17551                     }
17552                 }
17553             }
17554
17555             // If we actually concluded any broadcasts, we might now be able
17556             // to trim the recipients' apps from our working set
17557             if (doTrim) {
17558                 trimApplications();
17559                 return;
17560             }
17561
17562         } finally {
17563             Binder.restoreCallingIdentity(origId);
17564         }
17565     }
17566
17567     void removeReceiverLocked(ReceiverList rl) {
17568         mRegisteredReceivers.remove(rl.receiver.asBinder());
17569         for (int i = rl.size() - 1; i >= 0; i--) {
17570             mReceiverResolver.removeFilter(rl.get(i));
17571         }
17572     }
17573
17574     private final void sendPackageBroadcastLocked(int cmd, String[] packages, int userId) {
17575         for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) {
17576             ProcessRecord r = mLruProcesses.get(i);
17577             if (r.thread != null && (userId == UserHandle.USER_ALL || r.userId == userId)) {
17578                 try {
17579                     r.thread.dispatchPackageBroadcast(cmd, packages);
17580                 } catch (RemoteException ex) {
17581                 }
17582             }
17583         }
17584     }
17585
17586     private List<ResolveInfo> collectReceiverComponents(Intent intent, String resolvedType,
17587             int callingUid, int[] users) {
17588         // TODO: come back and remove this assumption to triage all broadcasts
17589         int pmFlags = STOCK_PM_FLAGS | MATCH_DEBUG_TRIAGED_MISSING;
17590
17591         List<ResolveInfo> receivers = null;
17592         try {
17593             HashSet<ComponentName> singleUserReceivers = null;
17594             boolean scannedFirstReceivers = false;
17595             for (int user : users) {
17596                 // Skip users that have Shell restrictions, with exception of always permitted
17597                 // Shell broadcasts
17598                 if (callingUid == Process.SHELL_UID
17599                         && mUserController.hasUserRestriction(
17600                                 UserManager.DISALLOW_DEBUGGING_FEATURES, user)
17601                         && !isPermittedShellBroadcast(intent)) {
17602                     continue;
17603                 }
17604                 List<ResolveInfo> newReceivers = AppGlobals.getPackageManager()
17605                         .queryIntentReceivers(intent, resolvedType, pmFlags, user).getList();
17606                 if (user != UserHandle.USER_SYSTEM && newReceivers != null) {
17607                     // If this is not the system user, we need to check for
17608                     // any receivers that should be filtered out.
17609                     for (int i=0; i<newReceivers.size(); i++) {
17610                         ResolveInfo ri = newReceivers.get(i);
17611                         if ((ri.activityInfo.flags&ActivityInfo.FLAG_SYSTEM_USER_ONLY) != 0) {
17612                             newReceivers.remove(i);
17613                             i--;
17614                         }
17615                     }
17616                 }
17617                 if (newReceivers != null && newReceivers.size() == 0) {
17618                     newReceivers = null;
17619                 }
17620                 if (receivers == null) {
17621                     receivers = newReceivers;
17622                 } else if (newReceivers != null) {
17623                     // We need to concatenate the additional receivers
17624                     // found with what we have do far.  This would be easy,
17625                     // but we also need to de-dup any receivers that are
17626                     // singleUser.
17627                     if (!scannedFirstReceivers) {
17628                         // Collect any single user receivers we had already retrieved.
17629                         scannedFirstReceivers = true;
17630                         for (int i=0; i<receivers.size(); i++) {
17631                             ResolveInfo ri = receivers.get(i);
17632                             if ((ri.activityInfo.flags&ActivityInfo.FLAG_SINGLE_USER) != 0) {
17633                                 ComponentName cn = new ComponentName(
17634                                         ri.activityInfo.packageName, ri.activityInfo.name);
17635                                 if (singleUserReceivers == null) {
17636                                     singleUserReceivers = new HashSet<ComponentName>();
17637                                 }
17638                                 singleUserReceivers.add(cn);
17639                             }
17640                         }
17641                     }
17642                     // Add the new results to the existing results, tracking
17643                     // and de-dupping single user receivers.
17644                     for (int i=0; i<newReceivers.size(); i++) {
17645                         ResolveInfo ri = newReceivers.get(i);
17646                         if ((ri.activityInfo.flags&ActivityInfo.FLAG_SINGLE_USER) != 0) {
17647                             ComponentName cn = new ComponentName(
17648                                     ri.activityInfo.packageName, ri.activityInfo.name);
17649                             if (singleUserReceivers == null) {
17650                                 singleUserReceivers = new HashSet<ComponentName>();
17651                             }
17652                             if (!singleUserReceivers.contains(cn)) {
17653                                 singleUserReceivers.add(cn);
17654                                 receivers.add(ri);
17655                             }
17656                         } else {
17657                             receivers.add(ri);
17658                         }
17659                     }
17660                 }
17661             }
17662         } catch (RemoteException ex) {
17663             // pm is in same process, this will never happen.
17664         }
17665         return receivers;
17666     }
17667
17668     private boolean isPermittedShellBroadcast(Intent intent) {
17669         // remote bugreport should always be allowed to be taken
17670         return INTENT_REMOTE_BUGREPORT_FINISHED.equals(intent.getAction());
17671     }
17672
17673     final int broadcastIntentLocked(ProcessRecord callerApp,
17674             String callerPackage, Intent intent, String resolvedType,
17675             IIntentReceiver resultTo, int resultCode, String resultData,
17676             Bundle resultExtras, String[] requiredPermissions, int appOp, Bundle bOptions,
17677             boolean ordered, boolean sticky, int callingPid, int callingUid, int userId) {
17678         intent = new Intent(intent);
17679
17680         // By default broadcasts do not go to stopped apps.
17681         intent.addFlags(Intent.FLAG_EXCLUDE_STOPPED_PACKAGES);
17682
17683         // If we have not finished booting, don't allow this to launch new processes.
17684         if (!mProcessesReady && (intent.getFlags()&Intent.FLAG_RECEIVER_BOOT_UPGRADE) == 0) {
17685             intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY);
17686         }
17687
17688         if (DEBUG_BROADCAST_LIGHT) Slog.v(TAG_BROADCAST,
17689                 (sticky ? "Broadcast sticky: ": "Broadcast: ") + intent
17690                 + " ordered=" + ordered + " userid=" + userId);
17691         if ((resultTo != null) && !ordered) {
17692             Slog.w(TAG, "Broadcast " + intent + " not ordered but result callback requested!");
17693         }
17694
17695         userId = mUserController.handleIncomingUser(callingPid, callingUid, userId, true,
17696                 ALLOW_NON_FULL, "broadcast", callerPackage);
17697
17698         // Make sure that the user who is receiving this broadcast is running.
17699         // If not, we will just skip it. Make an exception for shutdown broadcasts
17700         // and upgrade steps.
17701
17702         if (userId != UserHandle.USER_ALL && !mUserController.isUserRunningLocked(userId, 0)) {
17703             if ((callingUid != Process.SYSTEM_UID
17704                     || (intent.getFlags() & Intent.FLAG_RECEIVER_BOOT_UPGRADE) == 0)
17705                     && !Intent.ACTION_SHUTDOWN.equals(intent.getAction())) {
17706                 Slog.w(TAG, "Skipping broadcast of " + intent
17707                         + ": user " + userId + " is stopped");
17708                 return ActivityManager.BROADCAST_FAILED_USER_STOPPED;
17709             }
17710         }
17711
17712         BroadcastOptions brOptions = null;
17713         if (bOptions != null) {
17714             brOptions = new BroadcastOptions(bOptions);
17715             if (brOptions.getTemporaryAppWhitelistDuration() > 0) {
17716                 // See if the caller is allowed to do this.  Note we are checking against
17717                 // the actual real caller (not whoever provided the operation as say a
17718                 // PendingIntent), because that who is actually supplied the arguments.
17719                 if (checkComponentPermission(
17720                         android.Manifest.permission.CHANGE_DEVICE_IDLE_TEMP_WHITELIST,
17721                         Binder.getCallingPid(), Binder.getCallingUid(), -1, true)
17722                         != PackageManager.PERMISSION_GRANTED) {
17723                     String msg = "Permission Denial: " + intent.getAction()
17724                             + " broadcast from " + callerPackage + " (pid=" + callingPid
17725                             + ", uid=" + callingUid + ")"
17726                             + " requires "
17727                             + android.Manifest.permission.CHANGE_DEVICE_IDLE_TEMP_WHITELIST;
17728                     Slog.w(TAG, msg);
17729                     throw new SecurityException(msg);
17730                 }
17731             }
17732         }
17733
17734         // Verify that protected broadcasts are only being sent by system code,
17735         // and that system code is only sending protected broadcasts.
17736         final String action = intent.getAction();
17737         final boolean isProtectedBroadcast;
17738         try {
17739             isProtectedBroadcast = AppGlobals.getPackageManager().isProtectedBroadcast(action);
17740         } catch (RemoteException e) {
17741             Slog.w(TAG, "Remote exception", e);
17742             return ActivityManager.BROADCAST_SUCCESS;
17743         }
17744
17745         final boolean isCallerSystem;
17746         switch (UserHandle.getAppId(callingUid)) {
17747             case Process.ROOT_UID:
17748             case Process.SYSTEM_UID:
17749             case Process.PHONE_UID:
17750             case Process.BLUETOOTH_UID:
17751             case Process.NFC_UID:
17752                 isCallerSystem = true;
17753                 break;
17754             default:
17755                 isCallerSystem = (callerApp != null) && callerApp.persistent;
17756                 break;
17757         }
17758
17759         if (isCallerSystem) {
17760             if (isProtectedBroadcast
17761                     || Intent.ACTION_CLOSE_SYSTEM_DIALOGS.equals(action)
17762                     || Intent.ACTION_DISMISS_KEYBOARD_SHORTCUTS.equals(action)
17763                     || Intent.ACTION_MEDIA_BUTTON.equals(action)
17764                     || Intent.ACTION_MEDIA_SCANNER_SCAN_FILE.equals(action)
17765                     || Intent.ACTION_SHOW_KEYBOARD_SHORTCUTS.equals(action)
17766                     || AppWidgetManager.ACTION_APPWIDGET_CONFIGURE.equals(action)
17767                     || AppWidgetManager.ACTION_APPWIDGET_UPDATE.equals(action)
17768                     || LocationManager.HIGH_POWER_REQUEST_CHANGE_ACTION.equals(action)
17769                     || TelephonyIntents.ACTION_REQUEST_OMADM_CONFIGURATION_UPDATE.equals(action)
17770                     || SuggestionSpan.ACTION_SUGGESTION_PICKED.equals(action)) {
17771                 // Broadcast is either protected, or it's a public action that
17772                 // we've relaxed, so it's fine for system internals to send.
17773             } else {
17774                 // The vast majority of broadcasts sent from system internals
17775                 // should be protected to avoid security holes, so yell loudly
17776                 // to ensure we examine these cases.
17777                 if (callerApp != null) {
17778                     Log.wtf(TAG, "Sending non-protected broadcast " + action
17779                             + " from system " + callerApp.toShortString() + " pkg " + callerPackage,
17780                             new Throwable());
17781                 } else {
17782                     Log.wtf(TAG, "Sending non-protected broadcast " + action
17783                             + " from system uid " + UserHandle.formatUid(callingUid)
17784                             + " pkg " + callerPackage,
17785                             new Throwable());
17786                 }
17787             }
17788
17789         } else {
17790             if (isProtectedBroadcast) {
17791                 String msg = "Permission Denial: not allowed to send broadcast "
17792                         + action + " from pid="
17793                         + callingPid + ", uid=" + callingUid;
17794                 Slog.w(TAG, msg);
17795                 throw new SecurityException(msg);
17796
17797             } else if (AppWidgetManager.ACTION_APPWIDGET_CONFIGURE.equals(action)
17798                     || AppWidgetManager.ACTION_APPWIDGET_UPDATE.equals(action)) {
17799                 // Special case for compatibility: we don't want apps to send this,
17800                 // but historically it has not been protected and apps may be using it
17801                 // to poke their own app widget.  So, instead of making it protected,
17802                 // just limit it to the caller.
17803                 if (callerPackage == null) {
17804                     String msg = "Permission Denial: not allowed to send broadcast "
17805                             + action + " from unknown caller.";
17806                     Slog.w(TAG, msg);
17807                     throw new SecurityException(msg);
17808                 } else if (intent.getComponent() != null) {
17809                     // They are good enough to send to an explicit component...  verify
17810                     // it is being sent to the calling app.
17811                     if (!intent.getComponent().getPackageName().equals(
17812                             callerPackage)) {
17813                         String msg = "Permission Denial: not allowed to send broadcast "
17814                                 + action + " to "
17815                                 + intent.getComponent().getPackageName() + " from "
17816                                 + callerPackage;
17817                         Slog.w(TAG, msg);
17818                         throw new SecurityException(msg);
17819                     }
17820                 } else {
17821                     // Limit broadcast to their own package.
17822                     intent.setPackage(callerPackage);
17823                 }
17824             }
17825         }
17826
17827         if (action != null) {
17828             switch (action) {
17829                 case Intent.ACTION_UID_REMOVED:
17830                 case Intent.ACTION_PACKAGE_REMOVED:
17831                 case Intent.ACTION_PACKAGE_CHANGED:
17832                 case Intent.ACTION_EXTERNAL_APPLICATIONS_UNAVAILABLE:
17833                 case Intent.ACTION_EXTERNAL_APPLICATIONS_AVAILABLE:
17834                 case Intent.ACTION_PACKAGES_SUSPENDED:
17835                 case Intent.ACTION_PACKAGES_UNSUSPENDED:
17836                     // Handle special intents: if this broadcast is from the package
17837                     // manager about a package being removed, we need to remove all of
17838                     // its activities from the history stack.
17839                     if (checkComponentPermission(
17840                             android.Manifest.permission.BROADCAST_PACKAGE_REMOVED,
17841                             callingPid, callingUid, -1, true)
17842                             != PackageManager.PERMISSION_GRANTED) {
17843                         String msg = "Permission Denial: " + intent.getAction()
17844                                 + " broadcast from " + callerPackage + " (pid=" + callingPid
17845                                 + ", uid=" + callingUid + ")"
17846                                 + " requires "
17847                                 + android.Manifest.permission.BROADCAST_PACKAGE_REMOVED;
17848                         Slog.w(TAG, msg);
17849                         throw new SecurityException(msg);
17850                     }
17851                     switch (action) {
17852                         case Intent.ACTION_UID_REMOVED:
17853                             final Bundle intentExtras = intent.getExtras();
17854                             final int uid = intentExtras != null
17855                                     ? intentExtras.getInt(Intent.EXTRA_UID) : -1;
17856                             if (uid >= 0) {
17857                                 mBatteryStatsService.removeUid(uid);
17858                                 mAppOpsService.uidRemoved(uid);
17859                             }
17860                             break;
17861                         case Intent.ACTION_EXTERNAL_APPLICATIONS_UNAVAILABLE:
17862                             // If resources are unavailable just force stop all those packages
17863                             // and flush the attribute cache as well.
17864                             String list[] =
17865                                     intent.getStringArrayExtra(Intent.EXTRA_CHANGED_PACKAGE_LIST);
17866                             if (list != null && list.length > 0) {
17867                                 for (int i = 0; i < list.length; i++) {
17868                                     forceStopPackageLocked(list[i], -1, false, true, true,
17869                                             false, false, userId, "storage unmount");
17870                                 }
17871                                 mRecentTasks.cleanupLocked(UserHandle.USER_ALL);
17872                                 sendPackageBroadcastLocked(
17873                                         IApplicationThread.EXTERNAL_STORAGE_UNAVAILABLE, list,
17874                                         userId);
17875                             }
17876                             break;
17877                         case Intent.ACTION_EXTERNAL_APPLICATIONS_AVAILABLE:
17878                             mRecentTasks.cleanupLocked(UserHandle.USER_ALL);
17879                             break;
17880                         case Intent.ACTION_PACKAGE_REMOVED:
17881                         case Intent.ACTION_PACKAGE_CHANGED:
17882                             Uri data = intent.getData();
17883                             String ssp;
17884                             if (data != null && (ssp=data.getSchemeSpecificPart()) != null) {
17885                                 boolean removed = Intent.ACTION_PACKAGE_REMOVED.equals(action);
17886                                 final boolean replacing =
17887                                         intent.getBooleanExtra(Intent.EXTRA_REPLACING, false);
17888                                 final boolean killProcess =
17889                                         !intent.getBooleanExtra(Intent.EXTRA_DONT_KILL_APP, false);
17890                                 final boolean fullUninstall = removed && !replacing;
17891                                 if (removed) {
17892                                     if (killProcess) {
17893                                         forceStopPackageLocked(ssp, UserHandle.getAppId(
17894                                                 intent.getIntExtra(Intent.EXTRA_UID, -1)),
17895                                                 false, true, true, false, fullUninstall, userId,
17896                                                 removed ? "pkg removed" : "pkg changed");
17897                                     }
17898                                     final int cmd = killProcess
17899                                             ? IApplicationThread.PACKAGE_REMOVED
17900                                             : IApplicationThread.PACKAGE_REMOVED_DONT_KILL;
17901                                     sendPackageBroadcastLocked(cmd,
17902                                             new String[] {ssp}, userId);
17903                                     if (fullUninstall) {
17904                                         mAppOpsService.packageRemoved(
17905                                                 intent.getIntExtra(Intent.EXTRA_UID, -1), ssp);
17906
17907                                         // Remove all permissions granted from/to this package
17908                                         removeUriPermissionsForPackageLocked(ssp, userId, true);
17909
17910                                         removeTasksByPackageNameLocked(ssp, userId);
17911
17912                                         // Hide the "unsupported display" dialog if necessary.
17913                                         if (mUnsupportedDisplaySizeDialog != null && ssp.equals(
17914                                                 mUnsupportedDisplaySizeDialog.getPackageName())) {
17915                                             mUnsupportedDisplaySizeDialog.dismiss();
17916                                             mUnsupportedDisplaySizeDialog = null;
17917                                         }
17918                                         mCompatModePackages.handlePackageUninstalledLocked(ssp);
17919                                         mBatteryStatsService.notePackageUninstalled(ssp);
17920                                     }
17921                                 } else {
17922                                     if (killProcess) {
17923                                         killPackageProcessesLocked(ssp, UserHandle.getAppId(
17924                                                 intent.getIntExtra(Intent.EXTRA_UID, -1)),
17925                                                 userId, ProcessList.INVALID_ADJ,
17926                                                 false, true, true, false, "change " + ssp);
17927                                     }
17928                                     cleanupDisabledPackageComponentsLocked(ssp, userId, killProcess,
17929                                             intent.getStringArrayExtra(
17930                                                     Intent.EXTRA_CHANGED_COMPONENT_NAME_LIST));
17931                                 }
17932                             }
17933                             break;
17934                         case Intent.ACTION_PACKAGES_SUSPENDED:
17935                         case Intent.ACTION_PACKAGES_UNSUSPENDED:
17936                             final boolean suspended = Intent.ACTION_PACKAGES_SUSPENDED.equals(
17937                                     intent.getAction());
17938                             final String[] packageNames = intent.getStringArrayExtra(
17939                                     Intent.EXTRA_CHANGED_PACKAGE_LIST);
17940                             final int userHandle = intent.getIntExtra(
17941                                     Intent.EXTRA_USER_HANDLE, UserHandle.USER_NULL);
17942
17943                             synchronized(ActivityManagerService.this) {
17944                                 mRecentTasks.onPackagesSuspendedChanged(
17945                                         packageNames, suspended, userHandle);
17946                             }
17947                             break;
17948                     }
17949                     break;
17950                 case Intent.ACTION_PACKAGE_REPLACED:
17951                 {
17952                     final Uri data = intent.getData();
17953                     final String ssp;
17954                     if (data != null && (ssp = data.getSchemeSpecificPart()) != null) {
17955                         final ApplicationInfo aInfo =
17956                                 getPackageManagerInternalLocked().getApplicationInfo(
17957                                         ssp,
17958                                         userId);
17959                         if (aInfo == null) {
17960                             Slog.w(TAG, "Dropping ACTION_PACKAGE_REPLACED for non-existent pkg:"
17961                                     + " ssp=" + ssp + " data=" + data);
17962                             return ActivityManager.BROADCAST_SUCCESS;
17963                         }
17964                         mStackSupervisor.updateActivityApplicationInfoLocked(aInfo);
17965                         sendPackageBroadcastLocked(IApplicationThread.PACKAGE_REPLACED,
17966                                 new String[] {ssp}, userId);
17967                     }
17968                     break;
17969                 }
17970                 case Intent.ACTION_PACKAGE_ADDED:
17971                 {
17972                     // Special case for adding a package: by default turn on compatibility mode.
17973                     Uri data = intent.getData();
17974                     String ssp;
17975                     if (data != null && (ssp = data.getSchemeSpecificPart()) != null) {
17976                         final boolean replacing =
17977                                 intent.getBooleanExtra(Intent.EXTRA_REPLACING, false);
17978                         mCompatModePackages.handlePackageAddedLocked(ssp, replacing);
17979
17980                         try {
17981                             ApplicationInfo ai = AppGlobals.getPackageManager().
17982                                     getApplicationInfo(ssp, 0, 0);
17983                             mBatteryStatsService.notePackageInstalled(ssp,
17984                                     ai != null ? ai.versionCode : 0);
17985                         } catch (RemoteException e) {
17986                         }
17987                     }
17988                     break;
17989                 }
17990                 case Intent.ACTION_PACKAGE_DATA_CLEARED:
17991                 {
17992                     Uri data = intent.getData();
17993                     String ssp;
17994                     if (data != null && (ssp = data.getSchemeSpecificPart()) != null) {
17995                         // Hide the "unsupported display" dialog if necessary.
17996                         if (mUnsupportedDisplaySizeDialog != null && ssp.equals(
17997                                 mUnsupportedDisplaySizeDialog.getPackageName())) {
17998                             mUnsupportedDisplaySizeDialog.dismiss();
17999                             mUnsupportedDisplaySizeDialog = null;
18000                         }
18001                         mCompatModePackages.handlePackageDataClearedLocked(ssp);
18002                     }
18003                     break;
18004                 }
18005                 case Intent.ACTION_TIMEZONE_CHANGED:
18006                     // If this is the time zone changed action, queue up a message that will reset
18007                     // the timezone of all currently running processes. This message will get
18008                     // queued up before the broadcast happens.
18009                     mHandler.sendEmptyMessage(UPDATE_TIME_ZONE);
18010                     break;
18011                 case Intent.ACTION_TIME_CHANGED:
18012                     // If the user set the time, let all running processes know.
18013                     final int is24Hour =
18014                             intent.getBooleanExtra(Intent.EXTRA_TIME_PREF_24_HOUR_FORMAT, false) ? 1
18015                                     : 0;
18016                     mHandler.sendMessage(mHandler.obtainMessage(UPDATE_TIME, is24Hour, 0));
18017                     BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
18018                     synchronized (stats) {
18019                         stats.noteCurrentTimeChangedLocked();
18020                     }
18021                     break;
18022                 case Intent.ACTION_CLEAR_DNS_CACHE:
18023                     mHandler.sendEmptyMessage(CLEAR_DNS_CACHE_MSG);
18024                     break;
18025                 case Proxy.PROXY_CHANGE_ACTION:
18026                     ProxyInfo proxy = intent.getParcelableExtra(Proxy.EXTRA_PROXY_INFO);
18027                     mHandler.sendMessage(mHandler.obtainMessage(UPDATE_HTTP_PROXY_MSG, proxy));
18028                     break;
18029                 case android.hardware.Camera.ACTION_NEW_PICTURE:
18030                 case android.hardware.Camera.ACTION_NEW_VIDEO:
18031                     // These broadcasts are no longer allowed by the system, since they can
18032                     // cause significant thrashing at a crictical point (using the camera).
18033                     // Apps should use JobScehduler to monitor for media provider changes.
18034                     Slog.w(TAG, action + " no longer allowed; dropping from "
18035                             + UserHandle.formatUid(callingUid));
18036                     if (resultTo != null) {
18037                         final BroadcastQueue queue = broadcastQueueForIntent(intent);
18038                         try {
18039                             queue.performReceiveLocked(callerApp, resultTo, intent,
18040                                     Activity.RESULT_CANCELED, null, null,
18041                                     false, false, userId);
18042                         } catch (RemoteException e) {
18043                             Slog.w(TAG, "Failure ["
18044                                     + queue.mQueueName + "] sending broadcast result of "
18045                                     + intent, e);
18046
18047                         }
18048                     }
18049                     // Lie; we don't want to crash the app.
18050                     return ActivityManager.BROADCAST_SUCCESS;
18051             }
18052         }
18053
18054         // Add to the sticky list if requested.
18055         if (sticky) {
18056             if (checkPermission(android.Manifest.permission.BROADCAST_STICKY,
18057                     callingPid, callingUid)
18058                     != PackageManager.PERMISSION_GRANTED) {
18059                 String msg = "Permission Denial: broadcastIntent() requesting a sticky broadcast from pid="
18060                         + callingPid + ", uid=" + callingUid
18061                         + " requires " + android.Manifest.permission.BROADCAST_STICKY;
18062                 Slog.w(TAG, msg);
18063                 throw new SecurityException(msg);
18064             }
18065             if (requiredPermissions != null && requiredPermissions.length > 0) {
18066                 Slog.w(TAG, "Can't broadcast sticky intent " + intent
18067                         + " and enforce permissions " + Arrays.toString(requiredPermissions));
18068                 return ActivityManager.BROADCAST_STICKY_CANT_HAVE_PERMISSION;
18069             }
18070             if (intent.getComponent() != null) {
18071                 throw new SecurityException(
18072                         "Sticky broadcasts can't target a specific component");
18073             }
18074             // We use userId directly here, since the "all" target is maintained
18075             // as a separate set of sticky broadcasts.
18076             if (userId != UserHandle.USER_ALL) {
18077                 // But first, if this is not a broadcast to all users, then
18078                 // make sure it doesn't conflict with an existing broadcast to
18079                 // all users.
18080                 ArrayMap<String, ArrayList<Intent>> stickies = mStickyBroadcasts.get(
18081                         UserHandle.USER_ALL);
18082                 if (stickies != null) {
18083                     ArrayList<Intent> list = stickies.get(intent.getAction());
18084                     if (list != null) {
18085                         int N = list.size();
18086                         int i;
18087                         for (i=0; i<N; i++) {
18088                             if (intent.filterEquals(list.get(i))) {
18089                                 throw new IllegalArgumentException(
18090                                         "Sticky broadcast " + intent + " for user "
18091                                         + userId + " conflicts with existing global broadcast");
18092                             }
18093                         }
18094                     }
18095                 }
18096             }
18097             ArrayMap<String, ArrayList<Intent>> stickies = mStickyBroadcasts.get(userId);
18098             if (stickies == null) {
18099                 stickies = new ArrayMap<>();
18100                 mStickyBroadcasts.put(userId, stickies);
18101             }
18102             ArrayList<Intent> list = stickies.get(intent.getAction());
18103             if (list == null) {
18104                 list = new ArrayList<>();
18105                 stickies.put(intent.getAction(), list);
18106             }
18107             final int stickiesCount = list.size();
18108             int i;
18109             for (i = 0; i < stickiesCount; i++) {
18110                 if (intent.filterEquals(list.get(i))) {
18111                     // This sticky already exists, replace it.
18112                     list.set(i, new Intent(intent));
18113                     break;
18114                 }
18115             }
18116             if (i >= stickiesCount) {
18117                 list.add(new Intent(intent));
18118             }
18119         }
18120
18121         int[] users;
18122         if (userId == UserHandle.USER_ALL) {
18123             // Caller wants broadcast to go to all started users.
18124             users = mUserController.getStartedUserArrayLocked();
18125         } else {
18126             // Caller wants broadcast to go to one specific user.
18127             users = new int[] {userId};
18128         }
18129
18130         // Figure out who all will receive this broadcast.
18131         List receivers = null;
18132         List<BroadcastFilter> registeredReceivers = null;
18133         // Need to resolve the intent to interested receivers...
18134         if ((intent.getFlags()&Intent.FLAG_RECEIVER_REGISTERED_ONLY)
18135                  == 0) {
18136             receivers = collectReceiverComponents(intent, resolvedType, callingUid, users);
18137         }
18138         if (intent.getComponent() == null) {
18139             if (userId == UserHandle.USER_ALL && callingUid == Process.SHELL_UID) {
18140                 // Query one target user at a time, excluding shell-restricted users
18141                 for (int i = 0; i < users.length; i++) {
18142                     if (mUserController.hasUserRestriction(
18143                             UserManager.DISALLOW_DEBUGGING_FEATURES, users[i])) {
18144                         continue;
18145                     }
18146                     List<BroadcastFilter> registeredReceiversForUser =
18147                             mReceiverResolver.queryIntent(intent,
18148                                     resolvedType, false, users[i]);
18149                     if (registeredReceivers == null) {
18150                         registeredReceivers = registeredReceiversForUser;
18151                     } else if (registeredReceiversForUser != null) {
18152                         registeredReceivers.addAll(registeredReceiversForUser);
18153                     }
18154                 }
18155             } else {
18156                 registeredReceivers = mReceiverResolver.queryIntent(intent,
18157                         resolvedType, false, userId);
18158             }
18159         }
18160
18161         final boolean replacePending =
18162                 (intent.getFlags()&Intent.FLAG_RECEIVER_REPLACE_PENDING) != 0;
18163
18164         if (DEBUG_BROADCAST) Slog.v(TAG_BROADCAST, "Enqueing broadcast: " + intent.getAction()
18165                 + " replacePending=" + replacePending);
18166
18167         int NR = registeredReceivers != null ? registeredReceivers.size() : 0;
18168         if (!ordered && NR > 0) {
18169             // If we are not serializing this broadcast, then send the
18170             // registered receivers separately so they don't wait for the
18171             // components to be launched.
18172             final BroadcastQueue queue = broadcastQueueForIntent(intent);
18173             BroadcastRecord r = new BroadcastRecord(queue, intent, callerApp,
18174                     callerPackage, callingPid, callingUid, resolvedType, requiredPermissions,
18175                     appOp, brOptions, registeredReceivers, resultTo, resultCode, resultData,
18176                     resultExtras, ordered, sticky, false, userId);
18177             if (DEBUG_BROADCAST) Slog.v(TAG_BROADCAST, "Enqueueing parallel broadcast " + r);
18178             final boolean replaced = replacePending && queue.replaceParallelBroadcastLocked(r);
18179             if (!replaced) {
18180                 queue.enqueueParallelBroadcastLocked(r);
18181                 queue.scheduleBroadcastsLocked();
18182             }
18183             registeredReceivers = null;
18184             NR = 0;
18185         }
18186
18187         // Merge into one list.
18188         int ir = 0;
18189         if (receivers != null) {
18190             // A special case for PACKAGE_ADDED: do not allow the package
18191             // being added to see this broadcast.  This prevents them from
18192             // using this as a back door to get run as soon as they are
18193             // installed.  Maybe in the future we want to have a special install
18194             // broadcast or such for apps, but we'd like to deliberately make
18195             // this decision.
18196             String skipPackages[] = null;
18197             if (Intent.ACTION_PACKAGE_ADDED.equals(intent.getAction())
18198                     || Intent.ACTION_PACKAGE_RESTARTED.equals(intent.getAction())
18199                     || Intent.ACTION_PACKAGE_DATA_CLEARED.equals(intent.getAction())) {
18200                 Uri data = intent.getData();
18201                 if (data != null) {
18202                     String pkgName = data.getSchemeSpecificPart();
18203                     if (pkgName != null) {
18204                         skipPackages = new String[] { pkgName };
18205                     }
18206                 }
18207             } else if (Intent.ACTION_EXTERNAL_APPLICATIONS_AVAILABLE.equals(intent.getAction())) {
18208                 skipPackages = intent.getStringArrayExtra(Intent.EXTRA_CHANGED_PACKAGE_LIST);
18209             }
18210             if (skipPackages != null && (skipPackages.length > 0)) {
18211                 for (String skipPackage : skipPackages) {
18212                     if (skipPackage != null) {
18213                         int NT = receivers.size();
18214                         for (int it=0; it<NT; it++) {
18215                             ResolveInfo curt = (ResolveInfo)receivers.get(it);
18216                             if (curt.activityInfo.packageName.equals(skipPackage)) {
18217                                 receivers.remove(it);
18218                                 it--;
18219                                 NT--;
18220                             }
18221                         }
18222                     }
18223                 }
18224             }
18225
18226             int NT = receivers != null ? receivers.size() : 0;
18227             int it = 0;
18228             ResolveInfo curt = null;
18229             BroadcastFilter curr = null;
18230             while (it < NT && ir < NR) {
18231                 if (curt == null) {
18232                     curt = (ResolveInfo)receivers.get(it);
18233                 }
18234                 if (curr == null) {
18235                     curr = registeredReceivers.get(ir);
18236                 }
18237                 if (curr.getPriority() >= curt.priority) {
18238                     // Insert this broadcast record into the final list.
18239                     receivers.add(it, curr);
18240                     ir++;
18241                     curr = null;
18242                     it++;
18243                     NT++;
18244                 } else {
18245                     // Skip to the next ResolveInfo in the final list.
18246                     it++;
18247                     curt = null;
18248                 }
18249             }
18250         }
18251         while (ir < NR) {
18252             if (receivers == null) {
18253                 receivers = new ArrayList();
18254             }
18255             receivers.add(registeredReceivers.get(ir));
18256             ir++;
18257         }
18258
18259         if ((receivers != null && receivers.size() > 0)
18260                 || resultTo != null) {
18261             BroadcastQueue queue = broadcastQueueForIntent(intent);
18262             BroadcastRecord r = new BroadcastRecord(queue, intent, callerApp,
18263                     callerPackage, callingPid, callingUid, resolvedType,
18264                     requiredPermissions, appOp, brOptions, receivers, resultTo, resultCode,
18265                     resultData, resultExtras, ordered, sticky, false, userId);
18266
18267             if (DEBUG_BROADCAST) Slog.v(TAG_BROADCAST, "Enqueueing ordered broadcast " + r
18268                     + ": prev had " + queue.mOrderedBroadcasts.size());
18269             if (DEBUG_BROADCAST) Slog.i(TAG_BROADCAST,
18270                     "Enqueueing broadcast " + r.intent.getAction());
18271
18272             boolean replaced = replacePending && queue.replaceOrderedBroadcastLocked(r);
18273             if (!replaced) {
18274                 queue.enqueueOrderedBroadcastLocked(r);
18275                 queue.scheduleBroadcastsLocked();
18276             }
18277         } else {
18278             // There was nobody interested in the broadcast, but we still want to record
18279             // that it happened.
18280             if (intent.getComponent() == null && intent.getPackage() == null
18281                     && (intent.getFlags()&Intent.FLAG_RECEIVER_REGISTERED_ONLY) == 0) {
18282                 // This was an implicit broadcast... let's record it for posterity.
18283                 addBroadcastStatLocked(intent.getAction(), callerPackage, 0, 0, 0);
18284             }
18285         }
18286
18287         return ActivityManager.BROADCAST_SUCCESS;
18288     }
18289
18290     final void addBroadcastStatLocked(String action, String srcPackage, int receiveCount,
18291             int skipCount, long dispatchTime) {
18292         final long now = SystemClock.elapsedRealtime();
18293         if (mCurBroadcastStats == null ||
18294                 (mCurBroadcastStats.mStartRealtime +(24*60*60*1000) < now)) {
18295             mLastBroadcastStats = mCurBroadcastStats;
18296             if (mLastBroadcastStats != null) {
18297                 mLastBroadcastStats.mEndRealtime = SystemClock.elapsedRealtime();
18298                 mLastBroadcastStats.mEndUptime = SystemClock.uptimeMillis();
18299             }
18300             mCurBroadcastStats = new BroadcastStats();
18301         }
18302         mCurBroadcastStats.addBroadcast(action, srcPackage, receiveCount, skipCount, dispatchTime);
18303     }
18304
18305     final Intent verifyBroadcastLocked(Intent intent) {
18306         // Refuse possible leaked file descriptors
18307         if (intent != null && intent.hasFileDescriptors() == true) {
18308             throw new IllegalArgumentException("File descriptors passed in Intent");
18309         }
18310
18311         int flags = intent.getFlags();
18312
18313         if (!mProcessesReady) {
18314             // if the caller really truly claims to know what they're doing, go
18315             // ahead and allow the broadcast without launching any receivers
18316             if ((flags&Intent.FLAG_RECEIVER_REGISTERED_ONLY_BEFORE_BOOT) != 0) {
18317                 // This will be turned into a FLAG_RECEIVER_REGISTERED_ONLY later on if needed.
18318             } else if ((flags&Intent.FLAG_RECEIVER_REGISTERED_ONLY) == 0) {
18319                 Slog.e(TAG, "Attempt to launch receivers of broadcast intent " + intent
18320                         + " before boot completion");
18321                 throw new IllegalStateException("Cannot broadcast before boot completed");
18322             }
18323         }
18324
18325         if ((flags&Intent.FLAG_RECEIVER_BOOT_UPGRADE) != 0) {
18326             throw new IllegalArgumentException(
18327                     "Can't use FLAG_RECEIVER_BOOT_UPGRADE here");
18328         }
18329
18330         return intent;
18331     }
18332
18333     public final int broadcastIntent(IApplicationThread caller,
18334             Intent intent, String resolvedType, IIntentReceiver resultTo,
18335             int resultCode, String resultData, Bundle resultExtras,
18336             String[] requiredPermissions, int appOp, Bundle bOptions,
18337             boolean serialized, boolean sticky, int userId) {
18338         enforceNotIsolatedCaller("broadcastIntent");
18339         synchronized(this) {
18340             intent = verifyBroadcastLocked(intent);
18341
18342             final ProcessRecord callerApp = getRecordForAppLocked(caller);
18343             final int callingPid = Binder.getCallingPid();
18344             final int callingUid = Binder.getCallingUid();
18345             final long origId = Binder.clearCallingIdentity();
18346             int res = broadcastIntentLocked(callerApp,
18347                     callerApp != null ? callerApp.info.packageName : null,
18348                     intent, resolvedType, resultTo, resultCode, resultData, resultExtras,
18349                     requiredPermissions, appOp, bOptions, serialized, sticky,
18350                     callingPid, callingUid, userId);
18351             Binder.restoreCallingIdentity(origId);
18352             return res;
18353         }
18354     }
18355
18356
18357     int broadcastIntentInPackage(String packageName, int uid,
18358             Intent intent, String resolvedType, IIntentReceiver resultTo,
18359             int resultCode, String resultData, Bundle resultExtras,
18360             String requiredPermission, Bundle bOptions, boolean serialized, boolean sticky,
18361             int userId) {
18362         synchronized(this) {
18363             intent = verifyBroadcastLocked(intent);
18364
18365             final long origId = Binder.clearCallingIdentity();
18366             String[] requiredPermissions = requiredPermission == null ? null
18367                     : new String[] {requiredPermission};
18368             int res = broadcastIntentLocked(null, packageName, intent, resolvedType,
18369                     resultTo, resultCode, resultData, resultExtras,
18370                     requiredPermissions, AppOpsManager.OP_NONE, bOptions, serialized,
18371                     sticky, -1, uid, userId);
18372             Binder.restoreCallingIdentity(origId);
18373             return res;
18374         }
18375     }
18376
18377     public final void unbroadcastIntent(IApplicationThread caller, Intent intent, int userId) {
18378         // Refuse possible leaked file descriptors
18379         if (intent != null && intent.hasFileDescriptors() == true) {
18380             throw new IllegalArgumentException("File descriptors passed in Intent");
18381         }
18382
18383         userId = mUserController.handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(),
18384                 userId, true, ALLOW_NON_FULL, "removeStickyBroadcast", null);
18385
18386         synchronized(this) {
18387             if (checkCallingPermission(android.Manifest.permission.BROADCAST_STICKY)
18388                     != PackageManager.PERMISSION_GRANTED) {
18389                 String msg = "Permission Denial: unbroadcastIntent() from pid="
18390                         + Binder.getCallingPid()
18391                         + ", uid=" + Binder.getCallingUid()
18392                         + " requires " + android.Manifest.permission.BROADCAST_STICKY;
18393                 Slog.w(TAG, msg);
18394                 throw new SecurityException(msg);
18395             }
18396             ArrayMap<String, ArrayList<Intent>> stickies = mStickyBroadcasts.get(userId);
18397             if (stickies != null) {
18398                 ArrayList<Intent> list = stickies.get(intent.getAction());
18399                 if (list != null) {
18400                     int N = list.size();
18401                     int i;
18402                     for (i=0; i<N; i++) {
18403                         if (intent.filterEquals(list.get(i))) {
18404                             list.remove(i);
18405                             break;
18406                         }
18407                     }
18408                     if (list.size() <= 0) {
18409                         stickies.remove(intent.getAction());
18410                     }
18411                 }
18412                 if (stickies.size() <= 0) {
18413                     mStickyBroadcasts.remove(userId);
18414                 }
18415             }
18416         }
18417     }
18418
18419     void backgroundServicesFinishedLocked(int userId) {
18420         for (BroadcastQueue queue : mBroadcastQueues) {
18421             queue.backgroundServicesFinishedLocked(userId);
18422         }
18423     }
18424
18425     public void finishReceiver(IBinder who, int resultCode, String resultData,
18426             Bundle resultExtras, boolean resultAbort, int flags) {
18427         if (DEBUG_BROADCAST) Slog.v(TAG_BROADCAST, "Finish receiver: " + who);
18428
18429         // Refuse possible leaked file descriptors
18430         if (resultExtras != null && resultExtras.hasFileDescriptors()) {
18431             throw new IllegalArgumentException("File descriptors passed in Bundle");
18432         }
18433
18434         final long origId = Binder.clearCallingIdentity();
18435         try {
18436             boolean doNext = false;
18437             BroadcastRecord r;
18438
18439             synchronized(this) {
18440                 BroadcastQueue queue = (flags & Intent.FLAG_RECEIVER_FOREGROUND) != 0
18441                         ? mFgBroadcastQueue : mBgBroadcastQueue;
18442                 r = queue.getMatchingOrderedReceiver(who);
18443                 if (r != null) {
18444                     doNext = r.queue.finishReceiverLocked(r, resultCode,
18445                         resultData, resultExtras, resultAbort, true);
18446                 }
18447             }
18448
18449             if (doNext) {
18450                 r.queue.processNextBroadcast(false);
18451             }
18452             trimApplications();
18453         } finally {
18454             Binder.restoreCallingIdentity(origId);
18455         }
18456     }
18457
18458     // =========================================================
18459     // INSTRUMENTATION
18460     // =========================================================
18461
18462     public boolean startInstrumentation(ComponentName className,
18463             String profileFile, int flags, Bundle arguments,
18464             IInstrumentationWatcher watcher, IUiAutomationConnection uiAutomationConnection,
18465             int userId, String abiOverride) {
18466         enforceNotIsolatedCaller("startInstrumentation");
18467         userId = mUserController.handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(),
18468                 userId, false, ALLOW_FULL_ONLY, "startInstrumentation", null);
18469         // Refuse possible leaked file descriptors
18470         if (arguments != null && arguments.hasFileDescriptors()) {
18471             throw new IllegalArgumentException("File descriptors passed in Bundle");
18472         }
18473
18474         synchronized(this) {
18475             InstrumentationInfo ii = null;
18476             ApplicationInfo ai = null;
18477             try {
18478                 ii = mContext.getPackageManager().getInstrumentationInfo(
18479                     className, STOCK_PM_FLAGS);
18480                 ai = AppGlobals.getPackageManager().getApplicationInfo(
18481                         ii.targetPackage, STOCK_PM_FLAGS, userId);
18482             } catch (PackageManager.NameNotFoundException e) {
18483             } catch (RemoteException e) {
18484             }
18485             if (ii == null) {
18486                 reportStartInstrumentationFailureLocked(watcher, className,
18487                         "Unable to find instrumentation info for: " + className);
18488                 return false;
18489             }
18490             if (ai == null) {
18491                 reportStartInstrumentationFailureLocked(watcher, className,
18492                         "Unable to find instrumentation target package: " + ii.targetPackage);
18493                 return false;
18494             }
18495             if (!ai.hasCode()) {
18496                 reportStartInstrumentationFailureLocked(watcher, className,
18497                         "Instrumentation target has no code: " + ii.targetPackage);
18498                 return false;
18499             }
18500
18501             int match = mContext.getPackageManager().checkSignatures(
18502                     ii.targetPackage, ii.packageName);
18503             if (match < 0 && match != PackageManager.SIGNATURE_FIRST_NOT_SIGNED) {
18504                 String msg = "Permission Denial: starting instrumentation "
18505                         + className + " from pid="
18506                         + Binder.getCallingPid()
18507                         + ", uid=" + Binder.getCallingPid()
18508                         + " not allowed because package " + ii.packageName
18509                         + " does not have a signature matching the target "
18510                         + ii.targetPackage;
18511                 reportStartInstrumentationFailureLocked(watcher, className, msg);
18512                 throw new SecurityException(msg);
18513             }
18514
18515             final long origId = Binder.clearCallingIdentity();
18516             // Instrumentation can kill and relaunch even persistent processes
18517             forceStopPackageLocked(ii.targetPackage, -1, true, false, true, true, false, userId,
18518                     "start instr");
18519             ProcessRecord app = addAppLocked(ai, false, abiOverride);
18520             app.instrumentationClass = className;
18521             app.instrumentationInfo = ai;
18522             app.instrumentationProfileFile = profileFile;
18523             app.instrumentationArguments = arguments;
18524             app.instrumentationWatcher = watcher;
18525             app.instrumentationUiAutomationConnection = uiAutomationConnection;
18526             app.instrumentationResultClass = className;
18527             Binder.restoreCallingIdentity(origId);
18528         }
18529
18530         return true;
18531     }
18532
18533     /**
18534      * Report errors that occur while attempting to start Instrumentation.  Always writes the
18535      * error to the logs, but if somebody is watching, send the report there too.  This enables
18536      * the "am" command to report errors with more information.
18537      *
18538      * @param watcher The IInstrumentationWatcher.  Null if there isn't one.
18539      * @param cn The component name of the instrumentation.
18540      * @param report The error report.
18541      */
18542     private void reportStartInstrumentationFailureLocked(IInstrumentationWatcher watcher,
18543             ComponentName cn, String report) {
18544         Slog.w(TAG, report);
18545         if (watcher != null) {
18546             Bundle results = new Bundle();
18547             results.putString(Instrumentation.REPORT_KEY_IDENTIFIER, "ActivityManagerService");
18548             results.putString("Error", report);
18549             mInstrumentationReporter.reportStatus(watcher, cn, -1, results);
18550         }
18551     }
18552
18553     void finishInstrumentationLocked(ProcessRecord app, int resultCode, Bundle results) {
18554         if (app.instrumentationWatcher != null) {
18555             mInstrumentationReporter.reportFinished(app.instrumentationWatcher,
18556                     app.instrumentationClass, resultCode, results);
18557         }
18558
18559         // Can't call out of the system process with a lock held, so post a message.
18560         if (app.instrumentationUiAutomationConnection != null) {
18561             mHandler.obtainMessage(SHUTDOWN_UI_AUTOMATION_CONNECTION_MSG,
18562                     app.instrumentationUiAutomationConnection).sendToTarget();
18563         }
18564
18565         app.instrumentationWatcher = null;
18566         app.instrumentationUiAutomationConnection = null;
18567         app.instrumentationClass = null;
18568         app.instrumentationInfo = null;
18569         app.instrumentationProfileFile = null;
18570         app.instrumentationArguments = null;
18571
18572         forceStopPackageLocked(app.info.packageName, -1, false, false, true, true, false, app.userId,
18573                 "finished inst");
18574     }
18575
18576     public void finishInstrumentation(IApplicationThread target,
18577             int resultCode, Bundle results) {
18578         int userId = UserHandle.getCallingUserId();
18579         // Refuse possible leaked file descriptors
18580         if (results != null && results.hasFileDescriptors()) {
18581             throw new IllegalArgumentException("File descriptors passed in Intent");
18582         }
18583
18584         synchronized(this) {
18585             ProcessRecord app = getRecordForAppLocked(target);
18586             if (app == null) {
18587                 Slog.w(TAG, "finishInstrumentation: no app for " + target);
18588                 return;
18589             }
18590             final long origId = Binder.clearCallingIdentity();
18591             finishInstrumentationLocked(app, resultCode, results);
18592             Binder.restoreCallingIdentity(origId);
18593         }
18594     }
18595
18596     // =========================================================
18597     // CONFIGURATION
18598     // =========================================================
18599
18600     public ConfigurationInfo getDeviceConfigurationInfo() {
18601         ConfigurationInfo config = new ConfigurationInfo();
18602         synchronized (this) {
18603             config.reqTouchScreen = mConfiguration.touchscreen;
18604             config.reqKeyboardType = mConfiguration.keyboard;
18605             config.reqNavigation = mConfiguration.navigation;
18606             if (mConfiguration.navigation == Configuration.NAVIGATION_DPAD
18607                     || mConfiguration.navigation == Configuration.NAVIGATION_TRACKBALL) {
18608                 config.reqInputFeatures |= ConfigurationInfo.INPUT_FEATURE_FIVE_WAY_NAV;
18609             }
18610             if (mConfiguration.keyboard != Configuration.KEYBOARD_UNDEFINED
18611                     && mConfiguration.keyboard != Configuration.KEYBOARD_NOKEYS) {
18612                 config.reqInputFeatures |= ConfigurationInfo.INPUT_FEATURE_HARD_KEYBOARD;
18613             }
18614             config.reqGlEsVersion = GL_ES_VERSION;
18615         }
18616         return config;
18617     }
18618
18619     ActivityStack getFocusedStack() {
18620         return mStackSupervisor.getFocusedStack();
18621     }
18622
18623     @Override
18624     public int getFocusedStackId() throws RemoteException {
18625         ActivityStack focusedStack = getFocusedStack();
18626         if (focusedStack != null) {
18627             return focusedStack.getStackId();
18628         }
18629         return -1;
18630     }
18631
18632     public Configuration getConfiguration() {
18633         Configuration ci;
18634         synchronized(this) {
18635             ci = new Configuration(mConfiguration);
18636             ci.userSetLocale = false;
18637         }
18638         return ci;
18639     }
18640
18641     @Override
18642     public void suppressResizeConfigChanges(boolean suppress) throws RemoteException {
18643         enforceCallingPermission(MANAGE_ACTIVITY_STACKS, "suppressResizeConfigChanges()");
18644         synchronized (this) {
18645             mSuppressResizeConfigChanges = suppress;
18646         }
18647     }
18648
18649     @Override
18650     public void moveTasksToFullscreenStack(int fromStackId, boolean onTop) {
18651         enforceCallingPermission(MANAGE_ACTIVITY_STACKS, "moveTasksToFullscreenStack()");
18652         if (fromStackId == HOME_STACK_ID) {
18653             throw new IllegalArgumentException("You can't move tasks from the home stack.");
18654         }
18655         synchronized (this) {
18656             final long origId = Binder.clearCallingIdentity();
18657             try {
18658                 mStackSupervisor.moveTasksToFullscreenStackLocked(fromStackId, onTop);
18659             } finally {
18660                 Binder.restoreCallingIdentity(origId);
18661             }
18662         }
18663     }
18664
18665     @Override
18666     public void updatePersistentConfiguration(Configuration values) {
18667         enforceCallingPermission(android.Manifest.permission.CHANGE_CONFIGURATION,
18668                 "updateConfiguration()");
18669         enforceWriteSettingsPermission("updateConfiguration()");
18670         if (values == null) {
18671             throw new NullPointerException("Configuration must not be null");
18672         }
18673
18674         int userId = UserHandle.getCallingUserId();
18675
18676         synchronized(this) {
18677             final long origId = Binder.clearCallingIdentity();
18678             updateConfigurationLocked(values, null, false, true, userId);
18679             Binder.restoreCallingIdentity(origId);
18680         }
18681     }
18682
18683     private void updateFontScaleIfNeeded() {
18684         final int currentUserId;
18685         synchronized(this) {
18686             currentUserId = mUserController.getCurrentUserIdLocked();
18687         }
18688         final float scaleFactor = Settings.System.getFloatForUser(mContext.getContentResolver(),
18689                 FONT_SCALE, 1.0f, currentUserId);
18690         if (mConfiguration.fontScale != scaleFactor) {
18691             final Configuration configuration = mWindowManager.computeNewConfiguration();
18692             configuration.fontScale = scaleFactor;
18693             updatePersistentConfiguration(configuration);
18694         }
18695     }
18696
18697     private void enforceWriteSettingsPermission(String func) {
18698         int uid = Binder.getCallingUid();
18699         if (uid == Process.ROOT_UID) {
18700             return;
18701         }
18702
18703         if (Settings.checkAndNoteWriteSettingsOperation(mContext, uid,
18704                 Settings.getPackageNameForUid(mContext, uid), false)) {
18705             return;
18706         }
18707
18708         String msg = "Permission Denial: " + func + " from pid="
18709                 + Binder.getCallingPid()
18710                 + ", uid=" + uid
18711                 + " requires " + android.Manifest.permission.WRITE_SETTINGS;
18712         Slog.w(TAG, msg);
18713         throw new SecurityException(msg);
18714     }
18715
18716     public void updateConfiguration(Configuration values) {
18717         enforceCallingPermission(android.Manifest.permission.CHANGE_CONFIGURATION,
18718                 "updateConfiguration()");
18719
18720         synchronized(this) {
18721             if (values == null && mWindowManager != null) {
18722                 // sentinel: fetch the current configuration from the window manager
18723                 values = mWindowManager.computeNewConfiguration();
18724             }
18725
18726             if (mWindowManager != null) {
18727                 mProcessList.applyDisplaySize(mWindowManager);
18728             }
18729
18730             final long origId = Binder.clearCallingIdentity();
18731             if (values != null) {
18732                 Settings.System.clearConfiguration(values);
18733             }
18734             updateConfigurationLocked(values, null, false);
18735             Binder.restoreCallingIdentity(origId);
18736         }
18737     }
18738
18739     void updateUserConfigurationLocked() {
18740         Configuration configuration = new Configuration(mConfiguration);
18741         Settings.System.adjustConfigurationForUser(mContext.getContentResolver(), configuration,
18742                 mUserController.getCurrentUserIdLocked(), Settings.System.canWrite(mContext));
18743         updateConfigurationLocked(configuration, null, false);
18744     }
18745
18746     boolean updateConfigurationLocked(Configuration values,
18747             ActivityRecord starting, boolean initLocale) {
18748         // pass UserHandle.USER_NULL as userId because we don't persist configuration for any user
18749         return updateConfigurationLocked(values, starting, initLocale, false,
18750                 UserHandle.USER_NULL);
18751     }
18752
18753     // To cache the list of supported system locales
18754     private String[] mSupportedSystemLocales = null;
18755
18756     /**
18757      * Do either or both things: (1) change the current configuration, and (2)
18758      * make sure the given activity is running with the (now) current
18759      * configuration.  Returns true if the activity has been left running, or
18760      * false if <var>starting</var> is being destroyed to match the new
18761      * configuration.
18762      *
18763      * @param userId is only used when persistent parameter is set to true to persist configuration
18764      *               for that particular user
18765      */
18766     private boolean updateConfigurationLocked(Configuration values,
18767             ActivityRecord starting, boolean initLocale, boolean persistent, int userId) {
18768         int changes = 0;
18769
18770         if (mWindowManager != null) {
18771             mWindowManager.deferSurfaceLayout();
18772         }
18773         if (values != null) {
18774             Configuration newConfig = new Configuration(mConfiguration);
18775             changes = newConfig.updateFrom(values);
18776             if (changes != 0) {
18777                 if (DEBUG_SWITCH || DEBUG_CONFIGURATION) Slog.i(TAG_CONFIGURATION,
18778                         "Updating configuration to: " + values);
18779
18780                 EventLog.writeEvent(EventLogTags.CONFIGURATION_CHANGED, changes);
18781
18782                 if (!initLocale && !values.getLocales().isEmpty() && values.userSetLocale) {
18783                     final LocaleList locales = values.getLocales();
18784                     int bestLocaleIndex = 0;
18785                     if (locales.size() > 1) {
18786                         if (mSupportedSystemLocales == null) {
18787                             mSupportedSystemLocales =
18788                                     Resources.getSystem().getAssets().getLocales();
18789                         }
18790                         bestLocaleIndex = Math.max(0,
18791                                 locales.getFirstMatchIndex(mSupportedSystemLocales));
18792                     }
18793                     SystemProperties.set("persist.sys.locale",
18794                             locales.get(bestLocaleIndex).toLanguageTag());
18795                     LocaleList.setDefault(locales, bestLocaleIndex);
18796                     mHandler.sendMessage(mHandler.obtainMessage(SEND_LOCALE_TO_MOUNT_DAEMON_MSG,
18797                             locales.get(bestLocaleIndex)));
18798                 }
18799
18800                 mConfigurationSeq++;
18801                 if (mConfigurationSeq <= 0) {
18802                     mConfigurationSeq = 1;
18803                 }
18804                 newConfig.seq = mConfigurationSeq;
18805                 mConfiguration = newConfig;
18806                 Slog.i(TAG, "Config changes=" + Integer.toHexString(changes) + " " + newConfig);
18807                 mUsageStatsService.reportConfigurationChange(newConfig,
18808                         mUserController.getCurrentUserIdLocked());
18809                 //mUsageStatsService.noteStartConfig(newConfig);
18810
18811                 final Configuration configCopy = new Configuration(mConfiguration);
18812
18813                 // TODO: If our config changes, should we auto dismiss any currently
18814                 // showing dialogs?
18815                 mShowDialogs = shouldShowDialogs(newConfig, mInVrMode);
18816
18817                 AttributeCache ac = AttributeCache.instance();
18818                 if (ac != null) {
18819                     ac.updateConfiguration(configCopy);
18820                 }
18821
18822                 // Make sure all resources in our process are updated
18823                 // right now, so that anyone who is going to retrieve
18824                 // resource values after we return will be sure to get
18825                 // the new ones.  This is especially important during
18826                 // boot, where the first config change needs to guarantee
18827                 // all resources have that config before following boot
18828                 // code is executed.
18829                 mSystemThread.applyConfigurationToResources(configCopy);
18830
18831                 if (persistent && Settings.System.hasInterestingConfigurationChanges(changes)) {
18832                     Message msg = mHandler.obtainMessage(UPDATE_CONFIGURATION_MSG);
18833                     msg.obj = new Configuration(configCopy);
18834                     msg.arg1 = userId;
18835                     mHandler.sendMessage(msg);
18836                 }
18837
18838                 final boolean isDensityChange = (changes & ActivityInfo.CONFIG_DENSITY) != 0;
18839                 if (isDensityChange) {
18840                     // Reset the unsupported display size dialog.
18841                     mUiHandler.sendEmptyMessage(SHOW_UNSUPPORTED_DISPLAY_SIZE_DIALOG_MSG);
18842
18843                     killAllBackgroundProcessesExcept(Build.VERSION_CODES.N,
18844                             ActivityManager.PROCESS_STATE_FOREGROUND_SERVICE);
18845                 }
18846
18847                 for (int i=mLruProcesses.size()-1; i>=0; i--) {
18848                     ProcessRecord app = mLruProcesses.get(i);
18849                     try {
18850                         if (app.thread != null) {
18851                             if (DEBUG_CONFIGURATION) Slog.v(TAG_CONFIGURATION, "Sending to proc "
18852                                     + app.processName + " new config " + mConfiguration);
18853                             app.thread.scheduleConfigurationChanged(configCopy);
18854                         }
18855                     } catch (Exception e) {
18856                     }
18857                 }
18858                 Intent intent = new Intent(Intent.ACTION_CONFIGURATION_CHANGED);
18859                 intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY
18860                         | Intent.FLAG_RECEIVER_REPLACE_PENDING
18861                         | Intent.FLAG_RECEIVER_FOREGROUND);
18862                 broadcastIntentLocked(null, null, intent, null, null, 0, null, null,
18863                         null, AppOpsManager.OP_NONE, null, false, false,
18864                         MY_PID, Process.SYSTEM_UID, UserHandle.USER_ALL);
18865                 if ((changes&ActivityInfo.CONFIG_LOCALE) != 0) {
18866                     // Tell the shortcut manager that the system locale changed.  It needs to know
18867                     // it before any other apps receive ACTION_LOCALE_CHANGED, which is why
18868                     // we "push" from here, rather than having the service listen to the broadcast.
18869                     final ShortcutServiceInternal shortcutService =
18870                             LocalServices.getService(ShortcutServiceInternal.class);
18871                     if (shortcutService != null) {
18872                         shortcutService.onSystemLocaleChangedNoLock();
18873                     }
18874
18875                     intent = new Intent(Intent.ACTION_LOCALE_CHANGED);
18876                     intent.addFlags(Intent.FLAG_RECEIVER_FOREGROUND);
18877                     if (!mProcessesReady) {
18878                         intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY);
18879                     }
18880                     broadcastIntentLocked(null, null, intent,
18881                             null, null, 0, null, null, null, AppOpsManager.OP_NONE,
18882                             null, false, false, MY_PID, Process.SYSTEM_UID, UserHandle.USER_ALL);
18883                 }
18884             }
18885             // Update the configuration with WM first and check if any of the stacks need to be
18886             // resized due to the configuration change. If so, resize the stacks now and do any
18887             // relaunches if necessary. This way we don't need to relaunch again below in
18888             // ensureActivityConfigurationLocked().
18889             if (mWindowManager != null) {
18890                 final int[] resizedStacks = mWindowManager.setNewConfiguration(mConfiguration);
18891                 if (resizedStacks != null) {
18892                     for (int stackId : resizedStacks) {
18893                         final Rect newBounds = mWindowManager.getBoundsForNewConfiguration(stackId);
18894                         mStackSupervisor.resizeStackLocked(
18895                                 stackId, newBounds, null, null, false, false, !DEFER_RESUME);
18896                     }
18897                 }
18898             }
18899         }
18900
18901         boolean kept = true;
18902         final ActivityStack mainStack = mStackSupervisor.getFocusedStack();
18903         // mainStack is null during startup.
18904         if (mainStack != null) {
18905             if (changes != 0 && starting == null) {
18906                 // If the configuration changed, and the caller is not already
18907                 // in the process of starting an activity, then find the top
18908                 // activity to check if its configuration needs to change.
18909                 starting = mainStack.topRunningActivityLocked();
18910             }
18911
18912             if (starting != null) {
18913                 kept = mainStack.ensureActivityConfigurationLocked(starting, changes, false);
18914                 // And we need to make sure at this point that all other activities
18915                 // are made visible with the correct configuration.
18916                 mStackSupervisor.ensureActivitiesVisibleLocked(starting, changes,
18917                         !PRESERVE_WINDOWS);
18918             }
18919         }
18920         if (mWindowManager != null) {
18921             mWindowManager.continueSurfaceLayout();
18922         }
18923         return kept;
18924     }
18925
18926     /**
18927      * Decide based on the configuration whether we should shouw the ANR,
18928      * crash, etc dialogs.  The idea is that if there is no affordnace to
18929      * press the on-screen buttons, we shouldn't show the dialog.
18930      *
18931      * A thought: SystemUI might also want to get told about this, the Power
18932      * dialog / global actions also might want different behaviors.
18933      */
18934     private static final boolean shouldShowDialogs(Configuration config, boolean inVrMode) {
18935         final boolean inputMethodExists = !(config.keyboard == Configuration.KEYBOARD_NOKEYS
18936                                    && config.touchscreen == Configuration.TOUCHSCREEN_NOTOUCH
18937                                    && config.navigation == Configuration.NAVIGATION_NONAV);
18938         final boolean uiIsNotCarType = !((config.uiMode & Configuration.UI_MODE_TYPE_MASK)
18939                                     == Configuration.UI_MODE_TYPE_CAR);
18940         return inputMethodExists && uiIsNotCarType && !inVrMode;
18941     }
18942
18943     @Override
18944     public boolean shouldUpRecreateTask(IBinder token, String destAffinity) {
18945         synchronized (this) {
18946             ActivityRecord srec = ActivityRecord.forTokenLocked(token);
18947             if (srec != null) {
18948                 return srec.task.stack.shouldUpRecreateTaskLocked(srec, destAffinity);
18949             }
18950         }
18951         return false;
18952     }
18953
18954     public boolean navigateUpTo(IBinder token, Intent destIntent, int resultCode,
18955             Intent resultData) {
18956
18957         synchronized (this) {
18958             final ActivityRecord r = ActivityRecord.forTokenLocked(token);
18959             if (r != null) {
18960                 return r.task.stack.navigateUpToLocked(r, destIntent, resultCode, resultData);
18961             }
18962             return false;
18963         }
18964     }
18965
18966     public int getLaunchedFromUid(IBinder activityToken) {
18967         ActivityRecord srec;
18968         synchronized (this) {
18969             srec = ActivityRecord.forTokenLocked(activityToken);
18970         }
18971         if (srec == null) {
18972             return -1;
18973         }
18974         return srec.launchedFromUid;
18975     }
18976
18977     public String getLaunchedFromPackage(IBinder activityToken) {
18978         ActivityRecord srec;
18979         synchronized (this) {
18980             srec = ActivityRecord.forTokenLocked(activityToken);
18981         }
18982         if (srec == null) {
18983             return null;
18984         }
18985         return srec.launchedFromPackage;
18986     }
18987
18988     // =========================================================
18989     // LIFETIME MANAGEMENT
18990     // =========================================================
18991
18992     // Returns which broadcast queue the app is the current [or imminent] receiver
18993     // on, or 'null' if the app is not an active broadcast recipient.
18994     private BroadcastQueue isReceivingBroadcast(ProcessRecord app) {
18995         BroadcastRecord r = app.curReceiver;
18996         if (r != null) {
18997             return r.queue;
18998         }
18999
19000         // It's not the current receiver, but it might be starting up to become one
19001         synchronized (this) {
19002             for (BroadcastQueue queue : mBroadcastQueues) {
19003                 r = queue.mPendingBroadcast;
19004                 if (r != null && r.curApp == app) {
19005                     // found it; report which queue it's in
19006                     return queue;
19007                 }
19008             }
19009         }
19010
19011         return null;
19012     }
19013
19014     Association startAssociationLocked(int sourceUid, String sourceProcess, int sourceState,
19015             int targetUid, ComponentName targetComponent, String targetProcess) {
19016         if (!mTrackingAssociations) {
19017             return null;
19018         }
19019         ArrayMap<ComponentName, SparseArray<ArrayMap<String, Association>>> components
19020                 = mAssociations.get(targetUid);
19021         if (components == null) {
19022             components = new ArrayMap<>();
19023             mAssociations.put(targetUid, components);
19024         }
19025         SparseArray<ArrayMap<String, Association>> sourceUids = components.get(targetComponent);
19026         if (sourceUids == null) {
19027             sourceUids = new SparseArray<>();
19028             components.put(targetComponent, sourceUids);
19029         }
19030         ArrayMap<String, Association> sourceProcesses = sourceUids.get(sourceUid);
19031         if (sourceProcesses == null) {
19032             sourceProcesses = new ArrayMap<>();
19033             sourceUids.put(sourceUid, sourceProcesses);
19034         }
19035         Association ass = sourceProcesses.get(sourceProcess);
19036         if (ass == null) {
19037             ass = new Association(sourceUid, sourceProcess, targetUid, targetComponent,
19038                     targetProcess);
19039             sourceProcesses.put(sourceProcess, ass);
19040         }
19041         ass.mCount++;
19042         ass.mNesting++;
19043         if (ass.mNesting == 1) {
19044             ass.mStartTime = ass.mLastStateUptime = SystemClock.uptimeMillis();
19045             ass.mLastState = sourceState;
19046         }
19047         return ass;
19048     }
19049
19050     void stopAssociationLocked(int sourceUid, String sourceProcess, int targetUid,
19051             ComponentName targetComponent) {
19052         if (!mTrackingAssociations) {
19053             return;
19054         }
19055         ArrayMap<ComponentName, SparseArray<ArrayMap<String, Association>>> components
19056                 = mAssociations.get(targetUid);
19057         if (components == null) {
19058             return;
19059         }
19060         SparseArray<ArrayMap<String, Association>> sourceUids = components.get(targetComponent);
19061         if (sourceUids == null) {
19062             return;
19063         }
19064         ArrayMap<String, Association> sourceProcesses = sourceUids.get(sourceUid);
19065         if (sourceProcesses == null) {
19066             return;
19067         }
19068         Association ass = sourceProcesses.get(sourceProcess);
19069         if (ass == null || ass.mNesting <= 0) {
19070             return;
19071         }
19072         ass.mNesting--;
19073         if (ass.mNesting == 0) {
19074             long uptime = SystemClock.uptimeMillis();
19075             ass.mTime += uptime - ass.mStartTime;
19076             ass.mStateTimes[ass.mLastState-ActivityManager.MIN_PROCESS_STATE]
19077                     += uptime - ass.mLastStateUptime;
19078             ass.mLastState = ActivityManager.MAX_PROCESS_STATE + 2;
19079         }
19080     }
19081
19082     private void noteUidProcessState(final int uid, final int state) {
19083         mBatteryStatsService.noteUidProcessState(uid, state);
19084         if (mTrackingAssociations) {
19085             for (int i1=0, N1=mAssociations.size(); i1<N1; i1++) {
19086                 ArrayMap<ComponentName, SparseArray<ArrayMap<String, Association>>> targetComponents
19087                         = mAssociations.valueAt(i1);
19088                 for (int i2=0, N2=targetComponents.size(); i2<N2; i2++) {
19089                     SparseArray<ArrayMap<String, Association>> sourceUids
19090                             = targetComponents.valueAt(i2);
19091                     ArrayMap<String, Association> sourceProcesses = sourceUids.get(uid);
19092                     if (sourceProcesses != null) {
19093                         for (int i4=0, N4=sourceProcesses.size(); i4<N4; i4++) {
19094                             Association ass = sourceProcesses.valueAt(i4);
19095                             if (ass.mNesting >= 1) {
19096                                 // currently associated
19097                                 long uptime = SystemClock.uptimeMillis();
19098                                 ass.mStateTimes[ass.mLastState-ActivityManager.MIN_PROCESS_STATE]
19099                                         += uptime - ass.mLastStateUptime;
19100                                 ass.mLastState = state;
19101                                 ass.mLastStateUptime = uptime;
19102                             }
19103                         }
19104                     }
19105                 }
19106             }
19107         }
19108     }
19109
19110     private final int computeOomAdjLocked(ProcessRecord app, int cachedAdj, ProcessRecord TOP_APP,
19111             boolean doingAll, long now) {
19112         if (mAdjSeq == app.adjSeq) {
19113             // This adjustment has already been computed.
19114             return app.curRawAdj;
19115         }
19116
19117         if (app.thread == null) {
19118             app.adjSeq = mAdjSeq;
19119             app.curSchedGroup = ProcessList.SCHED_GROUP_BACKGROUND;
19120             app.curProcState = ActivityManager.PROCESS_STATE_CACHED_EMPTY;
19121             return (app.curAdj=app.curRawAdj=ProcessList.CACHED_APP_MAX_ADJ);
19122         }
19123
19124         app.adjTypeCode = ActivityManager.RunningAppProcessInfo.REASON_UNKNOWN;
19125         app.adjSource = null;
19126         app.adjTarget = null;
19127         app.empty = false;
19128         app.cached = false;
19129
19130         final int activitiesSize = app.activities.size();
19131
19132         if (app.maxAdj <= ProcessList.FOREGROUND_APP_ADJ) {
19133             // The max adjustment doesn't allow this app to be anything
19134             // below foreground, so it is not worth doing work for it.
19135             app.adjType = "fixed";
19136             app.adjSeq = mAdjSeq;
19137             app.curRawAdj = app.maxAdj;
19138             app.foregroundActivities = false;
19139             app.curSchedGroup = ProcessList.SCHED_GROUP_DEFAULT;
19140             app.curProcState = ActivityManager.PROCESS_STATE_PERSISTENT;
19141             // System processes can do UI, and when they do we want to have
19142             // them trim their memory after the user leaves the UI.  To
19143             // facilitate this, here we need to determine whether or not it
19144             // is currently showing UI.
19145             app.systemNoUi = true;
19146             if (app == TOP_APP) {
19147                 app.systemNoUi = false;
19148                 app.curSchedGroup = ProcessList.SCHED_GROUP_TOP_APP;
19149                 app.adjType = "pers-top-activity";
19150             } else if (activitiesSize > 0) {
19151                 for (int j = 0; j < activitiesSize; j++) {
19152                     final ActivityRecord r = app.activities.get(j);
19153                     if (r.visible) {
19154                         app.systemNoUi = false;
19155                     }
19156                 }
19157             }
19158             if (!app.systemNoUi) {
19159                 app.curProcState = ActivityManager.PROCESS_STATE_PERSISTENT_UI;
19160             }
19161             return (app.curAdj=app.maxAdj);
19162         }
19163
19164         app.systemNoUi = false;
19165
19166         final int PROCESS_STATE_CUR_TOP = mTopProcessState;
19167
19168         // Determine the importance of the process, starting with most
19169         // important to least, and assign an appropriate OOM adjustment.
19170         int adj;
19171         int schedGroup;
19172         int procState;
19173         boolean foregroundActivities = false;
19174         BroadcastQueue queue;
19175         if (app == TOP_APP) {
19176             // The last app on the list is the foreground app.
19177             adj = ProcessList.FOREGROUND_APP_ADJ;
19178             schedGroup = ProcessList.SCHED_GROUP_TOP_APP;
19179             app.adjType = "top-activity";
19180             foregroundActivities = true;
19181             procState = PROCESS_STATE_CUR_TOP;
19182         } else if (app.instrumentationClass != null) {
19183             // Don't want to kill running instrumentation.
19184             adj = ProcessList.FOREGROUND_APP_ADJ;
19185             schedGroup = ProcessList.SCHED_GROUP_DEFAULT;
19186             app.adjType = "instrumentation";
19187             procState = ActivityManager.PROCESS_STATE_FOREGROUND_SERVICE;
19188         } else if ((queue = isReceivingBroadcast(app)) != null) {
19189             // An app that is currently receiving a broadcast also
19190             // counts as being in the foreground for OOM killer purposes.
19191             // It's placed in a sched group based on the nature of the
19192             // broadcast as reflected by which queue it's active in.
19193             adj = ProcessList.FOREGROUND_APP_ADJ;
19194             schedGroup = (queue == mFgBroadcastQueue)
19195                     ? ProcessList.SCHED_GROUP_DEFAULT : ProcessList.SCHED_GROUP_BACKGROUND;
19196             app.adjType = "broadcast";
19197             procState = ActivityManager.PROCESS_STATE_RECEIVER;
19198         } else if (app.executingServices.size() > 0) {
19199             // An app that is currently executing a service callback also
19200             // counts as being in the foreground.
19201             adj = ProcessList.FOREGROUND_APP_ADJ;
19202             schedGroup = app.execServicesFg ?
19203                     ProcessList.SCHED_GROUP_DEFAULT : ProcessList.SCHED_GROUP_BACKGROUND;
19204             app.adjType = "exec-service";
19205             procState = ActivityManager.PROCESS_STATE_SERVICE;
19206             //Slog.i(TAG, "EXEC " + (app.execServicesFg ? "FG" : "BG") + ": " + app);
19207         } else {
19208             // As far as we know the process is empty.  We may change our mind later.
19209             schedGroup = ProcessList.SCHED_GROUP_BACKGROUND;
19210             // At this point we don't actually know the adjustment.  Use the cached adj
19211             // value that the caller wants us to.
19212             adj = cachedAdj;
19213             procState = ActivityManager.PROCESS_STATE_CACHED_EMPTY;
19214             app.cached = true;
19215             app.empty = true;
19216             app.adjType = "cch-empty";
19217         }
19218
19219         // Examine all activities if not already foreground.
19220         if (!foregroundActivities && activitiesSize > 0) {
19221             int minLayer = ProcessList.VISIBLE_APP_LAYER_MAX;
19222             for (int j = 0; j < activitiesSize; j++) {
19223                 final ActivityRecord r = app.activities.get(j);
19224                 if (r.app != app) {
19225                     Log.e(TAG, "Found activity " + r + " in proc activity list using " + r.app
19226                             + " instead of expected " + app);
19227                     if (r.app == null || (r.app.uid == app.uid)) {
19228                         // Only fix things up when they look sane
19229                         r.app = app;
19230                     } else {
19231                         continue;
19232                     }
19233                 }
19234                 if (r.visible) {
19235                     // App has a visible activity; only upgrade adjustment.
19236                     if (adj > ProcessList.VISIBLE_APP_ADJ) {
19237                         adj = ProcessList.VISIBLE_APP_ADJ;
19238                         app.adjType = "visible";
19239                     }
19240                     if (procState > PROCESS_STATE_CUR_TOP) {
19241                         procState = PROCESS_STATE_CUR_TOP;
19242                     }
19243                     schedGroup = ProcessList.SCHED_GROUP_DEFAULT;
19244                     app.cached = false;
19245                     app.empty = false;
19246                     foregroundActivities = true;
19247                     if (r.task != null && minLayer > 0) {
19248                         final int layer = r.task.mLayerRank;
19249                         if (layer >= 0 && minLayer > layer) {
19250                             minLayer = layer;
19251                         }
19252                     }
19253                     break;
19254                 } else if (r.state == ActivityState.PAUSING || r.state == ActivityState.PAUSED) {
19255                     if (adj > ProcessList.PERCEPTIBLE_APP_ADJ) {
19256                         adj = ProcessList.PERCEPTIBLE_APP_ADJ;
19257                         app.adjType = "pausing";
19258                     }
19259                     if (procState > PROCESS_STATE_CUR_TOP) {
19260                         procState = PROCESS_STATE_CUR_TOP;
19261                     }
19262                     schedGroup = ProcessList.SCHED_GROUP_DEFAULT;
19263                     app.cached = false;
19264                     app.empty = false;
19265                     foregroundActivities = true;
19266                 } else if (r.state == ActivityState.STOPPING) {
19267                     if (adj > ProcessList.PERCEPTIBLE_APP_ADJ) {
19268                         adj = ProcessList.PERCEPTIBLE_APP_ADJ;
19269                         app.adjType = "stopping";
19270                     }
19271                     // For the process state, we will at this point consider the
19272                     // process to be cached.  It will be cached either as an activity
19273                     // or empty depending on whether the activity is finishing.  We do
19274                     // this so that we can treat the process as cached for purposes of
19275                     // memory trimming (determing current memory level, trim command to
19276                     // send to process) since there can be an arbitrary number of stopping
19277                     // processes and they should soon all go into the cached state.
19278                     if (!r.finishing) {
19279                         if (procState > ActivityManager.PROCESS_STATE_LAST_ACTIVITY) {
19280                             procState = ActivityManager.PROCESS_STATE_LAST_ACTIVITY;
19281                         }
19282                     }
19283                     app.cached = false;
19284                     app.empty = false;
19285                     foregroundActivities = true;
19286                 } else {
19287                     if (procState > ActivityManager.PROCESS_STATE_CACHED_ACTIVITY) {
19288                         procState = ActivityManager.PROCESS_STATE_CACHED_ACTIVITY;
19289                         app.adjType = "cch-act";
19290                     }
19291                 }
19292             }
19293             if (adj == ProcessList.VISIBLE_APP_ADJ) {
19294                 adj += minLayer;
19295             }
19296         }
19297
19298         if (adj > ProcessList.PERCEPTIBLE_APP_ADJ
19299                 || procState > ActivityManager.PROCESS_STATE_FOREGROUND_SERVICE) {
19300             if (app.foregroundServices) {
19301                 // The user is aware of this app, so make it visible.
19302                 adj = ProcessList.PERCEPTIBLE_APP_ADJ;
19303                 procState = ActivityManager.PROCESS_STATE_FOREGROUND_SERVICE;
19304                 app.cached = false;
19305                 app.adjType = "fg-service";
19306                 schedGroup = ProcessList.SCHED_GROUP_DEFAULT;
19307             } else if (app.forcingToForeground != null) {
19308                 // The user is aware of this app, so make it visible.
19309                 adj = ProcessList.PERCEPTIBLE_APP_ADJ;
19310                 procState = ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND;
19311                 app.cached = false;
19312                 app.adjType = "force-fg";
19313                 app.adjSource = app.forcingToForeground;
19314                 schedGroup = ProcessList.SCHED_GROUP_DEFAULT;
19315             }
19316         }
19317
19318         if (app == mHeavyWeightProcess) {
19319             if (adj > ProcessList.HEAVY_WEIGHT_APP_ADJ) {
19320                 // We don't want to kill the current heavy-weight process.
19321                 adj = ProcessList.HEAVY_WEIGHT_APP_ADJ;
19322                 schedGroup = ProcessList.SCHED_GROUP_BACKGROUND;
19323                 app.cached = false;
19324                 app.adjType = "heavy";
19325             }
19326             if (procState > ActivityManager.PROCESS_STATE_HEAVY_WEIGHT) {
19327                 procState = ActivityManager.PROCESS_STATE_HEAVY_WEIGHT;
19328             }
19329         }
19330
19331         if (app == mHomeProcess) {
19332             if (adj > ProcessList.HOME_APP_ADJ) {
19333                 // This process is hosting what we currently consider to be the
19334                 // home app, so we don't want to let it go into the background.
19335                 adj = ProcessList.HOME_APP_ADJ;
19336                 schedGroup = ProcessList.SCHED_GROUP_BACKGROUND;
19337                 app.cached = false;
19338                 app.adjType = "home";
19339             }
19340             if (procState > ActivityManager.PROCESS_STATE_HOME) {
19341                 procState = ActivityManager.PROCESS_STATE_HOME;
19342             }
19343         }
19344
19345         if (app == mPreviousProcess && app.activities.size() > 0) {
19346             if (adj > ProcessList.PREVIOUS_APP_ADJ) {
19347                 // This was the previous process that showed UI to the user.
19348                 // We want to try to keep it around more aggressively, to give
19349                 // a good experience around switching between two apps.
19350                 adj = ProcessList.PREVIOUS_APP_ADJ;
19351                 schedGroup = ProcessList.SCHED_GROUP_BACKGROUND;
19352                 app.cached = false;
19353                 app.adjType = "previous";
19354             }
19355             if (procState > ActivityManager.PROCESS_STATE_LAST_ACTIVITY) {
19356                 procState = ActivityManager.PROCESS_STATE_LAST_ACTIVITY;
19357             }
19358         }
19359
19360         if (false) Slog.i(TAG, "OOM " + app + ": initial adj=" + adj
19361                 + " reason=" + app.adjType);
19362
19363         // By default, we use the computed adjustment.  It may be changed if
19364         // there are applications dependent on our services or providers, but
19365         // this gives us a baseline and makes sure we don't get into an
19366         // infinite recursion.
19367         app.adjSeq = mAdjSeq;
19368         app.curRawAdj = adj;
19369         app.hasStartedServices = false;
19370
19371         if (mBackupTarget != null && app == mBackupTarget.app) {
19372             // If possible we want to avoid killing apps while they're being backed up
19373             if (adj > ProcessList.BACKUP_APP_ADJ) {
19374                 if (DEBUG_BACKUP) Slog.v(TAG_BACKUP, "oom BACKUP_APP_ADJ for " + app);
19375                 adj = ProcessList.BACKUP_APP_ADJ;
19376                 if (procState > ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND) {
19377                     procState = ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND;
19378                 }
19379                 app.adjType = "backup";
19380                 app.cached = false;
19381             }
19382             if (procState > ActivityManager.PROCESS_STATE_BACKUP) {
19383                 procState = ActivityManager.PROCESS_STATE_BACKUP;
19384             }
19385         }
19386
19387         boolean mayBeTop = false;
19388
19389         for (int is = app.services.size()-1;
19390                 is >= 0 && (adj > ProcessList.FOREGROUND_APP_ADJ
19391                         || schedGroup == ProcessList.SCHED_GROUP_BACKGROUND
19392                         || procState > ActivityManager.PROCESS_STATE_TOP);
19393                 is--) {
19394             ServiceRecord s = app.services.valueAt(is);
19395             if (s.startRequested) {
19396                 app.hasStartedServices = true;
19397                 if (procState > ActivityManager.PROCESS_STATE_SERVICE) {
19398                     procState = ActivityManager.PROCESS_STATE_SERVICE;
19399                 }
19400                 if (app.hasShownUi && app != mHomeProcess) {
19401                     // If this process has shown some UI, let it immediately
19402                     // go to the LRU list because it may be pretty heavy with
19403                     // UI stuff.  We'll tag it with a label just to help
19404                     // debug and understand what is going on.
19405                     if (adj > ProcessList.SERVICE_ADJ) {
19406                         app.adjType = "cch-started-ui-services";
19407                     }
19408                 } else {
19409                     if (now < (s.lastActivity + ActiveServices.MAX_SERVICE_INACTIVITY)) {
19410                         // This service has seen some activity within
19411                         // recent memory, so we will keep its process ahead
19412                         // of the background processes.
19413                         if (adj > ProcessList.SERVICE_ADJ) {
19414                             adj = ProcessList.SERVICE_ADJ;
19415                             app.adjType = "started-services";
19416                             app.cached = false;
19417                         }
19418                     }
19419                     // If we have let the service slide into the background
19420                     // state, still have some text describing what it is doing
19421                     // even though the service no longer has an impact.
19422                     if (adj > ProcessList.SERVICE_ADJ) {
19423                         app.adjType = "cch-started-services";
19424                     }
19425                 }
19426             }
19427
19428             for (int conni = s.connections.size()-1;
19429                     conni >= 0 && (adj > ProcessList.FOREGROUND_APP_ADJ
19430                             || schedGroup == ProcessList.SCHED_GROUP_BACKGROUND
19431                             || procState > ActivityManager.PROCESS_STATE_TOP);
19432                     conni--) {
19433                 ArrayList<ConnectionRecord> clist = s.connections.valueAt(conni);
19434                 for (int i = 0;
19435                         i < clist.size() && (adj > ProcessList.FOREGROUND_APP_ADJ
19436                                 || schedGroup == ProcessList.SCHED_GROUP_BACKGROUND
19437                                 || procState > ActivityManager.PROCESS_STATE_TOP);
19438                         i++) {
19439                     // XXX should compute this based on the max of
19440                     // all connected clients.
19441                     ConnectionRecord cr = clist.get(i);
19442                     if (cr.binding.client == app) {
19443                         // Binding to ourself is not interesting.
19444                         continue;
19445                     }
19446
19447                     if ((cr.flags&Context.BIND_WAIVE_PRIORITY) == 0) {
19448                         ProcessRecord client = cr.binding.client;
19449                         int clientAdj = computeOomAdjLocked(client, cachedAdj,
19450                                 TOP_APP, doingAll, now);
19451                         int clientProcState = client.curProcState;
19452                         if (clientProcState >= ActivityManager.PROCESS_STATE_CACHED_ACTIVITY) {
19453                             // If the other app is cached for any reason, for purposes here
19454                             // we are going to consider it empty.  The specific cached state
19455                             // doesn't propagate except under certain conditions.
19456                             clientProcState = ActivityManager.PROCESS_STATE_CACHED_EMPTY;
19457                         }
19458                         String adjType = null;
19459                         if ((cr.flags&Context.BIND_ALLOW_OOM_MANAGEMENT) != 0) {
19460                             // Not doing bind OOM management, so treat
19461                             // this guy more like a started service.
19462                             if (app.hasShownUi && app != mHomeProcess) {
19463                                 // If this process has shown some UI, let it immediately
19464                                 // go to the LRU list because it may be pretty heavy with
19465                                 // UI stuff.  We'll tag it with a label just to help
19466                                 // debug and understand what is going on.
19467                                 if (adj > clientAdj) {
19468                                     adjType = "cch-bound-ui-services";
19469                                 }
19470                                 app.cached = false;
19471                                 clientAdj = adj;
19472                                 clientProcState = procState;
19473                             } else {
19474                                 if (now >= (s.lastActivity
19475                                         + ActiveServices.MAX_SERVICE_INACTIVITY)) {
19476                                     // This service has not seen activity within
19477                                     // recent memory, so allow it to drop to the
19478                                     // LRU list if there is no other reason to keep
19479                                     // it around.  We'll also tag it with a label just
19480                                     // to help debug and undertand what is going on.
19481                                     if (adj > clientAdj) {
19482                                         adjType = "cch-bound-services";
19483                                     }
19484                                     clientAdj = adj;
19485                                 }
19486                             }
19487                         }
19488                         if (adj > clientAdj) {
19489                             // If this process has recently shown UI, and
19490                             // the process that is binding to it is less
19491                             // important than being visible, then we don't
19492                             // care about the binding as much as we care
19493                             // about letting this process get into the LRU
19494                             // list to be killed and restarted if needed for
19495                             // memory.
19496                             if (app.hasShownUi && app != mHomeProcess
19497                                     && clientAdj > ProcessList.PERCEPTIBLE_APP_ADJ) {
19498                                 adjType = "cch-bound-ui-services";
19499                             } else {
19500                                 if ((cr.flags&(Context.BIND_ABOVE_CLIENT
19501                                         |Context.BIND_IMPORTANT)) != 0) {
19502                                     adj = clientAdj >= ProcessList.PERSISTENT_SERVICE_ADJ
19503                                             ? clientAdj : ProcessList.PERSISTENT_SERVICE_ADJ;
19504                                 } else if ((cr.flags&Context.BIND_NOT_VISIBLE) != 0
19505                                         && clientAdj < ProcessList.PERCEPTIBLE_APP_ADJ
19506                                         && adj > ProcessList.PERCEPTIBLE_APP_ADJ) {
19507                                     adj = ProcessList.PERCEPTIBLE_APP_ADJ;
19508                                 } else if (clientAdj >= ProcessList.PERCEPTIBLE_APP_ADJ) {
19509                                     adj = clientAdj;
19510                                 } else {
19511                                     if (adj > ProcessList.VISIBLE_APP_ADJ) {
19512                                         adj = Math.max(clientAdj, ProcessList.VISIBLE_APP_ADJ);
19513                                     }
19514                                 }
19515                                 if (!client.cached) {
19516                                     app.cached = false;
19517                                 }
19518                                 adjType = "service";
19519                             }
19520                         }
19521                         if ((cr.flags&Context.BIND_NOT_FOREGROUND) == 0) {
19522                             // This will treat important bound services identically to
19523                             // the top app, which may behave differently than generic
19524                             // foreground work.
19525                             if (client.curSchedGroup > schedGroup) {
19526                                 if ((cr.flags&Context.BIND_IMPORTANT) != 0) {
19527                                     schedGroup = client.curSchedGroup;
19528                                 } else {
19529                                     schedGroup = ProcessList.SCHED_GROUP_DEFAULT;
19530                                 }
19531                             }
19532                             if (clientProcState <= ActivityManager.PROCESS_STATE_TOP) {
19533                                 if (clientProcState == ActivityManager.PROCESS_STATE_TOP) {
19534                                     // Special handling of clients who are in the top state.
19535                                     // We *may* want to consider this process to be in the
19536                                     // top state as well, but only if there is not another
19537                                     // reason for it to be running.  Being on the top is a
19538                                     // special state, meaning you are specifically running
19539                                     // for the current top app.  If the process is already
19540                                     // running in the background for some other reason, it
19541                                     // is more important to continue considering it to be
19542                                     // in the background state.
19543                                     mayBeTop = true;
19544                                     clientProcState = ActivityManager.PROCESS_STATE_CACHED_EMPTY;
19545                                 } else {
19546                                     // Special handling for above-top states (persistent
19547                                     // processes).  These should not bring the current process
19548                                     // into the top state, since they are not on top.  Instead
19549                                     // give them the best state after that.
19550                                     if ((cr.flags&Context.BIND_FOREGROUND_SERVICE) != 0) {
19551                                         clientProcState =
19552                                                 ActivityManager.PROCESS_STATE_BOUND_FOREGROUND_SERVICE;
19553                                     } else if (mWakefulness
19554                                                     == PowerManagerInternal.WAKEFULNESS_AWAKE &&
19555                                             (cr.flags&Context.BIND_FOREGROUND_SERVICE_WHILE_AWAKE)
19556                                                     != 0) {
19557                                         clientProcState =
19558                                                 ActivityManager.PROCESS_STATE_BOUND_FOREGROUND_SERVICE;
19559                                     } else {
19560                                         clientProcState =
19561                                                 ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND;
19562                                     }
19563                                 }
19564                             }
19565                         } else {
19566                             if (clientProcState <
19567                                     ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND) {
19568                                 clientProcState =
19569                                         ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND;
19570                             }
19571                         }
19572                         if (procState > clientProcState) {
19573                             procState = clientProcState;
19574                         }
19575                         if (procState < ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND
19576                                 && (cr.flags&Context.BIND_SHOWING_UI) != 0) {
19577                             app.pendingUiClean = true;
19578                         }
19579                         if (adjType != null) {
19580                             app.adjType = adjType;
19581                             app.adjTypeCode = ActivityManager.RunningAppProcessInfo
19582                                     .REASON_SERVICE_IN_USE;
19583                             app.adjSource = cr.binding.client;
19584                             app.adjSourceProcState = clientProcState;
19585                             app.adjTarget = s.name;
19586                         }
19587                     }
19588                     if ((cr.flags&Context.BIND_TREAT_LIKE_ACTIVITY) != 0) {
19589                         app.treatLikeActivity = true;
19590                     }
19591                     final ActivityRecord a = cr.activity;
19592                     if ((cr.flags&Context.BIND_ADJUST_WITH_ACTIVITY) != 0) {
19593                         if (a != null && adj > ProcessList.FOREGROUND_APP_ADJ &&
19594                             (a.visible || a.state == ActivityState.RESUMED ||
19595                              a.state == ActivityState.PAUSING)) {
19596                             adj = ProcessList.FOREGROUND_APP_ADJ;
19597                             if ((cr.flags&Context.BIND_NOT_FOREGROUND) == 0) {
19598                                 if ((cr.flags&Context.BIND_IMPORTANT) != 0) {
19599                                     schedGroup = ProcessList.SCHED_GROUP_TOP_APP;
19600                                 } else {
19601                                     schedGroup = ProcessList.SCHED_GROUP_DEFAULT;
19602                                 }
19603                             }
19604                             app.cached = false;
19605                             app.adjType = "service";
19606                             app.adjTypeCode = ActivityManager.RunningAppProcessInfo
19607                                     .REASON_SERVICE_IN_USE;
19608                             app.adjSource = a;
19609                             app.adjSourceProcState = procState;
19610                             app.adjTarget = s.name;
19611                         }
19612                     }
19613                 }
19614             }
19615         }
19616
19617         for (int provi = app.pubProviders.size()-1;
19618                 provi >= 0 && (adj > ProcessList.FOREGROUND_APP_ADJ
19619                         || schedGroup == ProcessList.SCHED_GROUP_BACKGROUND
19620                         || procState > ActivityManager.PROCESS_STATE_TOP);
19621                 provi--) {
19622             ContentProviderRecord cpr = app.pubProviders.valueAt(provi);
19623             for (int i = cpr.connections.size()-1;
19624                     i >= 0 && (adj > ProcessList.FOREGROUND_APP_ADJ
19625                             || schedGroup == ProcessList.SCHED_GROUP_BACKGROUND
19626                             || procState > ActivityManager.PROCESS_STATE_TOP);
19627                     i--) {
19628                 ContentProviderConnection conn = cpr.connections.get(i);
19629                 ProcessRecord client = conn.client;
19630                 if (client == app) {
19631                     // Being our own client is not interesting.
19632                     continue;
19633                 }
19634                 int clientAdj = computeOomAdjLocked(client, cachedAdj, TOP_APP, doingAll, now);
19635                 int clientProcState = client.curProcState;
19636                 if (clientProcState >= ActivityManager.PROCESS_STATE_CACHED_ACTIVITY) {
19637                     // If the other app is cached for any reason, for purposes here
19638                     // we are going to consider it empty.
19639                     clientProcState = ActivityManager.PROCESS_STATE_CACHED_EMPTY;
19640                 }
19641                 if (adj > clientAdj) {
19642                     if (app.hasShownUi && app != mHomeProcess
19643                             && clientAdj > ProcessList.PERCEPTIBLE_APP_ADJ) {
19644                         app.adjType = "cch-ui-provider";
19645                     } else {
19646                         adj = clientAdj > ProcessList.FOREGROUND_APP_ADJ
19647                                 ? clientAdj : ProcessList.FOREGROUND_APP_ADJ;
19648                         app.adjType = "provider";
19649                     }
19650                     app.cached &= client.cached;
19651                     app.adjTypeCode = ActivityManager.RunningAppProcessInfo
19652                             .REASON_PROVIDER_IN_USE;
19653                     app.adjSource = client;
19654                     app.adjSourceProcState = clientProcState;
19655                     app.adjTarget = cpr.name;
19656                 }
19657                 if (clientProcState <= ActivityManager.PROCESS_STATE_TOP) {
19658                     if (clientProcState == ActivityManager.PROCESS_STATE_TOP) {
19659                         // Special handling of clients who are in the top state.
19660                         // We *may* want to consider this process to be in the
19661                         // top state as well, but only if there is not another
19662                         // reason for it to be running.  Being on the top is a
19663                         // special state, meaning you are specifically running
19664                         // for the current top app.  If the process is already
19665                         // running in the background for some other reason, it
19666                         // is more important to continue considering it to be
19667                         // in the background state.
19668                         mayBeTop = true;
19669                         clientProcState = ActivityManager.PROCESS_STATE_CACHED_EMPTY;
19670                     } else {
19671                         // Special handling for above-top states (persistent
19672                         // processes).  These should not bring the current process
19673                         // into the top state, since they are not on top.  Instead
19674                         // give them the best state after that.
19675                         clientProcState =
19676                                 ActivityManager.PROCESS_STATE_BOUND_FOREGROUND_SERVICE;
19677                     }
19678                 }
19679                 if (procState > clientProcState) {
19680                     procState = clientProcState;
19681                 }
19682                 if (client.curSchedGroup > schedGroup) {
19683                     schedGroup = ProcessList.SCHED_GROUP_DEFAULT;
19684                 }
19685             }
19686             // If the provider has external (non-framework) process
19687             // dependencies, ensure that its adjustment is at least
19688             // FOREGROUND_APP_ADJ.
19689             if (cpr.hasExternalProcessHandles()) {
19690                 if (adj > ProcessList.FOREGROUND_APP_ADJ) {
19691                     adj = ProcessList.FOREGROUND_APP_ADJ;
19692                     schedGroup = ProcessList.SCHED_GROUP_DEFAULT;
19693                     app.cached = false;
19694                     app.adjType = "provider";
19695                     app.adjTarget = cpr.name;
19696                 }
19697                 if (procState > ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND) {
19698                     procState = ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND;
19699                 }
19700             }
19701         }
19702
19703         if (app.lastProviderTime > 0 && (app.lastProviderTime+CONTENT_PROVIDER_RETAIN_TIME) > now) {
19704             if (adj > ProcessList.PREVIOUS_APP_ADJ) {
19705                 adj = ProcessList.PREVIOUS_APP_ADJ;
19706                 schedGroup = ProcessList.SCHED_GROUP_BACKGROUND;
19707                 app.cached = false;
19708                 app.adjType = "provider";
19709             }
19710             if (procState > ActivityManager.PROCESS_STATE_LAST_ACTIVITY) {
19711                 procState = ActivityManager.PROCESS_STATE_LAST_ACTIVITY;
19712             }
19713         }
19714
19715         if (mayBeTop && procState > ActivityManager.PROCESS_STATE_TOP) {
19716             // A client of one of our services or providers is in the top state.  We
19717             // *may* want to be in the top state, but not if we are already running in
19718             // the background for some other reason.  For the decision here, we are going
19719             // to pick out a few specific states that we want to remain in when a client
19720             // is top (states that tend to be longer-term) and otherwise allow it to go
19721             // to the top state.
19722             switch (procState) {
19723                 case ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND:
19724                 case ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND:
19725                 case ActivityManager.PROCESS_STATE_SERVICE:
19726                     // These all are longer-term states, so pull them up to the top
19727                     // of the background states, but not all the way to the top state.
19728                     procState = ActivityManager.PROCESS_STATE_BOUND_FOREGROUND_SERVICE;
19729                     break;
19730                 default:
19731                     // Otherwise, top is a better choice, so take it.
19732                     procState = ActivityManager.PROCESS_STATE_TOP;
19733                     break;
19734             }
19735         }
19736
19737         if (procState >= ActivityManager.PROCESS_STATE_CACHED_EMPTY) {
19738             if (app.hasClientActivities) {
19739                 // This is a cached process, but with client activities.  Mark it so.
19740                 procState = ActivityManager.PROCESS_STATE_CACHED_ACTIVITY_CLIENT;
19741                 app.adjType = "cch-client-act";
19742             } else if (app.treatLikeActivity) {
19743                 // This is a cached process, but somebody wants us to treat it like it has
19744                 // an activity, okay!
19745                 procState = ActivityManager.PROCESS_STATE_CACHED_ACTIVITY;
19746                 app.adjType = "cch-as-act";
19747             }
19748         }
19749
19750         if (adj == ProcessList.SERVICE_ADJ) {
19751             if (doingAll) {
19752                 app.serviceb = mNewNumAServiceProcs > (mNumServiceProcs/3);
19753                 mNewNumServiceProcs++;
19754                 //Slog.i(TAG, "ADJ " + app + " serviceb=" + app.serviceb);
19755                 if (!app.serviceb) {
19756                     // This service isn't far enough down on the LRU list to
19757                     // normally be a B service, but if we are low on RAM and it
19758                     // is large we want to force it down since we would prefer to
19759                     // keep launcher over it.
19760                     if (mLastMemoryLevel > ProcessStats.ADJ_MEM_FACTOR_NORMAL
19761                             && app.lastPss >= mProcessList.getCachedRestoreThresholdKb()) {
19762                         app.serviceHighRam = true;
19763                         app.serviceb = true;
19764                         //Slog.i(TAG, "ADJ " + app + " high ram!");
19765                     } else {
19766                         mNewNumAServiceProcs++;
19767                         //Slog.i(TAG, "ADJ " + app + " not high ram!");
19768                     }
19769                 } else {
19770                     app.serviceHighRam = false;
19771                 }
19772             }
19773             if (app.serviceb) {
19774                 adj = ProcessList.SERVICE_B_ADJ;
19775             }
19776         }
19777
19778         app.curRawAdj = adj;
19779
19780         //Slog.i(TAG, "OOM ADJ " + app + ": pid=" + app.pid +
19781         //      " adj=" + adj + " curAdj=" + app.curAdj + " maxAdj=" + app.maxAdj);
19782         if (adj > app.maxAdj) {
19783             adj = app.maxAdj;
19784             if (app.maxAdj <= ProcessList.PERCEPTIBLE_APP_ADJ) {
19785                 schedGroup = ProcessList.SCHED_GROUP_DEFAULT;
19786             }
19787         }
19788
19789         // Do final modification to adj.  Everything we do between here and applying
19790         // the final setAdj must be done in this function, because we will also use
19791         // it when computing the final cached adj later.  Note that we don't need to
19792         // worry about this for max adj above, since max adj will always be used to
19793         // keep it out of the cached vaues.
19794         app.curAdj = app.modifyRawOomAdj(adj);
19795         app.curSchedGroup = schedGroup;
19796         app.curProcState = procState;
19797         app.foregroundActivities = foregroundActivities;
19798
19799         return app.curRawAdj;
19800     }
19801
19802     /**
19803      * Record new PSS sample for a process.
19804      */
19805     void recordPssSampleLocked(ProcessRecord proc, int procState, long pss, long uss, long swapPss,
19806             long now) {
19807         EventLogTags.writeAmPss(proc.pid, proc.uid, proc.processName, pss * 1024, uss * 1024,
19808                 swapPss * 1024);
19809         proc.lastPssTime = now;
19810         proc.baseProcessTracker.addPss(pss, uss, true, proc.pkgList);
19811         if (DEBUG_PSS) Slog.d(TAG_PSS,
19812                 "PSS of " + proc.toShortString() + ": " + pss + " lastPss=" + proc.lastPss
19813                 + " state=" + ProcessList.makeProcStateString(procState));
19814         if (proc.initialIdlePss == 0) {
19815             proc.initialIdlePss = pss;
19816         }
19817         proc.lastPss = pss;
19818         proc.lastSwapPss = swapPss;
19819         if (procState >= ActivityManager.PROCESS_STATE_HOME) {
19820             proc.lastCachedPss = pss;
19821             proc.lastCachedSwapPss = swapPss;
19822         }
19823
19824         final SparseArray<Pair<Long, String>> watchUids
19825                 = mMemWatchProcesses.getMap().get(proc.processName);
19826         Long check = null;
19827         if (watchUids != null) {
19828             Pair<Long, String> val = watchUids.get(proc.uid);
19829             if (val == null) {
19830                 val = watchUids.get(0);
19831             }
19832             if (val != null) {
19833                 check = val.first;
19834             }
19835         }
19836         if (check != null) {
19837             if ((pss * 1024) >= check && proc.thread != null && mMemWatchDumpProcName == null) {
19838                 boolean isDebuggable = "1".equals(SystemProperties.get(SYSTEM_DEBUGGABLE, "0"));
19839                 if (!isDebuggable) {
19840                     if ((proc.info.flags&ApplicationInfo.FLAG_DEBUGGABLE) != 0) {
19841                         isDebuggable = true;
19842                     }
19843                 }
19844                 if (isDebuggable) {
19845                     Slog.w(TAG, "Process " + proc + " exceeded pss limit " + check + "; reporting");
19846                     final ProcessRecord myProc = proc;
19847                     final File heapdumpFile = DumpHeapProvider.getJavaFile();
19848                     mMemWatchDumpProcName = proc.processName;
19849                     mMemWatchDumpFile = heapdumpFile.toString();
19850                     mMemWatchDumpPid = proc.pid;
19851                     mMemWatchDumpUid = proc.uid;
19852                     BackgroundThread.getHandler().post(new Runnable() {
19853                         @Override
19854                         public void run() {
19855                             revokeUriPermission(ActivityThread.currentActivityThread()
19856                                             .getApplicationThread(),
19857                                     DumpHeapActivity.JAVA_URI,
19858                                     Intent.FLAG_GRANT_READ_URI_PERMISSION
19859                                             | Intent.FLAG_GRANT_WRITE_URI_PERMISSION,
19860                                     UserHandle.myUserId());
19861                             ParcelFileDescriptor fd = null;
19862                             try {
19863                                 heapdumpFile.delete();
19864                                 fd = ParcelFileDescriptor.open(heapdumpFile,
19865                                         ParcelFileDescriptor.MODE_CREATE |
19866                                                 ParcelFileDescriptor.MODE_TRUNCATE |
19867                                                 ParcelFileDescriptor.MODE_WRITE_ONLY |
19868                                                 ParcelFileDescriptor.MODE_APPEND);
19869                                 IApplicationThread thread = myProc.thread;
19870                                 if (thread != null) {
19871                                     try {
19872                                         if (DEBUG_PSS) Slog.d(TAG_PSS,
19873                                                 "Requesting dump heap from "
19874                                                 + myProc + " to " + heapdumpFile);
19875                                         thread.dumpHeap(true, heapdumpFile.toString(), fd);
19876                                     } catch (RemoteException e) {
19877                                     }
19878                                 }
19879                             } catch (FileNotFoundException e) {
19880                                 e.printStackTrace();
19881                             } finally {
19882                                 if (fd != null) {
19883                                     try {
19884                                         fd.close();
19885                                     } catch (IOException e) {
19886                                     }
19887                                 }
19888                             }
19889                         }
19890                     });
19891                 } else {
19892                     Slog.w(TAG, "Process " + proc + " exceeded pss limit " + check
19893                             + ", but debugging not enabled");
19894                 }
19895             }
19896         }
19897     }
19898
19899     /**
19900      * Schedule PSS collection of a process.
19901      */
19902     void requestPssLocked(ProcessRecord proc, int procState) {
19903         if (mPendingPssProcesses.contains(proc)) {
19904             return;
19905         }
19906         if (mPendingPssProcesses.size() == 0) {
19907             mBgHandler.sendEmptyMessage(COLLECT_PSS_BG_MSG);
19908         }
19909         if (DEBUG_PSS) Slog.d(TAG_PSS, "Requesting PSS of: " + proc);
19910         proc.pssProcState = procState;
19911         mPendingPssProcesses.add(proc);
19912     }
19913
19914     /**
19915      * Schedule PSS collection of all processes.
19916      */
19917     void requestPssAllProcsLocked(long now, boolean always, boolean memLowered) {
19918         if (!always) {
19919             if (now < (mLastFullPssTime +
19920                     (memLowered ? FULL_PSS_LOWERED_INTERVAL : FULL_PSS_MIN_INTERVAL))) {
19921                 return;
19922             }
19923         }
19924         if (DEBUG_PSS) Slog.d(TAG_PSS, "Requesting PSS of all procs!  memLowered=" + memLowered);
19925         mLastFullPssTime = now;
19926         mFullPssPending = true;
19927         mPendingPssProcesses.ensureCapacity(mLruProcesses.size());
19928         mPendingPssProcesses.clear();
19929         for (int i = mLruProcesses.size() - 1; i >= 0; i--) {
19930             ProcessRecord app = mLruProcesses.get(i);
19931             if (app.thread == null
19932                     || app.curProcState == ActivityManager.PROCESS_STATE_NONEXISTENT) {
19933                 continue;
19934             }
19935             if (memLowered || now > (app.lastStateTime+ProcessList.PSS_ALL_INTERVAL)) {
19936                 app.pssProcState = app.setProcState;
19937                 app.nextPssTime = ProcessList.computeNextPssTime(app.curProcState, true,
19938                         mTestPssMode, isSleepingLocked(), now);
19939                 mPendingPssProcesses.add(app);
19940             }
19941         }
19942         mBgHandler.sendEmptyMessage(COLLECT_PSS_BG_MSG);
19943     }
19944
19945     public void setTestPssMode(boolean enabled) {
19946         synchronized (this) {
19947             mTestPssMode = enabled;
19948             if (enabled) {
19949                 // Whenever we enable the mode, we want to take a snapshot all of current
19950                 // process mem use.
19951                 requestPssAllProcsLocked(SystemClock.uptimeMillis(), true, true);
19952             }
19953         }
19954     }
19955
19956     /**
19957      * Ask a given process to GC right now.
19958      */
19959     final void performAppGcLocked(ProcessRecord app) {
19960         try {
19961             app.lastRequestedGc = SystemClock.uptimeMillis();
19962             if (app.thread != null) {
19963                 if (app.reportLowMemory) {
19964                     app.reportLowMemory = false;
19965                     app.thread.scheduleLowMemory();
19966                 } else {
19967                     app.thread.processInBackground();
19968                 }
19969             }
19970         } catch (Exception e) {
19971             // whatever.
19972         }
19973     }
19974
19975     /**
19976      * Returns true if things are idle enough to perform GCs.
19977      */
19978     private final boolean canGcNowLocked() {
19979         boolean processingBroadcasts = false;
19980         for (BroadcastQueue q : mBroadcastQueues) {
19981             if (q.mParallelBroadcasts.size() != 0 || q.mOrderedBroadcasts.size() != 0) {
19982                 processingBroadcasts = true;
19983             }
19984         }
19985         return !processingBroadcasts
19986                 && (isSleepingLocked() || mStackSupervisor.allResumedActivitiesIdle());
19987     }
19988
19989     /**
19990      * Perform GCs on all processes that are waiting for it, but only
19991      * if things are idle.
19992      */
19993     final void performAppGcsLocked() {
19994         final int N = mProcessesToGc.size();
19995         if (N <= 0) {
19996             return;
19997         }
19998         if (canGcNowLocked()) {
19999             while (mProcessesToGc.size() > 0) {
20000                 ProcessRecord proc = mProcessesToGc.remove(0);
20001                 if (proc.curRawAdj > ProcessList.PERCEPTIBLE_APP_ADJ || proc.reportLowMemory) {
20002                     if ((proc.lastRequestedGc+GC_MIN_INTERVAL)
20003                             <= SystemClock.uptimeMillis()) {
20004                         // To avoid spamming the system, we will GC processes one
20005                         // at a time, waiting a few seconds between each.
20006                         performAppGcLocked(proc);
20007                         scheduleAppGcsLocked();
20008                         return;
20009                     } else {
20010                         // It hasn't been long enough since we last GCed this
20011                         // process...  put it in the list to wait for its time.
20012                         addProcessToGcListLocked(proc);
20013                         break;
20014                     }
20015                 }
20016             }
20017
20018             scheduleAppGcsLocked();
20019         }
20020     }
20021
20022     /**
20023      * If all looks good, perform GCs on all processes waiting for them.
20024      */
20025     final void performAppGcsIfAppropriateLocked() {
20026         if (canGcNowLocked()) {
20027             performAppGcsLocked();
20028             return;
20029         }
20030         // Still not idle, wait some more.
20031         scheduleAppGcsLocked();
20032     }
20033
20034     /**
20035      * Schedule the execution of all pending app GCs.
20036      */
20037     final void scheduleAppGcsLocked() {
20038         mHandler.removeMessages(GC_BACKGROUND_PROCESSES_MSG);
20039
20040         if (mProcessesToGc.size() > 0) {
20041             // Schedule a GC for the time to the next process.
20042             ProcessRecord proc = mProcessesToGc.get(0);
20043             Message msg = mHandler.obtainMessage(GC_BACKGROUND_PROCESSES_MSG);
20044
20045             long when = proc.lastRequestedGc + GC_MIN_INTERVAL;
20046             long now = SystemClock.uptimeMillis();
20047             if (when < (now+GC_TIMEOUT)) {
20048                 when = now + GC_TIMEOUT;
20049             }
20050             mHandler.sendMessageAtTime(msg, when);
20051         }
20052     }
20053
20054     /**
20055      * Add a process to the array of processes waiting to be GCed.  Keeps the
20056      * list in sorted order by the last GC time.  The process can't already be
20057      * on the list.
20058      */
20059     final void addProcessToGcListLocked(ProcessRecord proc) {
20060         boolean added = false;
20061         for (int i=mProcessesToGc.size()-1; i>=0; i--) {
20062             if (mProcessesToGc.get(i).lastRequestedGc <
20063                     proc.lastRequestedGc) {
20064                 added = true;
20065                 mProcessesToGc.add(i+1, proc);
20066                 break;
20067             }
20068         }
20069         if (!added) {
20070             mProcessesToGc.add(0, proc);
20071         }
20072     }
20073
20074     /**
20075      * Set up to ask a process to GC itself.  This will either do it
20076      * immediately, or put it on the list of processes to gc the next
20077      * time things are idle.
20078      */
20079     final void scheduleAppGcLocked(ProcessRecord app) {
20080         long now = SystemClock.uptimeMillis();
20081         if ((app.lastRequestedGc+GC_MIN_INTERVAL) > now) {
20082             return;
20083         }
20084         if (!mProcessesToGc.contains(app)) {
20085             addProcessToGcListLocked(app);
20086             scheduleAppGcsLocked();
20087         }
20088     }
20089
20090     final void checkExcessivePowerUsageLocked(boolean doKills) {
20091         updateCpuStatsNow();
20092
20093         BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
20094         boolean doWakeKills = doKills;
20095         boolean doCpuKills = doKills;
20096         if (mLastPowerCheckRealtime == 0) {
20097             doWakeKills = false;
20098         }
20099         if (mLastPowerCheckUptime == 0) {
20100             doCpuKills = false;
20101         }
20102         if (stats.isScreenOn()) {
20103             doWakeKills = false;
20104         }
20105         final long curRealtime = SystemClock.elapsedRealtime();
20106         final long realtimeSince = curRealtime - mLastPowerCheckRealtime;
20107         final long curUptime = SystemClock.uptimeMillis();
20108         final long uptimeSince = curUptime - mLastPowerCheckUptime;
20109         mLastPowerCheckRealtime = curRealtime;
20110         mLastPowerCheckUptime = curUptime;
20111         if (realtimeSince < WAKE_LOCK_MIN_CHECK_DURATION) {
20112             doWakeKills = false;
20113         }
20114         if (uptimeSince < CPU_MIN_CHECK_DURATION) {
20115             doCpuKills = false;
20116         }
20117         int i = mLruProcesses.size();
20118         while (i > 0) {
20119             i--;
20120             ProcessRecord app = mLruProcesses.get(i);
20121             if (app.setProcState >= ActivityManager.PROCESS_STATE_HOME) {
20122                 long wtime;
20123                 synchronized (stats) {
20124                     wtime = stats.getProcessWakeTime(app.info.uid,
20125                             app.pid, curRealtime);
20126                 }
20127                 long wtimeUsed = wtime - app.lastWakeTime;
20128                 long cputimeUsed = app.curCpuTime - app.lastCpuTime;
20129                 if (DEBUG_POWER) {
20130                     StringBuilder sb = new StringBuilder(128);
20131                     sb.append("Wake for ");
20132                     app.toShortString(sb);
20133                     sb.append(": over ");
20134                     TimeUtils.formatDuration(realtimeSince, sb);
20135                     sb.append(" used ");
20136                     TimeUtils.formatDuration(wtimeUsed, sb);
20137                     sb.append(" (");
20138                     sb.append((wtimeUsed*100)/realtimeSince);
20139                     sb.append("%)");
20140                     Slog.i(TAG_POWER, sb.toString());
20141                     sb.setLength(0);
20142                     sb.append("CPU for ");
20143                     app.toShortString(sb);
20144                     sb.append(": over ");
20145                     TimeUtils.formatDuration(uptimeSince, sb);
20146                     sb.append(" used ");
20147                     TimeUtils.formatDuration(cputimeUsed, sb);
20148                     sb.append(" (");
20149                     sb.append((cputimeUsed*100)/uptimeSince);
20150                     sb.append("%)");
20151                     Slog.i(TAG_POWER, sb.toString());
20152                 }
20153                 // If a process has held a wake lock for more
20154                 // than 50% of the time during this period,
20155                 // that sounds bad.  Kill!
20156                 if (doWakeKills && realtimeSince > 0
20157                         && ((wtimeUsed*100)/realtimeSince) >= 50) {
20158                     synchronized (stats) {
20159                         stats.reportExcessiveWakeLocked(app.info.uid, app.processName,
20160                                 realtimeSince, wtimeUsed);
20161                     }
20162                     app.kill("excessive wake held " + wtimeUsed + " during " + realtimeSince, true);
20163                     app.baseProcessTracker.reportExcessiveWake(app.pkgList);
20164                 } else if (doCpuKills && uptimeSince > 0
20165                         && ((cputimeUsed*100)/uptimeSince) >= 25) {
20166                     synchronized (stats) {
20167                         stats.reportExcessiveCpuLocked(app.info.uid, app.processName,
20168                                 uptimeSince, cputimeUsed);
20169                     }
20170                     app.kill("excessive cpu " + cputimeUsed + " during " + uptimeSince, true);
20171                     app.baseProcessTracker.reportExcessiveCpu(app.pkgList);
20172                 } else {
20173                     app.lastWakeTime = wtime;
20174                     app.lastCpuTime = app.curCpuTime;
20175                 }
20176             }
20177         }
20178     }
20179
20180     private final boolean applyOomAdjLocked(ProcessRecord app, boolean doingAll, long now,
20181             long nowElapsed) {
20182         boolean success = true;
20183
20184         if (app.curRawAdj != app.setRawAdj) {
20185             app.setRawAdj = app.curRawAdj;
20186         }
20187
20188         int changes = 0;
20189
20190         if (app.curAdj != app.setAdj) {
20191             ProcessList.setOomAdj(app.pid, app.info.uid, app.curAdj);
20192             if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG_OOM_ADJ,
20193                     "Set " + app.pid + " " + app.processName + " adj " + app.curAdj + ": "
20194                     + app.adjType);
20195             app.setAdj = app.curAdj;
20196             app.verifiedAdj = ProcessList.INVALID_ADJ;
20197         }
20198
20199         if (app.setSchedGroup != app.curSchedGroup) {
20200             app.setSchedGroup = app.curSchedGroup;
20201             if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG_OOM_ADJ,
20202                     "Setting sched group of " + app.processName
20203                     + " to " + app.curSchedGroup);
20204             if (app.waitingToKill != null && app.curReceiver == null
20205                     && app.setSchedGroup == ProcessList.SCHED_GROUP_BACKGROUND) {
20206                 app.kill(app.waitingToKill, true);
20207                 success = false;
20208             } else {
20209                 int processGroup;
20210                 switch (app.curSchedGroup) {
20211                     case ProcessList.SCHED_GROUP_BACKGROUND:
20212                         processGroup = Process.THREAD_GROUP_BG_NONINTERACTIVE;
20213                         break;
20214                     case ProcessList.SCHED_GROUP_TOP_APP:
20215                         processGroup = Process.THREAD_GROUP_TOP_APP;
20216                         break;
20217                     default:
20218                         processGroup = Process.THREAD_GROUP_DEFAULT;
20219                         break;
20220                 }
20221                 if (true) {
20222                     long oldId = Binder.clearCallingIdentity();
20223                     try {
20224                         Process.setProcessGroup(app.pid, processGroup);
20225                     } catch (Exception e) {
20226                         Slog.w(TAG, "Failed setting process group of " + app.pid
20227                                 + " to " + app.curSchedGroup);
20228                         e.printStackTrace();
20229                     } finally {
20230                         Binder.restoreCallingIdentity(oldId);
20231                     }
20232                 } else {
20233                     if (app.thread != null) {
20234                         try {
20235                             app.thread.setSchedulingGroup(processGroup);
20236                         } catch (RemoteException e) {
20237                         }
20238                     }
20239                 }
20240             }
20241         }
20242         if (app.repForegroundActivities != app.foregroundActivities) {
20243             app.repForegroundActivities = app.foregroundActivities;
20244             changes |= ProcessChangeItem.CHANGE_ACTIVITIES;
20245         }
20246         if (app.repProcState != app.curProcState) {
20247             app.repProcState = app.curProcState;
20248             changes |= ProcessChangeItem.CHANGE_PROCESS_STATE;
20249             if (app.thread != null) {
20250                 try {
20251                     if (false) {
20252                         //RuntimeException h = new RuntimeException("here");
20253                         Slog.i(TAG, "Sending new process state " + app.repProcState
20254                                 + " to " + app /*, h*/);
20255                     }
20256                     app.thread.setProcessState(app.repProcState);
20257                 } catch (RemoteException e) {
20258                 }
20259             }
20260         }
20261         if (app.setProcState == ActivityManager.PROCESS_STATE_NONEXISTENT
20262                 || ProcessList.procStatesDifferForMem(app.curProcState, app.setProcState)) {
20263             if (false && mTestPssMode && app.setProcState >= 0 && app.lastStateTime <= (now-200)) {
20264                 // Experimental code to more aggressively collect pss while
20265                 // running test...  the problem is that this tends to collect
20266                 // the data right when a process is transitioning between process
20267                 // states, which well tend to give noisy data.
20268                 long start = SystemClock.uptimeMillis();
20269                 long pss = Debug.getPss(app.pid, mTmpLong, null);
20270                 recordPssSampleLocked(app, app.curProcState, pss, mTmpLong[0], mTmpLong[1], now);
20271                 mPendingPssProcesses.remove(app);
20272                 Slog.i(TAG, "Recorded pss for " + app + " state " + app.setProcState
20273                         + " to " + app.curProcState + ": "
20274                         + (SystemClock.uptimeMillis()-start) + "ms");
20275             }
20276             app.lastStateTime = now;
20277             app.nextPssTime = ProcessList.computeNextPssTime(app.curProcState, true,
20278                     mTestPssMode, isSleepingLocked(), now);
20279             if (DEBUG_PSS) Slog.d(TAG_PSS, "Process state change from "
20280                     + ProcessList.makeProcStateString(app.setProcState) + " to "
20281                     + ProcessList.makeProcStateString(app.curProcState) + " next pss in "
20282                     + (app.nextPssTime-now) + ": " + app);
20283         } else {
20284             if (now > app.nextPssTime || (now > (app.lastPssTime+ProcessList.PSS_MAX_INTERVAL)
20285                     && now > (app.lastStateTime+ProcessList.minTimeFromStateChange(
20286                     mTestPssMode)))) {
20287                 requestPssLocked(app, app.setProcState);
20288                 app.nextPssTime = ProcessList.computeNextPssTime(app.curProcState, false,
20289                         mTestPssMode, isSleepingLocked(), now);
20290             } else if (false && DEBUG_PSS) Slog.d(TAG_PSS,
20291                     "Not requesting PSS of " + app + ": next=" + (app.nextPssTime-now));
20292         }
20293         if (app.setProcState != app.curProcState) {
20294             if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG_OOM_ADJ,
20295                     "Proc state change of " + app.processName
20296                             + " to " + app.curProcState);
20297             boolean setImportant = app.setProcState < ActivityManager.PROCESS_STATE_SERVICE;
20298             boolean curImportant = app.curProcState < ActivityManager.PROCESS_STATE_SERVICE;
20299             if (setImportant && !curImportant) {
20300                 // This app is no longer something we consider important enough to allow to
20301                 // use arbitrary amounts of battery power.  Note
20302                 // its current wake lock time to later know to kill it if
20303                 // it is not behaving well.
20304                 BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
20305                 synchronized (stats) {
20306                     app.lastWakeTime = stats.getProcessWakeTime(app.info.uid,
20307                             app.pid, nowElapsed);
20308                 }
20309                 app.lastCpuTime = app.curCpuTime;
20310
20311             }
20312             // Inform UsageStats of important process state change
20313             // Must be called before updating setProcState
20314             maybeUpdateUsageStatsLocked(app, nowElapsed);
20315
20316             app.setProcState = app.curProcState;
20317             if (app.setProcState >= ActivityManager.PROCESS_STATE_HOME) {
20318                 app.notCachedSinceIdle = false;
20319             }
20320             if (!doingAll) {
20321                 setProcessTrackerStateLocked(app, mProcessStats.getMemFactorLocked(), now);
20322             } else {
20323                 app.procStateChanged = true;
20324             }
20325         } else if (app.reportedInteraction && (nowElapsed-app.interactionEventTime)
20326                 > USAGE_STATS_INTERACTION_INTERVAL) {
20327             // For apps that sit around for a long time in the interactive state, we need
20328             // to report this at least once a day so they don't go idle.
20329             maybeUpdateUsageStatsLocked(app, nowElapsed);
20330         }
20331
20332         if (changes != 0) {
20333             if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG_PROCESS_OBSERVERS,
20334                     "Changes in " + app + ": " + changes);
20335             int i = mPendingProcessChanges.size()-1;
20336             ProcessChangeItem item = null;
20337             while (i >= 0) {
20338                 item = mPendingProcessChanges.get(i);
20339                 if (item.pid == app.pid) {
20340                     if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG_PROCESS_OBSERVERS,
20341                             "Re-using existing item: " + item);
20342                     break;
20343                 }
20344                 i--;
20345             }
20346             if (i < 0) {
20347                 // No existing item in pending changes; need a new one.
20348                 final int NA = mAvailProcessChanges.size();
20349                 if (NA > 0) {
20350                     item = mAvailProcessChanges.remove(NA-1);
20351                     if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG_PROCESS_OBSERVERS,
20352                             "Retrieving available item: " + item);
20353                 } else {
20354                     item = new ProcessChangeItem();
20355                     if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG_PROCESS_OBSERVERS,
20356                             "Allocating new item: " + item);
20357                 }
20358                 item.changes = 0;
20359                 item.pid = app.pid;
20360                 item.uid = app.info.uid;
20361                 if (mPendingProcessChanges.size() == 0) {
20362                     if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG_PROCESS_OBSERVERS,
20363                             "*** Enqueueing dispatch processes changed!");
20364                     mUiHandler.obtainMessage(DISPATCH_PROCESSES_CHANGED_UI_MSG).sendToTarget();
20365                 }
20366                 mPendingProcessChanges.add(item);
20367             }
20368             item.changes |= changes;
20369             item.processState = app.repProcState;
20370             item.foregroundActivities = app.repForegroundActivities;
20371             if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG_PROCESS_OBSERVERS,
20372                     "Item " + Integer.toHexString(System.identityHashCode(item))
20373                     + " " + app.toShortString() + ": changes=" + item.changes
20374                     + " procState=" + item.processState
20375                     + " foreground=" + item.foregroundActivities
20376                     + " type=" + app.adjType + " source=" + app.adjSource
20377                     + " target=" + app.adjTarget);
20378         }
20379
20380         return success;
20381     }
20382
20383     private final void enqueueUidChangeLocked(UidRecord uidRec, int uid, int change) {
20384         final UidRecord.ChangeItem pendingChange;
20385         if (uidRec == null || uidRec.pendingChange == null) {
20386             if (mPendingUidChanges.size() == 0) {
20387                 if (DEBUG_UID_OBSERVERS) Slog.i(TAG_UID_OBSERVERS,
20388                         "*** Enqueueing dispatch uid changed!");
20389                 mUiHandler.obtainMessage(DISPATCH_UIDS_CHANGED_UI_MSG).sendToTarget();
20390             }
20391             final int NA = mAvailUidChanges.size();
20392             if (NA > 0) {
20393                 pendingChange = mAvailUidChanges.remove(NA-1);
20394                 if (DEBUG_UID_OBSERVERS) Slog.i(TAG_UID_OBSERVERS,
20395                         "Retrieving available item: " + pendingChange);
20396             } else {
20397                 pendingChange = new UidRecord.ChangeItem();
20398                 if (DEBUG_UID_OBSERVERS) Slog.i(TAG_UID_OBSERVERS,
20399                         "Allocating new item: " + pendingChange);
20400             }
20401             if (uidRec != null) {
20402                 uidRec.pendingChange = pendingChange;
20403                 if (change == UidRecord.CHANGE_GONE && !uidRec.idle) {
20404                     // If this uid is going away, and we haven't yet reported it is gone,
20405                     // then do so now.
20406                     change = UidRecord.CHANGE_GONE_IDLE;
20407                 }
20408             } else if (uid < 0) {
20409                 throw new IllegalArgumentException("No UidRecord or uid");
20410             }
20411             pendingChange.uidRecord = uidRec;
20412             pendingChange.uid = uidRec != null ? uidRec.uid : uid;
20413             mPendingUidChanges.add(pendingChange);
20414         } else {
20415             pendingChange = uidRec.pendingChange;
20416             if (change == UidRecord.CHANGE_GONE && pendingChange.change == UidRecord.CHANGE_IDLE) {
20417                 change = UidRecord.CHANGE_GONE_IDLE;
20418             }
20419         }
20420         pendingChange.change = change;
20421         pendingChange.processState = uidRec != null
20422                 ? uidRec.setProcState : ActivityManager.PROCESS_STATE_NONEXISTENT;
20423     }
20424
20425     private void maybeUpdateProviderUsageStatsLocked(ProcessRecord app, String providerPkgName,
20426             String authority) {
20427         if (app == null) return;
20428         if (app.curProcState <= ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND) {
20429             UserState userState = mUserController.getStartedUserStateLocked(app.userId);
20430             if (userState == null) return;
20431             final long now = SystemClock.elapsedRealtime();
20432             Long lastReported = userState.mProviderLastReportedFg.get(authority);
20433             if (lastReported == null || lastReported < now - 60 * 1000L) {
20434                 mUsageStatsService.reportContentProviderUsage(
20435                         authority, providerPkgName, app.userId);
20436                 userState.mProviderLastReportedFg.put(authority, now);
20437             }
20438         }
20439     }
20440
20441     private void maybeUpdateUsageStatsLocked(ProcessRecord app, long nowElapsed) {
20442         if (DEBUG_USAGE_STATS) {
20443             Slog.d(TAG, "Checking proc [" + Arrays.toString(app.getPackageList())
20444                     + "] state changes: old = " + app.setProcState + ", new = "
20445                     + app.curProcState);
20446         }
20447         if (mUsageStatsService == null) {
20448             return;
20449         }
20450         boolean isInteraction;
20451         // To avoid some abuse patterns, we are going to be careful about what we consider
20452         // to be an app interaction.  Being the top activity doesn't count while the display
20453         // is sleeping, nor do short foreground services.
20454         if (app.curProcState <= ActivityManager.PROCESS_STATE_BOUND_FOREGROUND_SERVICE) {
20455             isInteraction = true;
20456             app.fgInteractionTime = 0;
20457         } else if (app.curProcState <= ActivityManager.PROCESS_STATE_TOP_SLEEPING) {
20458             if (app.fgInteractionTime == 0) {
20459                 app.fgInteractionTime = nowElapsed;
20460                 isInteraction = false;
20461             } else {
20462                 isInteraction = nowElapsed > app.fgInteractionTime + SERVICE_USAGE_INTERACTION_TIME;
20463             }
20464         } else {
20465             isInteraction = app.curProcState
20466                     <= ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND;
20467             app.fgInteractionTime = 0;
20468         }
20469         if (isInteraction && (!app.reportedInteraction
20470                 || (nowElapsed-app.interactionEventTime) > USAGE_STATS_INTERACTION_INTERVAL)) {
20471             app.interactionEventTime = nowElapsed;
20472             String[] packages = app.getPackageList();
20473             if (packages != null) {
20474                 for (int i = 0; i < packages.length; i++) {
20475                     mUsageStatsService.reportEvent(packages[i], app.userId,
20476                             UsageEvents.Event.SYSTEM_INTERACTION);
20477                 }
20478             }
20479         }
20480         app.reportedInteraction = isInteraction;
20481         if (!isInteraction) {
20482             app.interactionEventTime = 0;
20483         }
20484     }
20485
20486     private final void setProcessTrackerStateLocked(ProcessRecord proc, int memFactor, long now) {
20487         if (proc.thread != null) {
20488             if (proc.baseProcessTracker != null) {
20489                 proc.baseProcessTracker.setState(proc.repProcState, memFactor, now, proc.pkgList);
20490             }
20491         }
20492     }
20493
20494     private final boolean updateOomAdjLocked(ProcessRecord app, int cachedAdj,
20495             ProcessRecord TOP_APP, boolean doingAll, long now) {
20496         if (app.thread == null) {
20497             return false;
20498         }
20499
20500         computeOomAdjLocked(app, cachedAdj, TOP_APP, doingAll, now);
20501
20502         return applyOomAdjLocked(app, doingAll, now, SystemClock.elapsedRealtime());
20503     }
20504
20505     final void updateProcessForegroundLocked(ProcessRecord proc, boolean isForeground,
20506             boolean oomAdj) {
20507         if (isForeground != proc.foregroundServices) {
20508             proc.foregroundServices = isForeground;
20509             ArrayList<ProcessRecord> curProcs = mForegroundPackages.get(proc.info.packageName,
20510                     proc.info.uid);
20511             if (isForeground) {
20512                 if (curProcs == null) {
20513                     curProcs = new ArrayList<ProcessRecord>();
20514                     mForegroundPackages.put(proc.info.packageName, proc.info.uid, curProcs);
20515                 }
20516                 if (!curProcs.contains(proc)) {
20517                     curProcs.add(proc);
20518                     mBatteryStatsService.noteEvent(BatteryStats.HistoryItem.EVENT_FOREGROUND_START,
20519                             proc.info.packageName, proc.info.uid);
20520                 }
20521             } else {
20522                 if (curProcs != null) {
20523                     if (curProcs.remove(proc)) {
20524                         mBatteryStatsService.noteEvent(
20525                                 BatteryStats.HistoryItem.EVENT_FOREGROUND_FINISH,
20526                                 proc.info.packageName, proc.info.uid);
20527                         if (curProcs.size() <= 0) {
20528                             mForegroundPackages.remove(proc.info.packageName, proc.info.uid);
20529                         }
20530                     }
20531                 }
20532             }
20533             if (oomAdj) {
20534                 updateOomAdjLocked();
20535             }
20536         }
20537     }
20538
20539     private final ActivityRecord resumedAppLocked() {
20540         ActivityRecord act = mStackSupervisor.resumedAppLocked();
20541         String pkg;
20542         int uid;
20543         if (act != null) {
20544             pkg = act.packageName;
20545             uid = act.info.applicationInfo.uid;
20546         } else {
20547             pkg = null;
20548             uid = -1;
20549         }
20550         // Has the UID or resumed package name changed?
20551         if (uid != mCurResumedUid || (pkg != mCurResumedPackage
20552                 && (pkg == null || !pkg.equals(mCurResumedPackage)))) {
20553             if (mCurResumedPackage != null) {
20554                 mBatteryStatsService.noteEvent(BatteryStats.HistoryItem.EVENT_TOP_FINISH,
20555                         mCurResumedPackage, mCurResumedUid);
20556             }
20557             mCurResumedPackage = pkg;
20558             mCurResumedUid = uid;
20559             if (mCurResumedPackage != null) {
20560                 mBatteryStatsService.noteEvent(BatteryStats.HistoryItem.EVENT_TOP_START,
20561                         mCurResumedPackage, mCurResumedUid);
20562             }
20563         }
20564         return act;
20565     }
20566
20567     final boolean updateOomAdjLocked(ProcessRecord app) {
20568         final ActivityRecord TOP_ACT = resumedAppLocked();
20569         final ProcessRecord TOP_APP = TOP_ACT != null ? TOP_ACT.app : null;
20570         final boolean wasCached = app.cached;
20571
20572         mAdjSeq++;
20573
20574         // This is the desired cached adjusment we want to tell it to use.
20575         // If our app is currently cached, we know it, and that is it.  Otherwise,
20576         // we don't know it yet, and it needs to now be cached we will then
20577         // need to do a complete oom adj.
20578         final int cachedAdj = app.curRawAdj >= ProcessList.CACHED_APP_MIN_ADJ
20579                 ? app.curRawAdj : ProcessList.UNKNOWN_ADJ;
20580         boolean success = updateOomAdjLocked(app, cachedAdj, TOP_APP, false,
20581                 SystemClock.uptimeMillis());
20582         if (wasCached != app.cached || app.curRawAdj == ProcessList.UNKNOWN_ADJ) {
20583             // Changed to/from cached state, so apps after it in the LRU
20584             // list may also be changed.
20585             updateOomAdjLocked();
20586         }
20587         return success;
20588     }
20589
20590     final void updateOomAdjLocked() {
20591         final ActivityRecord TOP_ACT = resumedAppLocked();
20592         final ProcessRecord TOP_APP = TOP_ACT != null ? TOP_ACT.app : null;
20593         final long now = SystemClock.uptimeMillis();
20594         final long nowElapsed = SystemClock.elapsedRealtime();
20595         final long oldTime = now - ProcessList.MAX_EMPTY_TIME;
20596         final int N = mLruProcesses.size();
20597
20598         if (false) {
20599             RuntimeException e = new RuntimeException();
20600             e.fillInStackTrace();
20601             Slog.i(TAG, "updateOomAdj: top=" + TOP_ACT, e);
20602         }
20603
20604         // Reset state in all uid records.
20605         for (int i=mActiveUids.size()-1; i>=0; i--) {
20606             final UidRecord uidRec = mActiveUids.valueAt(i);
20607             if (false && DEBUG_UID_OBSERVERS) Slog.i(TAG_UID_OBSERVERS,
20608                     "Starting update of " + uidRec);
20609             uidRec.reset();
20610         }
20611
20612         mStackSupervisor.rankTaskLayersIfNeeded();
20613
20614         mAdjSeq++;
20615         mNewNumServiceProcs = 0;
20616         mNewNumAServiceProcs = 0;
20617
20618         final int emptyProcessLimit;
20619         final int cachedProcessLimit;
20620         if (mProcessLimit <= 0) {
20621             emptyProcessLimit = cachedProcessLimit = 0;
20622         } else if (mProcessLimit == 1) {
20623             emptyProcessLimit = 1;
20624             cachedProcessLimit = 0;
20625         } else {
20626             emptyProcessLimit = ProcessList.computeEmptyProcessLimit(mProcessLimit);
20627             cachedProcessLimit = mProcessLimit - emptyProcessLimit;
20628         }
20629
20630         // Let's determine how many processes we have running vs.
20631         // how many slots we have for background processes; we may want
20632         // to put multiple processes in a slot of there are enough of
20633         // them.
20634         int numSlots = (ProcessList.CACHED_APP_MAX_ADJ
20635                 - ProcessList.CACHED_APP_MIN_ADJ + 1) / 2;
20636         int numEmptyProcs = N - mNumNonCachedProcs - mNumCachedHiddenProcs;
20637         if (numEmptyProcs > cachedProcessLimit) {
20638             // If there are more empty processes than our limit on cached
20639             // processes, then use the cached process limit for the factor.
20640             // This ensures that the really old empty processes get pushed
20641             // down to the bottom, so if we are running low on memory we will
20642             // have a better chance at keeping around more cached processes
20643             // instead of a gazillion empty processes.
20644             numEmptyProcs = cachedProcessLimit;
20645         }
20646         int emptyFactor = numEmptyProcs/numSlots;
20647         if (emptyFactor < 1) emptyFactor = 1;
20648         int cachedFactor = (mNumCachedHiddenProcs > 0 ? mNumCachedHiddenProcs : 1)/numSlots;
20649         if (cachedFactor < 1) cachedFactor = 1;
20650         int stepCached = 0;
20651         int stepEmpty = 0;
20652         int numCached = 0;
20653         int numEmpty = 0;
20654         int numTrimming = 0;
20655
20656         mNumNonCachedProcs = 0;
20657         mNumCachedHiddenProcs = 0;
20658
20659         // First update the OOM adjustment for each of the
20660         // application processes based on their current state.
20661         int curCachedAdj = ProcessList.CACHED_APP_MIN_ADJ;
20662         int nextCachedAdj = curCachedAdj+1;
20663         int curEmptyAdj = ProcessList.CACHED_APP_MIN_ADJ;
20664         int nextEmptyAdj = curEmptyAdj+2;
20665         for (int i=N-1; i>=0; i--) {
20666             ProcessRecord app = mLruProcesses.get(i);
20667             if (!app.killedByAm && app.thread != null) {
20668                 app.procStateChanged = false;
20669                 computeOomAdjLocked(app, ProcessList.UNKNOWN_ADJ, TOP_APP, true, now);
20670
20671                 // If we haven't yet assigned the final cached adj
20672                 // to the process, do that now.
20673                 if (app.curAdj >= ProcessList.UNKNOWN_ADJ) {
20674                     switch (app.curProcState) {
20675                         case ActivityManager.PROCESS_STATE_CACHED_ACTIVITY:
20676                         case ActivityManager.PROCESS_STATE_CACHED_ACTIVITY_CLIENT:
20677                             // This process is a cached process holding activities...
20678                             // assign it the next cached value for that type, and then
20679                             // step that cached level.
20680                             app.curRawAdj = curCachedAdj;
20681                             app.curAdj = app.modifyRawOomAdj(curCachedAdj);
20682                             if (DEBUG_LRU && false) Slog.d(TAG_LRU, "Assigning activity LRU #" + i
20683                                     + " adj: " + app.curAdj + " (curCachedAdj=" + curCachedAdj
20684                                     + ")");
20685                             if (curCachedAdj != nextCachedAdj) {
20686                                 stepCached++;
20687                                 if (stepCached >= cachedFactor) {
20688                                     stepCached = 0;
20689                                     curCachedAdj = nextCachedAdj;
20690                                     nextCachedAdj += 2;
20691                                     if (nextCachedAdj > ProcessList.CACHED_APP_MAX_ADJ) {
20692                                         nextCachedAdj = ProcessList.CACHED_APP_MAX_ADJ;
20693                                     }
20694                                 }
20695                             }
20696                             break;
20697                         default:
20698                             // For everything else, assign next empty cached process
20699                             // level and bump that up.  Note that this means that
20700                             // long-running services that have dropped down to the
20701                             // cached level will be treated as empty (since their process
20702                             // state is still as a service), which is what we want.
20703                             app.curRawAdj = curEmptyAdj;
20704                             app.curAdj = app.modifyRawOomAdj(curEmptyAdj);
20705                             if (DEBUG_LRU && false) Slog.d(TAG_LRU, "Assigning empty LRU #" + i
20706                                     + " adj: " + app.curAdj + " (curEmptyAdj=" + curEmptyAdj
20707                                     + ")");
20708                             if (curEmptyAdj != nextEmptyAdj) {
20709                                 stepEmpty++;
20710                                 if (stepEmpty >= emptyFactor) {
20711                                     stepEmpty = 0;
20712                                     curEmptyAdj = nextEmptyAdj;
20713                                     nextEmptyAdj += 2;
20714                                     if (nextEmptyAdj > ProcessList.CACHED_APP_MAX_ADJ) {
20715                                         nextEmptyAdj = ProcessList.CACHED_APP_MAX_ADJ;
20716                                     }
20717                                 }
20718                             }
20719                             break;
20720                     }
20721                 }
20722
20723                 applyOomAdjLocked(app, true, now, nowElapsed);
20724
20725                 // Count the number of process types.
20726                 switch (app.curProcState) {
20727                     case ActivityManager.PROCESS_STATE_CACHED_ACTIVITY:
20728                     case ActivityManager.PROCESS_STATE_CACHED_ACTIVITY_CLIENT:
20729                         mNumCachedHiddenProcs++;
20730                         numCached++;
20731                         if (numCached > cachedProcessLimit) {
20732                             app.kill("cached #" + numCached, true);
20733                         }
20734                         break;
20735                     case ActivityManager.PROCESS_STATE_CACHED_EMPTY:
20736                         if (numEmpty > ProcessList.TRIM_EMPTY_APPS
20737                                 && app.lastActivityTime < oldTime) {
20738                             app.kill("empty for "
20739                                     + ((oldTime + ProcessList.MAX_EMPTY_TIME - app.lastActivityTime)
20740                                     / 1000) + "s", true);
20741                         } else {
20742                             numEmpty++;
20743                             if (numEmpty > emptyProcessLimit) {
20744                                 app.kill("empty #" + numEmpty, true);
20745                             }
20746                         }
20747                         break;
20748                     default:
20749                         mNumNonCachedProcs++;
20750                         break;
20751                 }
20752
20753                 if (app.isolated && app.services.size() <= 0) {
20754                     // If this is an isolated process, and there are no
20755                     // services running in it, then the process is no longer
20756                     // needed.  We agressively kill these because we can by
20757                     // definition not re-use the same process again, and it is
20758                     // good to avoid having whatever code was running in them
20759                     // left sitting around after no longer needed.
20760                     app.kill("isolated not needed", true);
20761                 } else {
20762                     // Keeping this process, update its uid.
20763                     final UidRecord uidRec = app.uidRecord;
20764                     if (uidRec != null && uidRec.curProcState > app.curProcState) {
20765                         uidRec.curProcState = app.curProcState;
20766                     }
20767                 }
20768
20769                 if (app.curProcState >= ActivityManager.PROCESS_STATE_HOME
20770                         && !app.killedByAm) {
20771                     numTrimming++;
20772                 }
20773             }
20774         }
20775
20776         mNumServiceProcs = mNewNumServiceProcs;
20777
20778         // Now determine the memory trimming level of background processes.
20779         // Unfortunately we need to start at the back of the list to do this
20780         // properly.  We only do this if the number of background apps we
20781         // are managing to keep around is less than half the maximum we desire;
20782         // if we are keeping a good number around, we'll let them use whatever
20783         // memory they want.
20784         final int numCachedAndEmpty = numCached + numEmpty;
20785         int memFactor;
20786         if (numCached <= ProcessList.TRIM_CACHED_APPS
20787                 && numEmpty <= ProcessList.TRIM_EMPTY_APPS) {
20788             if (numCachedAndEmpty <= ProcessList.TRIM_CRITICAL_THRESHOLD) {
20789                 memFactor = ProcessStats.ADJ_MEM_FACTOR_CRITICAL;
20790             } else if (numCachedAndEmpty <= ProcessList.TRIM_LOW_THRESHOLD) {
20791                 memFactor = ProcessStats.ADJ_MEM_FACTOR_LOW;
20792             } else {
20793                 memFactor = ProcessStats.ADJ_MEM_FACTOR_MODERATE;
20794             }
20795         } else {
20796             memFactor = ProcessStats.ADJ_MEM_FACTOR_NORMAL;
20797         }
20798         // We always allow the memory level to go up (better).  We only allow it to go
20799         // down if we are in a state where that is allowed, *and* the total number of processes
20800         // has gone down since last time.
20801         if (DEBUG_OOM_ADJ) Slog.d(TAG_OOM_ADJ, "oom: memFactor=" + memFactor
20802                 + " last=" + mLastMemoryLevel + " allowLow=" + mAllowLowerMemLevel
20803                 + " numProcs=" + mLruProcesses.size() + " last=" + mLastNumProcesses);
20804         if (memFactor > mLastMemoryLevel) {
20805             if (!mAllowLowerMemLevel || mLruProcesses.size() >= mLastNumProcesses) {
20806                 memFactor = mLastMemoryLevel;
20807                 if (DEBUG_OOM_ADJ) Slog.d(TAG_OOM_ADJ, "Keeping last mem factor!");
20808             }
20809         }
20810         if (memFactor != mLastMemoryLevel) {
20811             EventLogTags.writeAmMemFactor(memFactor, mLastMemoryLevel);
20812         }
20813         mLastMemoryLevel = memFactor;
20814         mLastNumProcesses = mLruProcesses.size();
20815         boolean allChanged = mProcessStats.setMemFactorLocked(memFactor, !isSleepingLocked(), now);
20816         final int trackerMemFactor = mProcessStats.getMemFactorLocked();
20817         if (memFactor != ProcessStats.ADJ_MEM_FACTOR_NORMAL) {
20818             if (mLowRamStartTime == 0) {
20819                 mLowRamStartTime = now;
20820             }
20821             int step = 0;
20822             int fgTrimLevel;
20823             switch (memFactor) {
20824                 case ProcessStats.ADJ_MEM_FACTOR_CRITICAL:
20825                     fgTrimLevel = ComponentCallbacks2.TRIM_MEMORY_RUNNING_CRITICAL;
20826                     break;
20827                 case ProcessStats.ADJ_MEM_FACTOR_LOW:
20828                     fgTrimLevel = ComponentCallbacks2.TRIM_MEMORY_RUNNING_LOW;
20829                     break;
20830                 default:
20831                     fgTrimLevel = ComponentCallbacks2.TRIM_MEMORY_RUNNING_MODERATE;
20832                     break;
20833             }
20834             int factor = numTrimming/3;
20835             int minFactor = 2;
20836             if (mHomeProcess != null) minFactor++;
20837             if (mPreviousProcess != null) minFactor++;
20838             if (factor < minFactor) factor = minFactor;
20839             int curLevel = ComponentCallbacks2.TRIM_MEMORY_COMPLETE;
20840             for (int i=N-1; i>=0; i--) {
20841                 ProcessRecord app = mLruProcesses.get(i);
20842                 if (allChanged || app.procStateChanged) {
20843                     setProcessTrackerStateLocked(app, trackerMemFactor, now);
20844                     app.procStateChanged = false;
20845                 }
20846                 if (app.curProcState >= ActivityManager.PROCESS_STATE_HOME
20847                         && !app.killedByAm) {
20848                     if (app.trimMemoryLevel < curLevel && app.thread != null) {
20849                         try {
20850                             if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG_OOM_ADJ,
20851                                     "Trimming memory of " + app.processName + " to " + curLevel);
20852                             app.thread.scheduleTrimMemory(curLevel);
20853                         } catch (RemoteException e) {
20854                         }
20855                         if (false) {
20856                             // For now we won't do this; our memory trimming seems
20857                             // to be good enough at this point that destroying
20858                             // activities causes more harm than good.
20859                             if (curLevel >= ComponentCallbacks2.TRIM_MEMORY_COMPLETE
20860                                     && app != mHomeProcess && app != mPreviousProcess) {
20861                                 // Need to do this on its own message because the stack may not
20862                                 // be in a consistent state at this point.
20863                                 // For these apps we will also finish their activities
20864                                 // to help them free memory.
20865                                 mStackSupervisor.scheduleDestroyAllActivities(app, "trim");
20866                             }
20867                         }
20868                     }
20869                     app.trimMemoryLevel = curLevel;
20870                     step++;
20871                     if (step >= factor) {
20872                         step = 0;
20873                         switch (curLevel) {
20874                             case ComponentCallbacks2.TRIM_MEMORY_COMPLETE:
20875                                 curLevel = ComponentCallbacks2.TRIM_MEMORY_MODERATE;
20876                                 break;
20877                             case ComponentCallbacks2.TRIM_MEMORY_MODERATE:
20878                                 curLevel = ComponentCallbacks2.TRIM_MEMORY_BACKGROUND;
20879                                 break;
20880                         }
20881                     }
20882                 } else if (app.curProcState == ActivityManager.PROCESS_STATE_HEAVY_WEIGHT) {
20883                     if (app.trimMemoryLevel < ComponentCallbacks2.TRIM_MEMORY_BACKGROUND
20884                             && app.thread != null) {
20885                         try {
20886                             if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG_OOM_ADJ,
20887                                     "Trimming memory of heavy-weight " + app.processName
20888                                     + " to " + ComponentCallbacks2.TRIM_MEMORY_BACKGROUND);
20889                             app.thread.scheduleTrimMemory(
20890                                     ComponentCallbacks2.TRIM_MEMORY_BACKGROUND);
20891                         } catch (RemoteException e) {
20892                         }
20893                     }
20894                     app.trimMemoryLevel = ComponentCallbacks2.TRIM_MEMORY_BACKGROUND;
20895                 } else {
20896                     if ((app.curProcState >= ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND
20897                             || app.systemNoUi) && app.pendingUiClean) {
20898                         // If this application is now in the background and it
20899                         // had done UI, then give it the special trim level to
20900                         // have it free UI resources.
20901                         final int level = ComponentCallbacks2.TRIM_MEMORY_UI_HIDDEN;
20902                         if (app.trimMemoryLevel < level && app.thread != null) {
20903                             try {
20904                                 if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG_OOM_ADJ,
20905                                         "Trimming memory of bg-ui " + app.processName
20906                                         + " to " + level);
20907                                 app.thread.scheduleTrimMemory(level);
20908                             } catch (RemoteException e) {
20909                             }
20910                         }
20911                         app.pendingUiClean = false;
20912                     }
20913                     if (app.trimMemoryLevel < fgTrimLevel && app.thread != null) {
20914                         try {
20915                             if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG_OOM_ADJ,
20916                                     "Trimming memory of fg " + app.processName
20917                                     + " to " + fgTrimLevel);
20918                             app.thread.scheduleTrimMemory(fgTrimLevel);
20919                         } catch (RemoteException e) {
20920                         }
20921                     }
20922                     app.trimMemoryLevel = fgTrimLevel;
20923                 }
20924             }
20925         } else {
20926             if (mLowRamStartTime != 0) {
20927                 mLowRamTimeSinceLastIdle += now - mLowRamStartTime;
20928                 mLowRamStartTime = 0;
20929             }
20930             for (int i=N-1; i>=0; i--) {
20931                 ProcessRecord app = mLruProcesses.get(i);
20932                 if (allChanged || app.procStateChanged) {
20933                     setProcessTrackerStateLocked(app, trackerMemFactor, now);
20934                     app.procStateChanged = false;
20935                 }
20936                 if ((app.curProcState >= ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND
20937                         || app.systemNoUi) && app.pendingUiClean) {
20938                     if (app.trimMemoryLevel < ComponentCallbacks2.TRIM_MEMORY_UI_HIDDEN
20939                             && app.thread != null) {
20940                         try {
20941                             if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG_OOM_ADJ,
20942                                     "Trimming memory of ui hidden " + app.processName
20943                                     + " to " + ComponentCallbacks2.TRIM_MEMORY_UI_HIDDEN);
20944                             app.thread.scheduleTrimMemory(
20945                                     ComponentCallbacks2.TRIM_MEMORY_UI_HIDDEN);
20946                         } catch (RemoteException e) {
20947                         }
20948                     }
20949                     app.pendingUiClean = false;
20950                 }
20951                 app.trimMemoryLevel = 0;
20952             }
20953         }
20954
20955         if (mAlwaysFinishActivities) {
20956             // Need to do this on its own message because the stack may not
20957             // be in a consistent state at this point.
20958             mStackSupervisor.scheduleDestroyAllActivities(null, "always-finish");
20959         }
20960
20961         if (allChanged) {
20962             requestPssAllProcsLocked(now, false, mProcessStats.isMemFactorLowered());
20963         }
20964
20965         // Update from any uid changes.
20966         for (int i=mActiveUids.size()-1; i>=0; i--) {
20967             final UidRecord uidRec = mActiveUids.valueAt(i);
20968             int uidChange = UidRecord.CHANGE_PROCSTATE;
20969             if (uidRec.setProcState != uidRec.curProcState) {
20970                 if (DEBUG_UID_OBSERVERS) Slog.i(TAG_UID_OBSERVERS,
20971                         "Changes in " + uidRec + ": proc state from " + uidRec.setProcState
20972                         + " to " + uidRec.curProcState);
20973                 if (ActivityManager.isProcStateBackground(uidRec.curProcState)) {
20974                     if (!ActivityManager.isProcStateBackground(uidRec.setProcState)) {
20975                         uidRec.lastBackgroundTime = nowElapsed;
20976                         if (!mHandler.hasMessages(IDLE_UIDS_MSG)) {
20977                             // Note: the background settle time is in elapsed realtime, while
20978                             // the handler time base is uptime.  All this means is that we may
20979                             // stop background uids later than we had intended, but that only
20980                             // happens because the device was sleeping so we are okay anyway.
20981                             mHandler.sendEmptyMessageDelayed(IDLE_UIDS_MSG, BACKGROUND_SETTLE_TIME);
20982                         }
20983                     }
20984                 } else {
20985                     if (uidRec.idle) {
20986                         uidChange = UidRecord.CHANGE_ACTIVE;
20987                         uidRec.idle = false;
20988                     }
20989                     uidRec.lastBackgroundTime = 0;
20990                 }
20991                 uidRec.setProcState = uidRec.curProcState;
20992                 enqueueUidChangeLocked(uidRec, -1, uidChange);
20993                 noteUidProcessState(uidRec.uid, uidRec.curProcState);
20994             }
20995         }
20996
20997         if (mProcessStats.shouldWriteNowLocked(now)) {
20998             mHandler.post(new Runnable() {
20999                 @Override public void run() {
21000                     synchronized (ActivityManagerService.this) {
21001                         mProcessStats.writeStateAsyncLocked();
21002                     }
21003                 }
21004             });
21005         }
21006
21007         if (DEBUG_OOM_ADJ) {
21008             final long duration = SystemClock.uptimeMillis() - now;
21009             if (false) {
21010                 Slog.d(TAG_OOM_ADJ, "Did OOM ADJ in " + duration + "ms",
21011                         new RuntimeException("here").fillInStackTrace());
21012             } else {
21013                 Slog.d(TAG_OOM_ADJ, "Did OOM ADJ in " + duration + "ms");
21014             }
21015         }
21016     }
21017
21018     final void idleUids() {
21019         synchronized (this) {
21020             final long nowElapsed = SystemClock.elapsedRealtime();
21021             final long maxBgTime = nowElapsed - BACKGROUND_SETTLE_TIME;
21022             long nextTime = 0;
21023             for (int i=mActiveUids.size()-1; i>=0; i--) {
21024                 final UidRecord uidRec = mActiveUids.valueAt(i);
21025                 final long bgTime = uidRec.lastBackgroundTime;
21026                 if (bgTime > 0 && !uidRec.idle) {
21027                     if (bgTime <= maxBgTime) {
21028                         uidRec.idle = true;
21029                         doStopUidLocked(uidRec.uid, uidRec);
21030                     } else {
21031                         if (nextTime == 0 || nextTime > bgTime) {
21032                             nextTime = bgTime;
21033                         }
21034                     }
21035                 }
21036             }
21037             if (nextTime > 0) {
21038                 mHandler.removeMessages(IDLE_UIDS_MSG);
21039                 mHandler.sendEmptyMessageDelayed(IDLE_UIDS_MSG,
21040                         nextTime + BACKGROUND_SETTLE_TIME - nowElapsed);
21041             }
21042         }
21043     }
21044
21045     final void runInBackgroundDisabled(int uid) {
21046         synchronized (this) {
21047             UidRecord uidRec = mActiveUids.get(uid);
21048             if (uidRec != null) {
21049                 // This uid is actually running...  should it be considered background now?
21050                 if (uidRec.idle) {
21051                     doStopUidLocked(uidRec.uid, uidRec);
21052                 }
21053             } else {
21054                 // This uid isn't actually running...  still send a report about it being "stopped".
21055                 doStopUidLocked(uid, null);
21056             }
21057         }
21058     }
21059
21060     final void doStopUidLocked(int uid, final UidRecord uidRec) {
21061         mServices.stopInBackgroundLocked(uid);
21062         enqueueUidChangeLocked(uidRec, uid, UidRecord.CHANGE_IDLE);
21063     }
21064
21065     final void trimApplications() {
21066         synchronized (this) {
21067             int i;
21068
21069             // First remove any unused application processes whose package
21070             // has been removed.
21071             for (i=mRemovedProcesses.size()-1; i>=0; i--) {
21072                 final ProcessRecord app = mRemovedProcesses.get(i);
21073                 if (app.activities.size() == 0
21074                         && app.curReceiver == null && app.services.size() == 0) {
21075                     Slog.i(
21076                         TAG, "Exiting empty application process "
21077                         + app.toShortString() + " ("
21078                         + (app.thread != null ? app.thread.asBinder() : null)
21079                         + ")\n");
21080                     if (app.pid > 0 && app.pid != MY_PID) {
21081                         app.kill("empty", false);
21082                     } else {
21083                         try {
21084                             app.thread.scheduleExit();
21085                         } catch (Exception e) {
21086                             // Ignore exceptions.
21087                         }
21088                     }
21089                     cleanUpApplicationRecordLocked(app, false, true, -1, false /*replacingPid*/);
21090                     mRemovedProcesses.remove(i);
21091
21092                     if (app.persistent) {
21093                         addAppLocked(app.info, false, null /* ABI override */);
21094                     }
21095                 }
21096             }
21097
21098             // Now update the oom adj for all processes.
21099             updateOomAdjLocked();
21100         }
21101     }
21102
21103     /** This method sends the specified signal to each of the persistent apps */
21104     public void signalPersistentProcesses(int sig) throws RemoteException {
21105         if (sig != Process.SIGNAL_USR1) {
21106             throw new SecurityException("Only SIGNAL_USR1 is allowed");
21107         }
21108
21109         synchronized (this) {
21110             if (checkCallingPermission(android.Manifest.permission.SIGNAL_PERSISTENT_PROCESSES)
21111                     != PackageManager.PERMISSION_GRANTED) {
21112                 throw new SecurityException("Requires permission "
21113                         + android.Manifest.permission.SIGNAL_PERSISTENT_PROCESSES);
21114             }
21115
21116             for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) {
21117                 ProcessRecord r = mLruProcesses.get(i);
21118                 if (r.thread != null && r.persistent) {
21119                     Process.sendSignal(r.pid, sig);
21120                 }
21121             }
21122         }
21123     }
21124
21125     private void stopProfilerLocked(ProcessRecord proc, int profileType) {
21126         if (proc == null || proc == mProfileProc) {
21127             proc = mProfileProc;
21128             profileType = mProfileType;
21129             clearProfilerLocked();
21130         }
21131         if (proc == null) {
21132             return;
21133         }
21134         try {
21135             proc.thread.profilerControl(false, null, profileType);
21136         } catch (RemoteException e) {
21137             throw new IllegalStateException("Process disappeared");
21138         }
21139     }
21140
21141     private void clearProfilerLocked() {
21142         if (mProfileFd != null) {
21143             try {
21144                 mProfileFd.close();
21145             } catch (IOException e) {
21146             }
21147         }
21148         mProfileApp = null;
21149         mProfileProc = null;
21150         mProfileFile = null;
21151         mProfileType = 0;
21152         mAutoStopProfiler = false;
21153         mSamplingInterval = 0;
21154     }
21155
21156     public boolean profileControl(String process, int userId, boolean start,
21157             ProfilerInfo profilerInfo, int profileType) throws RemoteException {
21158
21159         try {
21160             synchronized (this) {
21161                 // note: hijacking SET_ACTIVITY_WATCHER, but should be changed to
21162                 // its own permission.
21163                 if (checkCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER)
21164                         != PackageManager.PERMISSION_GRANTED) {
21165                     throw new SecurityException("Requires permission "
21166                             + android.Manifest.permission.SET_ACTIVITY_WATCHER);
21167                 }
21168
21169                 if (start && (profilerInfo == null || profilerInfo.profileFd == null)) {
21170                     throw new IllegalArgumentException("null profile info or fd");
21171                 }
21172
21173                 ProcessRecord proc = null;
21174                 if (process != null) {
21175                     proc = findProcessLocked(process, userId, "profileControl");
21176                 }
21177
21178                 if (start && (proc == null || proc.thread == null)) {
21179                     throw new IllegalArgumentException("Unknown process: " + process);
21180                 }
21181
21182                 if (start) {
21183                     stopProfilerLocked(null, 0);
21184                     setProfileApp(proc.info, proc.processName, profilerInfo);
21185                     mProfileProc = proc;
21186                     mProfileType = profileType;
21187                     ParcelFileDescriptor fd = profilerInfo.profileFd;
21188                     try {
21189                         fd = fd.dup();
21190                     } catch (IOException e) {
21191                         fd = null;
21192                     }
21193                     profilerInfo.profileFd = fd;
21194                     proc.thread.profilerControl(start, profilerInfo, profileType);
21195                     fd = null;
21196                     mProfileFd = null;
21197                 } else {
21198                     stopProfilerLocked(proc, profileType);
21199                     if (profilerInfo != null && profilerInfo.profileFd != null) {
21200                         try {
21201                             profilerInfo.profileFd.close();
21202                         } catch (IOException e) {
21203                         }
21204                     }
21205                 }
21206
21207                 return true;
21208             }
21209         } catch (RemoteException e) {
21210             throw new IllegalStateException("Process disappeared");
21211         } finally {
21212             if (profilerInfo != null && profilerInfo.profileFd != null) {
21213                 try {
21214                     profilerInfo.profileFd.close();
21215                 } catch (IOException e) {
21216                 }
21217             }
21218         }
21219     }
21220
21221     private ProcessRecord findProcessLocked(String process, int userId, String callName) {
21222         userId = mUserController.handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(),
21223                 userId, true, ALLOW_FULL_ONLY, callName, null);
21224         ProcessRecord proc = null;
21225         try {
21226             int pid = Integer.parseInt(process);
21227             synchronized (mPidsSelfLocked) {
21228                 proc = mPidsSelfLocked.get(pid);
21229             }
21230         } catch (NumberFormatException e) {
21231         }
21232
21233         if (proc == null) {
21234             ArrayMap<String, SparseArray<ProcessRecord>> all
21235                     = mProcessNames.getMap();
21236             SparseArray<ProcessRecord> procs = all.get(process);
21237             if (procs != null && procs.size() > 0) {
21238                 proc = procs.valueAt(0);
21239                 if (userId != UserHandle.USER_ALL && proc.userId != userId) {
21240                     for (int i=1; i<procs.size(); i++) {
21241                         ProcessRecord thisProc = procs.valueAt(i);
21242                         if (thisProc.userId == userId) {
21243                             proc = thisProc;
21244                             break;
21245                         }
21246                     }
21247                 }
21248             }
21249         }
21250
21251         return proc;
21252     }
21253
21254     public boolean dumpHeap(String process, int userId, boolean managed,
21255             String path, ParcelFileDescriptor fd) throws RemoteException {
21256
21257         try {
21258             synchronized (this) {
21259                 // note: hijacking SET_ACTIVITY_WATCHER, but should be changed to
21260                 // its own permission (same as profileControl).
21261                 if (checkCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER)
21262                         != PackageManager.PERMISSION_GRANTED) {
21263                     throw new SecurityException("Requires permission "
21264                             + android.Manifest.permission.SET_ACTIVITY_WATCHER);
21265                 }
21266
21267                 if (fd == null) {
21268                     throw new IllegalArgumentException("null fd");
21269                 }
21270
21271                 ProcessRecord proc = findProcessLocked(process, userId, "dumpHeap");
21272                 if (proc == null || proc.thread == null) {
21273                     throw new IllegalArgumentException("Unknown process: " + process);
21274                 }
21275
21276                 boolean isDebuggable = "1".equals(SystemProperties.get(SYSTEM_DEBUGGABLE, "0"));
21277                 if (!isDebuggable) {
21278                     if ((proc.info.flags&ApplicationInfo.FLAG_DEBUGGABLE) == 0) {
21279                         throw new SecurityException("Process not debuggable: " + proc);
21280                     }
21281                 }
21282
21283                 proc.thread.dumpHeap(managed, path, fd);
21284                 fd = null;
21285                 return true;
21286             }
21287         } catch (RemoteException e) {
21288             throw new IllegalStateException("Process disappeared");
21289         } finally {
21290             if (fd != null) {
21291                 try {
21292                     fd.close();
21293                 } catch (IOException e) {
21294                 }
21295             }
21296         }
21297     }
21298
21299     @Override
21300     public void setDumpHeapDebugLimit(String processName, int uid, long maxMemSize,
21301             String reportPackage) {
21302         if (processName != null) {
21303             enforceCallingPermission(android.Manifest.permission.SET_DEBUG_APP,
21304                     "setDumpHeapDebugLimit()");
21305         } else {
21306             synchronized (mPidsSelfLocked) {
21307                 ProcessRecord proc = mPidsSelfLocked.get(Binder.getCallingPid());
21308                 if (proc == null) {
21309                     throw new SecurityException("No process found for calling pid "
21310                             + Binder.getCallingPid());
21311                 }
21312                 if (!Build.IS_DEBUGGABLE
21313                         && (proc.info.flags&ApplicationInfo.FLAG_DEBUGGABLE) == 0) {
21314                     throw new SecurityException("Not running a debuggable build");
21315                 }
21316                 processName = proc.processName;
21317                 uid = proc.uid;
21318                 if (reportPackage != null && !proc.pkgList.containsKey(reportPackage)) {
21319                     throw new SecurityException("Package " + reportPackage + " is not running in "
21320                             + proc);
21321                 }
21322             }
21323         }
21324         synchronized (this) {
21325             if (maxMemSize > 0) {
21326                 mMemWatchProcesses.put(processName, uid, new Pair(maxMemSize, reportPackage));
21327             } else {
21328                 if (uid != 0) {
21329                     mMemWatchProcesses.remove(processName, uid);
21330                 } else {
21331                     mMemWatchProcesses.getMap().remove(processName);
21332                 }
21333             }
21334         }
21335     }
21336
21337     @Override
21338     public void dumpHeapFinished(String path) {
21339         synchronized (this) {
21340             if (Binder.getCallingPid() != mMemWatchDumpPid) {
21341                 Slog.w(TAG, "dumpHeapFinished: Calling pid " + Binder.getCallingPid()
21342                         + " does not match last pid " + mMemWatchDumpPid);
21343                 return;
21344             }
21345             if (mMemWatchDumpFile == null || !mMemWatchDumpFile.equals(path)) {
21346                 Slog.w(TAG, "dumpHeapFinished: Calling path " + path
21347                         + " does not match last path " + mMemWatchDumpFile);
21348                 return;
21349             }
21350             if (DEBUG_PSS) Slog.d(TAG_PSS, "Dump heap finished for " + path);
21351             mHandler.sendEmptyMessage(POST_DUMP_HEAP_NOTIFICATION_MSG);
21352         }
21353     }
21354
21355     /** In this method we try to acquire our lock to make sure that we have not deadlocked */
21356     public void monitor() {
21357         synchronized (this) { }
21358     }
21359
21360     void onCoreSettingsChange(Bundle settings) {
21361         for (int i = mLruProcesses.size() - 1; i >= 0; i--) {
21362             ProcessRecord processRecord = mLruProcesses.get(i);
21363             try {
21364                 if (processRecord.thread != null) {
21365                     processRecord.thread.setCoreSettings(settings);
21366                 }
21367             } catch (RemoteException re) {
21368                 /* ignore */
21369             }
21370         }
21371     }
21372
21373     // Multi-user methods
21374
21375     /**
21376      * Start user, if its not already running, but don't bring it to foreground.
21377      */
21378     @Override
21379     public boolean startUserInBackground(final int userId) {
21380         return mUserController.startUser(userId, /* foreground */ false);
21381     }
21382
21383     @Override
21384     public boolean unlockUser(int userId, byte[] token, byte[] secret, IProgressListener listener) {
21385         return mUserController.unlockUser(userId, token, secret, listener);
21386     }
21387
21388     @Override
21389     public boolean switchUser(final int targetUserId) {
21390         enforceShellRestriction(UserManager.DISALLOW_DEBUGGING_FEATURES, targetUserId);
21391         UserInfo currentUserInfo;
21392         UserInfo targetUserInfo;
21393         synchronized (this) {
21394             int currentUserId = mUserController.getCurrentUserIdLocked();
21395             currentUserInfo = mUserController.getUserInfo(currentUserId);
21396             targetUserInfo = mUserController.getUserInfo(targetUserId);
21397             if (targetUserInfo == null) {
21398                 Slog.w(TAG, "No user info for user #" + targetUserId);
21399                 return false;
21400             }
21401             if (!targetUserInfo.supportsSwitchTo()) {
21402                 Slog.w(TAG, "Cannot switch to User #" + targetUserId + ": not supported");
21403                 return false;
21404             }
21405             if (targetUserInfo.isManagedProfile()) {
21406                 Slog.w(TAG, "Cannot switch to User #" + targetUserId + ": not a full user");
21407                 return false;
21408             }
21409             mUserController.setTargetUserIdLocked(targetUserId);
21410         }
21411         Pair<UserInfo, UserInfo> userNames = new Pair<>(currentUserInfo, targetUserInfo);
21412         mUiHandler.removeMessages(START_USER_SWITCH_UI_MSG);
21413         mUiHandler.sendMessage(mUiHandler.obtainMessage(START_USER_SWITCH_UI_MSG, userNames));
21414         return true;
21415     }
21416
21417     void scheduleStartProfilesLocked() {
21418         if (!mHandler.hasMessages(START_PROFILES_MSG)) {
21419             mHandler.sendMessageDelayed(mHandler.obtainMessage(START_PROFILES_MSG),
21420                     DateUtils.SECOND_IN_MILLIS);
21421         }
21422     }
21423
21424     @Override
21425     public int stopUser(final int userId, boolean force, final IStopUserCallback callback) {
21426         return mUserController.stopUser(userId, force, callback);
21427     }
21428
21429     @Override
21430     public UserInfo getCurrentUser() {
21431         return mUserController.getCurrentUser();
21432     }
21433
21434     @Override
21435     public boolean isUserRunning(int userId, int flags) {
21436         if (userId != UserHandle.getCallingUserId() && checkCallingPermission(
21437                 INTERACT_ACROSS_USERS) != PackageManager.PERMISSION_GRANTED) {
21438             String msg = "Permission Denial: isUserRunning() from pid="
21439                     + Binder.getCallingPid()
21440                     + ", uid=" + Binder.getCallingUid()
21441                     + " requires " + INTERACT_ACROSS_USERS;
21442             Slog.w(TAG, msg);
21443             throw new SecurityException(msg);
21444         }
21445         synchronized (this) {
21446             return mUserController.isUserRunningLocked(userId, flags);
21447         }
21448     }
21449
21450     @Override
21451     public int[] getRunningUserIds() {
21452         if (checkCallingPermission(INTERACT_ACROSS_USERS)
21453                 != PackageManager.PERMISSION_GRANTED) {
21454             String msg = "Permission Denial: isUserRunning() from pid="
21455                     + Binder.getCallingPid()
21456                     + ", uid=" + Binder.getCallingUid()
21457                     + " requires " + INTERACT_ACROSS_USERS;
21458             Slog.w(TAG, msg);
21459             throw new SecurityException(msg);
21460         }
21461         synchronized (this) {
21462             return mUserController.getStartedUserArrayLocked();
21463         }
21464     }
21465
21466     @Override
21467     public void registerUserSwitchObserver(IUserSwitchObserver observer) {
21468         mUserController.registerUserSwitchObserver(observer);
21469     }
21470
21471     @Override
21472     public void unregisterUserSwitchObserver(IUserSwitchObserver observer) {
21473         mUserController.unregisterUserSwitchObserver(observer);
21474     }
21475
21476     ApplicationInfo getAppInfoForUser(ApplicationInfo info, int userId) {
21477         if (info == null) return null;
21478         ApplicationInfo newInfo = new ApplicationInfo(info);
21479         newInfo.initForUser(userId);
21480         return newInfo;
21481     }
21482
21483     public boolean isUserStopped(int userId) {
21484         synchronized (this) {
21485             return mUserController.getStartedUserStateLocked(userId) == null;
21486         }
21487     }
21488
21489     ActivityInfo getActivityInfoForUser(ActivityInfo aInfo, int userId) {
21490         if (aInfo == null
21491                 || (userId < 1 && aInfo.applicationInfo.uid < UserHandle.PER_USER_RANGE)) {
21492             return aInfo;
21493         }
21494
21495         ActivityInfo info = new ActivityInfo(aInfo);
21496         info.applicationInfo = getAppInfoForUser(info.applicationInfo, userId);
21497         return info;
21498     }
21499
21500     private boolean processSanityChecksLocked(ProcessRecord process) {
21501         if (process == null || process.thread == null) {
21502             return false;
21503         }
21504
21505         boolean isDebuggable = "1".equals(SystemProperties.get(SYSTEM_DEBUGGABLE, "0"));
21506         if (!isDebuggable) {
21507             if ((process.info.flags&ApplicationInfo.FLAG_DEBUGGABLE) == 0) {
21508                 return false;
21509             }
21510         }
21511
21512         return true;
21513     }
21514
21515     public boolean startBinderTracking() throws RemoteException {
21516         synchronized (this) {
21517             mBinderTransactionTrackingEnabled = true;
21518             // TODO: hijacking SET_ACTIVITY_WATCHER, but should be changed to its own
21519             // permission (same as profileControl).
21520             if (checkCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER)
21521                     != PackageManager.PERMISSION_GRANTED) {
21522                 throw new SecurityException("Requires permission "
21523                         + android.Manifest.permission.SET_ACTIVITY_WATCHER);
21524             }
21525
21526             for (int i = 0; i < mLruProcesses.size(); i++) {
21527                 ProcessRecord process = mLruProcesses.get(i);
21528                 if (!processSanityChecksLocked(process)) {
21529                     continue;
21530                 }
21531                 try {
21532                     process.thread.startBinderTracking();
21533                 } catch (RemoteException e) {
21534                     Log.v(TAG, "Process disappared");
21535                 }
21536             }
21537             return true;
21538         }
21539     }
21540
21541     public boolean stopBinderTrackingAndDump(ParcelFileDescriptor fd) throws RemoteException {
21542         try {
21543             synchronized (this) {
21544                 mBinderTransactionTrackingEnabled = false;
21545                 // TODO: hijacking SET_ACTIVITY_WATCHER, but should be changed to its own
21546                 // permission (same as profileControl).
21547                 if (checkCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER)
21548                         != PackageManager.PERMISSION_GRANTED) {
21549                     throw new SecurityException("Requires permission "
21550                             + android.Manifest.permission.SET_ACTIVITY_WATCHER);
21551                 }
21552
21553                 if (fd == null) {
21554                     throw new IllegalArgumentException("null fd");
21555                 }
21556
21557                 PrintWriter pw = new FastPrintWriter(new FileOutputStream(fd.getFileDescriptor()));
21558                 pw.println("Binder transaction traces for all processes.\n");
21559                 for (ProcessRecord process : mLruProcesses) {
21560                     if (!processSanityChecksLocked(process)) {
21561                         continue;
21562                     }
21563
21564                     pw.println("Traces for process: " + process.processName);
21565                     pw.flush();
21566                     try {
21567                         TransferPipe tp = new TransferPipe();
21568                         try {
21569                             process.thread.stopBinderTrackingAndDump(
21570                                     tp.getWriteFd().getFileDescriptor());
21571                             tp.go(fd.getFileDescriptor());
21572                         } finally {
21573                             tp.kill();
21574                         }
21575                     } catch (IOException e) {
21576                         pw.println("Failure while dumping IPC traces from " + process +
21577                                 ".  Exception: " + e);
21578                         pw.flush();
21579                     } catch (RemoteException e) {
21580                         pw.println("Got a RemoteException while dumping IPC traces from " +
21581                                 process + ".  Exception: " + e);
21582                         pw.flush();
21583                     }
21584                 }
21585                 fd = null;
21586                 return true;
21587             }
21588         } finally {
21589             if (fd != null) {
21590                 try {
21591                     fd.close();
21592                 } catch (IOException e) {
21593                 }
21594             }
21595         }
21596     }
21597
21598     private final class LocalService extends ActivityManagerInternal {
21599         @Override
21600         public void grantUriPermissionFromIntent(int callingUid, String targetPkg, Intent intent,
21601                 int targetUserId) {
21602             synchronized (ActivityManagerService.this) {
21603                 ActivityManagerService.this.grantUriPermissionFromIntentLocked(callingUid,
21604                         targetPkg, intent, null, targetUserId);
21605             }
21606         }
21607
21608         @Override
21609         public String checkContentProviderAccess(String authority, int userId) {
21610             return ActivityManagerService.this.checkContentProviderAccess(authority, userId);
21611         }
21612
21613         @Override
21614         public void onWakefulnessChanged(int wakefulness) {
21615             ActivityManagerService.this.onWakefulnessChanged(wakefulness);
21616         }
21617
21618         @Override
21619         public int startIsolatedProcess(String entryPoint, String[] entryPointArgs,
21620                 String processName, String abiOverride, int uid, Runnable crashHandler) {
21621             return ActivityManagerService.this.startIsolatedProcess(entryPoint, entryPointArgs,
21622                     processName, abiOverride, uid, crashHandler);
21623         }
21624
21625         @Override
21626         public SleepToken acquireSleepToken(String tag) {
21627             Preconditions.checkNotNull(tag);
21628
21629             ComponentName requestedVrService = null;
21630             ComponentName callingVrActivity = null;
21631             int userId = -1;
21632             synchronized (ActivityManagerService.this) {
21633                 if (mFocusedActivity != null) {
21634                     requestedVrService = mFocusedActivity.requestedVrComponent;
21635                     callingVrActivity = mFocusedActivity.info.getComponentName();
21636                     userId = mFocusedActivity.userId;
21637                 }
21638             }
21639
21640             if (requestedVrService != null) {
21641                 applyVrMode(false, requestedVrService, userId, callingVrActivity, true);
21642             }
21643
21644             synchronized (ActivityManagerService.this) {
21645                 SleepTokenImpl token = new SleepTokenImpl(tag);
21646                 mSleepTokens.add(token);
21647                 updateSleepIfNeededLocked();
21648                 return token;
21649             }
21650         }
21651
21652         @Override
21653         public ComponentName getHomeActivityForUser(int userId) {
21654             synchronized (ActivityManagerService.this) {
21655                 ActivityRecord homeActivity = mStackSupervisor.getHomeActivityForUser(userId);
21656                 return homeActivity == null ? null : homeActivity.realActivity;
21657             }
21658         }
21659
21660         @Override
21661         public void onUserRemoved(int userId) {
21662             synchronized (ActivityManagerService.this) {
21663                 ActivityManagerService.this.onUserStoppedLocked(userId);
21664             }
21665         }
21666
21667         @Override
21668         public void onLocalVoiceInteractionStarted(IBinder activity,
21669                 IVoiceInteractionSession voiceSession, IVoiceInteractor voiceInteractor) {
21670             synchronized (ActivityManagerService.this) {
21671                 ActivityManagerService.this.onLocalVoiceInteractionStartedLocked(activity,
21672                         voiceSession, voiceInteractor);
21673             }
21674         }
21675
21676         @Override
21677         public void notifyStartingWindowDrawn() {
21678             synchronized (ActivityManagerService.this) {
21679                 mStackSupervisor.mActivityMetricsLogger.notifyStartingWindowDrawn();
21680             }
21681         }
21682
21683         @Override
21684         public void notifyAppTransitionStarting(int reason) {
21685             synchronized (ActivityManagerService.this) {
21686                 mStackSupervisor.mActivityMetricsLogger.notifyTransitionStarting(reason);
21687             }
21688         }
21689
21690         @Override
21691         public void notifyAppTransitionFinished() {
21692             synchronized (ActivityManagerService.this) {
21693                 mStackSupervisor.notifyAppTransitionDone();
21694             }
21695         }
21696
21697         @Override
21698         public void notifyAppTransitionCancelled() {
21699             synchronized (ActivityManagerService.this) {
21700                 mStackSupervisor.notifyAppTransitionDone();
21701             }
21702         }
21703
21704         @Override
21705         public List<IBinder> getTopVisibleActivities() {
21706             synchronized (ActivityManagerService.this) {
21707                 return mStackSupervisor.getTopVisibleActivities();
21708             }
21709         }
21710
21711         @Override
21712         public void notifyDockedStackMinimizedChanged(boolean minimized) {
21713             synchronized (ActivityManagerService.this) {
21714                 mStackSupervisor.setDockedStackMinimized(minimized);
21715             }
21716         }
21717
21718         @Override
21719         public void killForegroundAppsForUser(int userHandle) {
21720             synchronized (ActivityManagerService.this) {
21721                 final ArrayList<ProcessRecord> procs = new ArrayList<>();
21722                 final int NP = mProcessNames.getMap().size();
21723                 for (int ip = 0; ip < NP; ip++) {
21724                     final SparseArray<ProcessRecord> apps = mProcessNames.getMap().valueAt(ip);
21725                     final int NA = apps.size();
21726                     for (int ia = 0; ia < NA; ia++) {
21727                         final ProcessRecord app = apps.valueAt(ia);
21728                         if (app.persistent) {
21729                             // We don't kill persistent processes.
21730                             continue;
21731                         }
21732                         if (app.removed) {
21733                             procs.add(app);
21734                         } else if (app.userId == userHandle && app.foregroundActivities) {
21735                             app.removed = true;
21736                             procs.add(app);
21737                         }
21738                     }
21739                 }
21740
21741                 final int N = procs.size();
21742                 for (int i = 0; i < N; i++) {
21743                     removeProcessLocked(procs.get(i), false, true, "kill all fg");
21744                 }
21745             }
21746         }
21747
21748         @Override
21749         public void setPendingIntentWhitelistDuration(IIntentSender target, long duration) {
21750             if (!(target instanceof PendingIntentRecord)) {
21751                 Slog.w(TAG, "markAsSentFromNotification(): not a PendingIntentRecord: " + target);
21752                 return;
21753             }
21754             ((PendingIntentRecord) target).setWhitelistDuration(duration);
21755         }
21756     }
21757
21758     private final class SleepTokenImpl extends SleepToken {
21759         private final String mTag;
21760         private final long mAcquireTime;
21761
21762         public SleepTokenImpl(String tag) {
21763             mTag = tag;
21764             mAcquireTime = SystemClock.uptimeMillis();
21765         }
21766
21767         @Override
21768         public void release() {
21769             synchronized (ActivityManagerService.this) {
21770                 if (mSleepTokens.remove(this)) {
21771                     updateSleepIfNeededLocked();
21772                 }
21773             }
21774         }
21775
21776         @Override
21777         public String toString() {
21778             return "{\"" + mTag + "\", acquire at " + TimeUtils.formatUptime(mAcquireTime) + "}";
21779         }
21780     }
21781
21782     /**
21783      * An implementation of IAppTask, that allows an app to manage its own tasks via
21784      * {@link android.app.ActivityManager.AppTask}.  We keep track of the callingUid to ensure that
21785      * only the process that calls getAppTasks() can call the AppTask methods.
21786      */
21787     class AppTaskImpl extends IAppTask.Stub {
21788         private int mTaskId;
21789         private int mCallingUid;
21790
21791         public AppTaskImpl(int taskId, int callingUid) {
21792             mTaskId = taskId;
21793             mCallingUid = callingUid;
21794         }
21795
21796         private void checkCaller() {
21797             if (mCallingUid != Binder.getCallingUid()) {
21798                 throw new SecurityException("Caller " + mCallingUid
21799                         + " does not match caller of getAppTasks(): " + Binder.getCallingUid());
21800             }
21801         }
21802
21803         @Override
21804         public void finishAndRemoveTask() {
21805             checkCaller();
21806
21807             synchronized (ActivityManagerService.this) {
21808                 long origId = Binder.clearCallingIdentity();
21809                 try {
21810                     // We remove the task from recents to preserve backwards
21811                     if (!removeTaskByIdLocked(mTaskId, false, REMOVE_FROM_RECENTS)) {
21812                         throw new IllegalArgumentException("Unable to find task ID " + mTaskId);
21813                     }
21814                 } finally {
21815                     Binder.restoreCallingIdentity(origId);
21816                 }
21817             }
21818         }
21819
21820         @Override
21821         public ActivityManager.RecentTaskInfo getTaskInfo() {
21822             checkCaller();
21823
21824             synchronized (ActivityManagerService.this) {
21825                 long origId = Binder.clearCallingIdentity();
21826                 try {
21827                     TaskRecord tr = mStackSupervisor.anyTaskForIdLocked(mTaskId);
21828                     if (tr == null) {
21829                         throw new IllegalArgumentException("Unable to find task ID " + mTaskId);
21830                     }
21831                     return createRecentTaskInfoFromTaskRecord(tr);
21832                 } finally {
21833                     Binder.restoreCallingIdentity(origId);
21834                 }
21835             }
21836         }
21837
21838         @Override
21839         public void moveToFront() {
21840             checkCaller();
21841             // Will bring task to front if it already has a root activity.
21842             final long origId = Binder.clearCallingIdentity();
21843             try {
21844                 synchronized (this) {
21845                     mStackSupervisor.startActivityFromRecentsInner(mTaskId, null);
21846                 }
21847             } finally {
21848                 Binder.restoreCallingIdentity(origId);
21849             }
21850         }
21851
21852         @Override
21853         public int startActivity(IBinder whoThread, String callingPackage,
21854                 Intent intent, String resolvedType, Bundle bOptions) {
21855             checkCaller();
21856
21857             int callingUser = UserHandle.getCallingUserId();
21858             TaskRecord tr;
21859             IApplicationThread appThread;
21860             synchronized (ActivityManagerService.this) {
21861                 tr = mStackSupervisor.anyTaskForIdLocked(mTaskId);
21862                 if (tr == null) {
21863                     throw new IllegalArgumentException("Unable to find task ID " + mTaskId);
21864                 }
21865                 appThread = ApplicationThreadNative.asInterface(whoThread);
21866                 if (appThread == null) {
21867                     throw new IllegalArgumentException("Bad app thread " + appThread);
21868                 }
21869             }
21870             return mActivityStarter.startActivityMayWait(appThread, -1, callingPackage, intent,
21871                     resolvedType, null, null, null, null, 0, 0, null, null,
21872                     null, bOptions, false, callingUser, null, tr);
21873         }
21874
21875         @Override
21876         public void setExcludeFromRecents(boolean exclude) {
21877             checkCaller();
21878
21879             synchronized (ActivityManagerService.this) {
21880                 long origId = Binder.clearCallingIdentity();
21881                 try {
21882                     TaskRecord tr = mStackSupervisor.anyTaskForIdLocked(mTaskId);
21883                     if (tr == null) {
21884                         throw new IllegalArgumentException("Unable to find task ID " + mTaskId);
21885                     }
21886                     Intent intent = tr.getBaseIntent();
21887                     if (exclude) {
21888                         intent.addFlags(Intent.FLAG_ACTIVITY_EXCLUDE_FROM_RECENTS);
21889                     } else {
21890                         intent.setFlags(intent.getFlags()
21891                                 & ~Intent.FLAG_ACTIVITY_EXCLUDE_FROM_RECENTS);
21892                     }
21893                 } finally {
21894                     Binder.restoreCallingIdentity(origId);
21895                 }
21896             }
21897         }
21898     }
21899
21900     /**
21901      * Kill processes for the user with id userId and that depend on the package named packageName
21902      */
21903     @Override
21904     public void killPackageDependents(String packageName, int userId) {
21905         enforceCallingPermission(android.Manifest.permission.KILL_UID, "killPackageDependents()");
21906         if (packageName == null) {
21907             throw new NullPointerException(
21908                     "Cannot kill the dependents of a package without its name.");
21909         }
21910
21911         long callingId = Binder.clearCallingIdentity();
21912         IPackageManager pm = AppGlobals.getPackageManager();
21913         int pkgUid = -1;
21914         try {
21915             pkgUid = pm.getPackageUid(packageName, MATCH_DEBUG_TRIAGED_MISSING, userId);
21916         } catch (RemoteException e) {
21917         }
21918         if (userId != UserHandle.USER_ALL && pkgUid == -1) {
21919             throw new IllegalArgumentException(
21920                     "Cannot kill dependents of non-existing package " + packageName);
21921         }
21922         try {
21923             synchronized(this) {
21924                 killPackageProcessesLocked(packageName, UserHandle.getAppId(pkgUid), userId,
21925                         ProcessList.FOREGROUND_APP_ADJ, false, true, true, false,
21926                         "dep: " + packageName);
21927             }
21928         } finally {
21929             Binder.restoreCallingIdentity(callingId);
21930         }
21931     }
21932 }