OSDN Git Service

Show launcher when profile is locked immediately
[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.google.android.collect.Lists;
20 import com.google.android.collect.Maps;
21 import com.android.internal.R;
22 import com.android.internal.annotations.GuardedBy;
23 import com.android.internal.app.AssistUtils;
24 import com.android.internal.app.DumpHeapActivity;
25 import com.android.internal.app.IAppOpsCallback;
26 import com.android.internal.app.IAppOpsService;
27 import com.android.internal.app.IVoiceInteractor;
28 import com.android.internal.app.ProcessMap;
29 import com.android.internal.app.ProcessStats;
30 import com.android.internal.app.SystemUserHomeActivity;
31 import com.android.internal.os.BackgroundThread;
32 import com.android.internal.os.BatteryStatsImpl;
33 import com.android.internal.os.IResultReceiver;
34 import com.android.internal.os.ProcessCpuTracker;
35 import com.android.internal.os.TransferPipe;
36 import com.android.internal.os.Zygote;
37 import com.android.internal.os.InstallerConnection.InstallerException;
38 import com.android.internal.util.ArrayUtils;
39 import com.android.internal.util.FastPrintWriter;
40 import com.android.internal.util.FastXmlSerializer;
41 import com.android.internal.util.MemInfoReader;
42 import com.android.internal.util.Preconditions;
43 import com.android.server.AppOpsService;
44 import com.android.server.AttributeCache;
45 import com.android.server.DeviceIdleController;
46 import com.android.server.IntentResolver;
47 import com.android.server.LocalServices;
48 import com.android.server.LockGuard;
49 import com.android.server.ServiceThread;
50 import com.android.server.SystemService;
51 import com.android.server.SystemServiceManager;
52 import com.android.server.Watchdog;
53 import com.android.server.am.ActivityStack.ActivityState;
54 import com.android.server.firewall.IntentFirewall;
55 import com.android.server.pm.Installer;
56 import com.android.server.statusbar.StatusBarManagerInternal;
57 import com.android.server.vr.VrManagerInternal;
58 import com.android.server.wm.AppTransition;
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.admin.DevicePolicyManagerInternal;
106 import android.app.admin.IDevicePolicyManager;
107 import android.app.assist.AssistContent;
108 import android.app.assist.AssistStructure;
109 import android.app.backup.IBackupManager;
110 import android.app.usage.UsageEvents;
111 import android.app.usage.UsageStatsManagerInternal;
112 import android.appwidget.AppWidgetManager;
113 import android.content.ActivityNotFoundException;
114 import android.content.BroadcastReceiver;
115 import android.content.ClipData;
116 import android.content.ComponentCallbacks2;
117 import android.content.ComponentName;
118 import android.content.ContentProvider;
119 import android.content.ContentResolver;
120 import android.content.Context;
121 import android.content.DialogInterface;
122 import android.content.IContentProvider;
123 import android.content.IIntentReceiver;
124 import android.content.IIntentSender;
125 import android.content.Intent;
126 import android.content.IntentFilter;
127 import android.content.IntentSender;
128 import android.content.pm.ActivityInfo;
129 import android.content.pm.ApplicationInfo;
130 import android.content.pm.ConfigurationInfo;
131 import android.content.pm.IPackageDataObserver;
132 import android.content.pm.IPackageManager;
133 import android.content.pm.InstrumentationInfo;
134 import android.content.pm.PackageInfo;
135 import android.content.pm.PackageManager;
136 import android.content.pm.PackageManager.NameNotFoundException;
137 import android.content.pm.PackageManagerInternal;
138 import android.content.pm.ParceledListSlice;
139 import android.content.pm.PathPermission;
140 import android.content.pm.PermissionInfo;
141 import android.content.pm.ProviderInfo;
142 import android.content.pm.ResolveInfo;
143 import android.content.pm.ServiceInfo;
144 import android.content.pm.UserInfo;
145 import android.content.res.CompatibilityInfo;
146 import android.content.res.Configuration;
147 import android.content.res.Resources;
148 import android.database.ContentObserver;
149 import android.graphics.Bitmap;
150 import android.graphics.Point;
151 import android.graphics.Rect;
152 import android.location.LocationManager;
153 import android.net.Proxy;
154 import android.net.ProxyInfo;
155 import android.net.Uri;
156 import android.os.BatteryStats;
157 import android.os.Binder;
158 import android.os.Build;
159 import android.os.Bundle;
160 import android.os.Debug;
161 import android.os.DropBoxManager;
162 import android.os.Environment;
163 import android.os.FactoryTest;
164 import android.os.FileObserver;
165 import android.os.FileUtils;
166 import android.os.Handler;
167 import android.os.IBinder;
168 import android.os.IPermissionController;
169 import android.os.IProcessInfoService;
170 import android.os.Looper;
171 import android.os.Message;
172 import android.os.Parcel;
173 import android.os.ParcelFileDescriptor;
174 import android.os.PersistableBundle;
175 import android.os.PowerManager;
176 import android.os.PowerManagerInternal;
177 import android.os.Process;
178 import android.os.RemoteCallbackList;
179 import android.os.RemoteException;
180 import android.os.ResultReceiver;
181 import android.os.ServiceManager;
182 import android.os.StrictMode;
183 import android.os.SystemClock;
184 import android.os.SystemProperties;
185 import android.os.Trace;
186 import android.os.TransactionTooLargeException;
187 import android.os.UpdateLock;
188 import android.os.UserHandle;
189 import android.os.UserManager;
190 import android.os.WorkSource;
191 import android.os.storage.IMountService;
192 import android.os.storage.MountServiceInternal;
193 import android.os.storage.StorageManager;
194 import android.provider.Settings;
195 import android.service.voice.IVoiceInteractionSession;
196 import android.service.voice.VoiceInteractionManagerInternal;
197 import android.service.voice.VoiceInteractionSession;
198 import android.text.format.DateUtils;
199 import android.text.format.Time;
200 import android.util.ArrayMap;
201 import android.util.ArraySet;
202 import android.util.AtomicFile;
203 import android.util.DebugUtils;
204 import android.util.EventLog;
205 import android.util.LocaleList;
206 import android.util.Log;
207 import android.util.Pair;
208 import android.util.PrintWriterPrinter;
209 import android.util.Slog;
210 import android.util.SparseArray;
211 import android.util.TimeUtils;
212 import android.util.Xml;
213 import android.view.Display;
214 import android.view.Gravity;
215 import android.view.LayoutInflater;
216 import android.view.View;
217 import android.view.WindowManager;
218
219 import java.io.BufferedInputStream;
220 import java.io.BufferedOutputStream;
221 import java.io.DataInputStream;
222 import java.io.DataOutputStream;
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.Set;
245 import java.util.concurrent.atomic.AtomicBoolean;
246 import java.util.concurrent.atomic.AtomicLong;
247
248 import dalvik.system.VMRuntime;
249
250 import libcore.io.IoUtils;
251 import libcore.util.EmptyArray;
252
253 import static android.Manifest.permission.INTERACT_ACROSS_USERS;
254 import static android.Manifest.permission.INTERACT_ACROSS_USERS_FULL;
255 import static android.Manifest.permission.MANAGE_ACTIVITY_STACKS;
256 import static android.Manifest.permission.START_TASKS_FROM_RECENTS;
257 import static android.app.ActivityManager.DOCKED_STACK_CREATE_MODE_TOP_OR_LEFT;
258 import static android.app.ActivityManager.RESIZE_MODE_PRESERVE_WINDOW;
259 import static android.app.ActivityManager.StackId.DOCKED_STACK_ID;
260 import static android.app.ActivityManager.StackId.FIRST_STATIC_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.LAST_STATIC_STACK_ID;
266 import static android.app.ActivityManager.StackId.PINNED_STACK_ID;
267 import static android.content.pm.PackageManager.FEATURE_FREEFORM_WINDOW_MANAGEMENT;
268 import static android.content.pm.PackageManager.FEATURE_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_UNAWARE;
272 import static android.content.pm.PackageManager.MATCH_SYSTEM_ONLY;
273 import static android.content.pm.PackageManager.MATCH_UNINSTALLED_PACKAGES;
274 import static android.content.pm.PackageManager.PERMISSION_GRANTED;
275 import static android.provider.Settings.Global.ALWAYS_FINISH_ACTIVITIES;
276 import static android.provider.Settings.Global.DEBUG_APP;
277 import static android.provider.Settings.Global.DEVELOPMENT_ENABLE_FREEFORM_WINDOWS_SUPPORT;
278 import static android.provider.Settings.Global.DEVELOPMENT_FORCE_RESIZABLE_ACTIVITIES;
279 import static android.provider.Settings.Global.DEVELOPMENT_FORCE_RTL;
280 import static android.provider.Settings.Global.LENIENT_BACKGROUND_CHECK;
281 import static android.provider.Settings.Global.WAIT_FOR_DEBUGGER;
282 import static android.provider.Settings.System.FONT_SCALE;
283 import static com.android.internal.util.XmlUtils.readBooleanAttribute;
284 import static com.android.internal.util.XmlUtils.readIntAttribute;
285 import static com.android.internal.util.XmlUtils.readLongAttribute;
286 import static com.android.internal.util.XmlUtils.writeBooleanAttribute;
287 import static com.android.internal.util.XmlUtils.writeIntAttribute;
288 import static com.android.internal.util.XmlUtils.writeLongAttribute;
289 import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_ALL;
290 import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_ANR;
291 import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_BACKUP;
292 import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_BROADCAST;
293 import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_BROADCAST_BACKGROUND;
294 import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_BROADCAST_LIGHT;
295 import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_CLEANUP;
296 import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_CONFIGURATION;
297 import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_FOCUS;
298 import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_IMMERSIVE;
299 import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_LOCKSCREEN;
300 import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_LOCKTASK;
301 import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_LRU;
302 import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_MU;
303 import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_OOM_ADJ;
304 import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_PERMISSIONS_REVIEW;
305 import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_POWER;
306 import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_POWER_QUICK;
307 import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_PROCESSES;
308 import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_PROCESS_OBSERVERS;
309 import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_PROVIDER;
310 import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_PSS;
311 import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_RECENTS;
312 import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_SERVICE;
313 import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_STACK;
314 import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_SWITCH;
315 import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_TASKS;
316 import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_UID_OBSERVERS;
317 import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_URI_PERMISSION;
318 import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_USAGE_STATS;
319 import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_VISIBILITY;
320 import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_VISIBLE_BEHIND;
321 import static com.android.server.am.ActivityManagerDebugConfig.POSTFIX_BACKUP;
322 import static com.android.server.am.ActivityManagerDebugConfig.POSTFIX_BROADCAST;
323 import static com.android.server.am.ActivityManagerDebugConfig.POSTFIX_CLEANUP;
324 import static com.android.server.am.ActivityManagerDebugConfig.POSTFIX_CONFIGURATION;
325 import static com.android.server.am.ActivityManagerDebugConfig.POSTFIX_FOCUS;
326 import static com.android.server.am.ActivityManagerDebugConfig.POSTFIX_IMMERSIVE;
327 import static com.android.server.am.ActivityManagerDebugConfig.POSTFIX_LOCKSCREEN;
328 import static com.android.server.am.ActivityManagerDebugConfig.POSTFIX_LOCKTASK;
329 import static com.android.server.am.ActivityManagerDebugConfig.POSTFIX_LRU;
330 import static com.android.server.am.ActivityManagerDebugConfig.POSTFIX_MU;
331 import static com.android.server.am.ActivityManagerDebugConfig.POSTFIX_OOM_ADJ;
332 import static com.android.server.am.ActivityManagerDebugConfig.POSTFIX_POWER;
333 import static com.android.server.am.ActivityManagerDebugConfig.POSTFIX_PROCESSES;
334 import static com.android.server.am.ActivityManagerDebugConfig.POSTFIX_PROCESS_OBSERVERS;
335 import static com.android.server.am.ActivityManagerDebugConfig.POSTFIX_PROVIDER;
336 import static com.android.server.am.ActivityManagerDebugConfig.POSTFIX_PSS;
337 import static com.android.server.am.ActivityManagerDebugConfig.POSTFIX_RECENTS;
338 import static com.android.server.am.ActivityManagerDebugConfig.POSTFIX_SERVICE;
339 import static com.android.server.am.ActivityManagerDebugConfig.POSTFIX_STACK;
340 import static com.android.server.am.ActivityManagerDebugConfig.POSTFIX_SWITCH;
341 import static com.android.server.am.ActivityManagerDebugConfig.POSTFIX_UID_OBSERVERS;
342 import static com.android.server.am.ActivityManagerDebugConfig.POSTFIX_URI_PERMISSION;
343 import static com.android.server.am.ActivityManagerDebugConfig.POSTFIX_VISIBILITY;
344 import static com.android.server.am.ActivityManagerDebugConfig.POSTFIX_VISIBLE_BEHIND;
345 import static com.android.server.am.ActivityManagerDebugConfig.TAG_AM;
346 import static com.android.server.am.ActivityManagerDebugConfig.TAG_WITH_CLASS_NAME;
347 import static com.android.server.am.ActivityStackSupervisor.ActivityContainer.FORCE_NEW_TASK_FLAGS;
348 import static com.android.server.am.ActivityStackSupervisor.FORCE_FOCUS;
349 import static com.android.server.am.ActivityStackSupervisor.ON_TOP;
350 import static com.android.server.am.ActivityStackSupervisor.PRESERVE_WINDOWS;
351 import static com.android.server.am.ActivityStackSupervisor.RESTORE_FROM_RECENTS;
352 import static com.android.server.am.TaskRecord.INVALID_TASK_ID;
353 import static com.android.server.am.TaskRecord.LOCK_TASK_AUTH_DONT_LOCK;
354 import static com.android.server.am.TaskRecord.LOCK_TASK_AUTH_LAUNCHABLE_PRIV;
355 import static com.android.server.am.TaskRecord.LOCK_TASK_AUTH_PINNABLE;
356 import static com.android.server.wm.AppTransition.TRANSIT_ACTIVITY_OPEN;
357 import static com.android.server.wm.AppTransition.TRANSIT_ACTIVITY_RELAUNCH;
358 import static com.android.server.wm.AppTransition.TRANSIT_TASK_IN_PLACE;
359 import static com.android.server.wm.AppTransition.TRANSIT_TASK_OPEN;
360 import static com.android.server.wm.AppTransition.TRANSIT_TASK_TO_FRONT;
361 import static org.xmlpull.v1.XmlPullParser.END_DOCUMENT;
362 import static org.xmlpull.v1.XmlPullParser.START_TAG;
363
364 public final class ActivityManagerService extends ActivityManagerNative
365         implements Watchdog.Monitor, BatteryStatsImpl.BatteryCallback {
366
367     // File that stores last updated system version and called preboot receivers
368     static final String CALLED_PRE_BOOTS_FILENAME = "called_pre_boots.dat";
369
370     private static final String TAG = TAG_WITH_CLASS_NAME ? "ActivityManagerService" : TAG_AM;
371     private static final String TAG_BACKUP = TAG + POSTFIX_BACKUP;
372     private static final String TAG_BROADCAST = TAG + POSTFIX_BROADCAST;
373     private static final String TAG_CLEANUP = TAG + POSTFIX_CLEANUP;
374     private static final String TAG_CONFIGURATION = TAG + POSTFIX_CONFIGURATION;
375     private static final String TAG_FOCUS = TAG + POSTFIX_FOCUS;
376     private static final String TAG_IMMERSIVE = TAG + POSTFIX_IMMERSIVE;
377     private static final String TAG_LOCKSCREEN = TAG + POSTFIX_LOCKSCREEN;
378     private static final String TAG_LOCKTASK = TAG + POSTFIX_LOCKTASK;
379     private static final String TAG_LRU = TAG + POSTFIX_LRU;
380     private static final String TAG_MU = TAG + POSTFIX_MU;
381     private static final String TAG_OOM_ADJ = TAG + POSTFIX_OOM_ADJ;
382     private static final String TAG_POWER = TAG + POSTFIX_POWER;
383     private static final String TAG_PROCESS_OBSERVERS = TAG + POSTFIX_PROCESS_OBSERVERS;
384     private static final String TAG_PROCESSES = TAG + POSTFIX_PROCESSES;
385     private static final String TAG_PROVIDER = TAG + POSTFIX_PROVIDER;
386     private static final String TAG_PSS = TAG + POSTFIX_PSS;
387     private static final String TAG_RECENTS = TAG + POSTFIX_RECENTS;
388     private static final String TAG_SERVICE = TAG + POSTFIX_SERVICE;
389     private static final String TAG_STACK = TAG + POSTFIX_STACK;
390     private static final String TAG_SWITCH = TAG + POSTFIX_SWITCH;
391     private static final String TAG_UID_OBSERVERS = TAG + POSTFIX_UID_OBSERVERS;
392     private static final String TAG_URI_PERMISSION = TAG + POSTFIX_URI_PERMISSION;
393     private static final String TAG_VISIBILITY = TAG + POSTFIX_VISIBILITY;
394     private static final String TAG_VISIBLE_BEHIND = TAG + POSTFIX_VISIBLE_BEHIND;
395
396     /** Control over CPU and battery monitoring */
397     // write battery stats every 30 minutes.
398     static final long BATTERY_STATS_TIME = 30 * 60 * 1000;
399     static final boolean MONITOR_CPU_USAGE = true;
400     // don't sample cpu less than every 5 seconds.
401     static final long MONITOR_CPU_MIN_TIME = 5 * 1000;
402     // wait possibly forever for next cpu sample.
403     static final long MONITOR_CPU_MAX_TIME = 0x0fffffff;
404     static final boolean MONITOR_THREAD_CPU_USAGE = false;
405
406     // The flags that are set for all calls we make to the package manager.
407     static final int STOCK_PM_FLAGS = PackageManager.GET_SHARED_LIBRARY_FILES;
408
409     static final String SYSTEM_DEBUGGABLE = "ro.debuggable";
410
411     static final boolean IS_USER_BUILD = "user".equals(Build.TYPE);
412
413     // Amount of time after a call to stopAppSwitches() during which we will
414     // prevent further untrusted switches from happening.
415     static final long APP_SWITCH_DELAY_TIME = 5*1000;
416
417     // How long we wait for a launched process to attach to the activity manager
418     // before we decide it's never going to come up for real.
419     static final int PROC_START_TIMEOUT = 10*1000;
420     // How long we wait for an attached process to publish its content providers
421     // before we decide it must be hung.
422     static final int CONTENT_PROVIDER_PUBLISH_TIMEOUT = 10*1000;
423
424     // How long we will retain processes hosting content providers in the "last activity"
425     // state before allowing them to drop down to the regular cached LRU list.  This is
426     // to avoid thrashing of provider processes under low memory situations.
427     static final int CONTENT_PROVIDER_RETAIN_TIME = 20*1000;
428
429     // How long we wait for a launched process to attach to the activity manager
430     // before we decide it's never going to come up for real, when the process was
431     // started with a wrapper for instrumentation (such as Valgrind) because it
432     // could take much longer than usual.
433     static final int PROC_START_TIMEOUT_WITH_WRAPPER = 1200*1000;
434
435     // How long to wait after going idle before forcing apps to GC.
436     static final int GC_TIMEOUT = 5*1000;
437
438     // The minimum amount of time between successive GC requests for a process.
439     static final int GC_MIN_INTERVAL = 60*1000;
440
441     // The minimum amount of time between successive PSS requests for a process.
442     static final int FULL_PSS_MIN_INTERVAL = 10*60*1000;
443
444     // The minimum amount of time between successive PSS requests for a process
445     // when the request is due to the memory state being lowered.
446     static final int FULL_PSS_LOWERED_INTERVAL = 2*60*1000;
447
448     // The rate at which we check for apps using excessive power -- 15 mins.
449     static final int POWER_CHECK_DELAY = (DEBUG_POWER_QUICK ? 2 : 15) * 60*1000;
450
451     // The minimum sample duration we will allow before deciding we have
452     // enough data on wake locks to start killing things.
453     static final int WAKE_LOCK_MIN_CHECK_DURATION = (DEBUG_POWER_QUICK ? 1 : 5) * 60*1000;
454
455     // The minimum sample duration we will allow before deciding we have
456     // enough data on CPU usage to start killing things.
457     static final int CPU_MIN_CHECK_DURATION = (DEBUG_POWER_QUICK ? 1 : 5) * 60*1000;
458
459     // How long we allow a receiver to run before giving up on it.
460     static final int BROADCAST_FG_TIMEOUT = 10*1000;
461     static final int BROADCAST_BG_TIMEOUT = 60*1000;
462
463     // How long we wait until we timeout on key dispatching.
464     static final int KEY_DISPATCHING_TIMEOUT = 5*1000;
465
466     // How long we wait until we timeout on key dispatching during instrumentation.
467     static final int INSTRUMENTATION_KEY_DISPATCHING_TIMEOUT = 60*1000;
468
469     // This is the amount of time an app needs to be running a foreground service before
470     // we will consider it to be doing interaction for usage stats.
471     static final int SERVICE_USAGE_INTERACTION_TIME = 30*60*1000;
472
473     // Maximum amount of time we will allow to elapse before re-reporting usage stats
474     // interaction with foreground processes.
475     static final long USAGE_STATS_INTERACTION_INTERVAL = 24*60*60*1000L;
476
477     // This is the amount of time we allow an app to settle after it goes into the background,
478     // before we start restricting what it can do.
479     static final int BACKGROUND_SETTLE_TIME = 1*60*1000;
480
481     // How long to wait in getAssistContextExtras for the activity and foreground services
482     // to respond with the result.
483     static final int PENDING_ASSIST_EXTRAS_TIMEOUT = 500;
484
485     // How long top wait when going through the modern assist (which doesn't need to block
486     // on getting this result before starting to launch its UI).
487     static final int PENDING_ASSIST_EXTRAS_LONG_TIMEOUT = 2000;
488
489     // Maximum number of persisted Uri grants a package is allowed
490     static final int MAX_PERSISTED_URI_GRANTS = 128;
491
492     static final int MY_PID = Process.myPid();
493
494     static final String[] EMPTY_STRING_ARRAY = new String[0];
495
496     // How many bytes to write into the dropbox log before truncating
497     static final int DROPBOX_MAX_SIZE = 256 * 1024;
498
499     // Access modes for handleIncomingUser.
500     static final int ALLOW_NON_FULL = 0;
501     static final int ALLOW_NON_FULL_IN_PROFILE = 1;
502     static final int ALLOW_FULL_ONLY = 2;
503
504     static final int LAST_PREBOOT_DELIVERED_FILE_VERSION = 10000;
505
506     // Delay in notifying task stack change listeners (in millis)
507     static final int NOTIFY_TASK_STACK_CHANGE_LISTENERS_DELAY = 100;
508
509     // Necessary ApplicationInfo flags to mark an app as persistent
510     private static final int PERSISTENT_MASK =
511             ApplicationInfo.FLAG_SYSTEM|ApplicationInfo.FLAG_PERSISTENT;
512
513     // Intent sent when remote bugreport collection has been completed
514     private static final String INTENT_REMOTE_BUGREPORT_FINISHED =
515             "android.intent.action.REMOTE_BUGREPORT_FINISHED";
516
517     // Delay to disable app launch boost
518     static final int APP_BOOST_MESSAGE_DELAY = 3000;
519     // Lower delay than APP_BOOST_MESSAGE_DELAY to disable the boost
520     static final int APP_BOOST_TIMEOUT = 2500;
521
522     // Used to indicate that a task is removed it should also be removed from recents.
523     private static final boolean REMOVE_FROM_RECENTS = true;
524     // Used to indicate that an app transition should be animated.
525     static final boolean ANIMATE = true;
526
527     // Determines whether to take full screen screenshots
528     static final boolean TAKE_FULLSCREEN_SCREENSHOTS = true;
529
530     private static native int nativeMigrateToBoost();
531     private static native int nativeMigrateFromBoost();
532     private boolean mIsBoosted = false;
533     private long mBoostStartTime = 0;
534
535     /** All system services */
536     SystemServiceManager mSystemServiceManager;
537
538     private Installer mInstaller;
539
540     /** Run all ActivityStacks through this */
541     final ActivityStackSupervisor mStackSupervisor;
542
543     final ActivityStarter mActivityStarter;
544
545     /** Task stack change listeners. */
546     private final RemoteCallbackList<ITaskStackListener> mTaskStackListeners =
547             new RemoteCallbackList<ITaskStackListener>();
548
549     final InstrumentationReporter mInstrumentationReporter = new InstrumentationReporter();
550
551     public IntentFirewall mIntentFirewall;
552
553     // Whether we should show our dialogs (ANR, crash, etc) or just perform their
554     // default actuion automatically.  Important for devices without direct input
555     // devices.
556     private boolean mShowDialogs = true;
557     private boolean mInVrMode = false;
558
559     BroadcastQueue mFgBroadcastQueue;
560     BroadcastQueue mBgBroadcastQueue;
561     // Convenient for easy iteration over the queues. Foreground is first
562     // so that dispatch of foreground broadcasts gets precedence.
563     final BroadcastQueue[] mBroadcastQueues = new BroadcastQueue[2];
564
565     BroadcastQueue broadcastQueueForIntent(Intent intent) {
566         final boolean isFg = (intent.getFlags() & Intent.FLAG_RECEIVER_FOREGROUND) != 0;
567         if (DEBUG_BROADCAST_BACKGROUND) Slog.i(TAG_BROADCAST,
568                 "Broadcast intent " + intent + " on "
569                 + (isFg ? "foreground" : "background") + " queue");
570         return (isFg) ? mFgBroadcastQueue : mBgBroadcastQueue;
571     }
572
573     /**
574      * Activity we have told the window manager to have key focus.
575      */
576     ActivityRecord mFocusedActivity = null;
577
578     /**
579      * User id of the last activity mFocusedActivity was set to.
580      */
581     private int mLastFocusedUserId;
582
583     /**
584      * If non-null, we are tracking the time the user spends in the currently focused app.
585      */
586     private AppTimeTracker mCurAppTimeTracker;
587
588     /**
589      * List of intents that were used to start the most recent tasks.
590      */
591     final RecentTasks mRecentTasks;
592
593     /**
594      * For addAppTask: cached of the last activity component that was added.
595      */
596     ComponentName mLastAddedTaskComponent;
597
598     /**
599      * For addAppTask: cached of the last activity uid that was added.
600      */
601     int mLastAddedTaskUid;
602
603     /**
604      * For addAppTask: cached of the last ActivityInfo that was added.
605      */
606     ActivityInfo mLastAddedTaskActivity;
607
608     /**
609      * List of packages whitelisted by DevicePolicyManager for locktask. Indexed by userId.
610      */
611     SparseArray<String[]> mLockTaskPackages = new SparseArray<>();
612
613     /**
614      * The package name of the DeviceOwner. This package is not permitted to have its data cleared.
615      */
616     String mDeviceOwnerName;
617
618     final UserController mUserController;
619
620     final AppErrors mAppErrors;
621
622     boolean mDoingSetFocusedActivity;
623
624     public boolean canShowErrorDialogs() {
625         return mShowDialogs && !mSleeping && !mShuttingDown;
626     }
627
628     public class PendingAssistExtras extends Binder implements Runnable {
629         public final ActivityRecord activity;
630         public final Bundle extras;
631         public final Intent intent;
632         public final String hint;
633         public final IResultReceiver receiver;
634         public final int userHandle;
635         public boolean haveResult = false;
636         public Bundle result = null;
637         public AssistStructure structure = null;
638         public AssistContent content = null;
639         public PendingAssistExtras(ActivityRecord _activity, Bundle _extras, Intent _intent,
640                 String _hint, IResultReceiver _receiver, int _userHandle) {
641             activity = _activity;
642             extras = _extras;
643             intent = _intent;
644             hint = _hint;
645             receiver = _receiver;
646             userHandle = _userHandle;
647         }
648         @Override
649         public void run() {
650             Slog.w(TAG, "getAssistContextExtras failed: timeout retrieving from " + activity);
651             synchronized (this) {
652                 haveResult = true;
653                 notifyAll();
654             }
655             pendingAssistExtrasTimedOut(this);
656         }
657     }
658
659     final ArrayList<PendingAssistExtras> mPendingAssistExtras
660             = new ArrayList<PendingAssistExtras>();
661
662     /**
663      * Process management.
664      */
665     final ProcessList mProcessList = new ProcessList();
666
667     /**
668      * All of the applications we currently have running organized by name.
669      * The keys are strings of the application package name (as
670      * returned by the package manager), and the keys are ApplicationRecord
671      * objects.
672      */
673     final ProcessMap<ProcessRecord> mProcessNames = new ProcessMap<ProcessRecord>();
674
675     /**
676      * Tracking long-term execution of processes to look for abuse and other
677      * bad app behavior.
678      */
679     final ProcessStatsService mProcessStats;
680
681     /**
682      * The currently running isolated processes.
683      */
684     final SparseArray<ProcessRecord> mIsolatedProcesses = new SparseArray<ProcessRecord>();
685
686     /**
687      * Counter for assigning isolated process uids, to avoid frequently reusing the
688      * same ones.
689      */
690     int mNextIsolatedProcessUid = 0;
691
692     /**
693      * The currently running heavy-weight process, if any.
694      */
695     ProcessRecord mHeavyWeightProcess = null;
696
697     /**
698      * All of the processes we currently have running organized by pid.
699      * The keys are the pid running the application.
700      *
701      * <p>NOTE: This object is protected by its own lock, NOT the global
702      * activity manager lock!
703      */
704     final SparseArray<ProcessRecord> mPidsSelfLocked = new SparseArray<ProcessRecord>();
705
706     /**
707      * All of the processes that have been forced to be foreground.  The key
708      * is the pid of the caller who requested it (we hold a death
709      * link on it).
710      */
711     abstract class ForegroundToken implements IBinder.DeathRecipient {
712         int pid;
713         IBinder token;
714     }
715     final SparseArray<ForegroundToken> mForegroundProcesses = new SparseArray<ForegroundToken>();
716
717     /**
718      * List of records for processes that someone had tried to start before the
719      * system was ready.  We don't start them at that point, but ensure they
720      * are started by the time booting is complete.
721      */
722     final ArrayList<ProcessRecord> mProcessesOnHold = new ArrayList<ProcessRecord>();
723
724     /**
725      * List of persistent applications that are in the process
726      * of being started.
727      */
728     final ArrayList<ProcessRecord> mPersistentStartingProcesses = new ArrayList<ProcessRecord>();
729
730     /**
731      * Processes that are being forcibly torn down.
732      */
733     final ArrayList<ProcessRecord> mRemovedProcesses = new ArrayList<ProcessRecord>();
734
735     /**
736      * List of running applications, sorted by recent usage.
737      * The first entry in the list is the least recently used.
738      */
739     final ArrayList<ProcessRecord> mLruProcesses = new ArrayList<ProcessRecord>();
740
741     /**
742      * Where in mLruProcesses that the processes hosting activities start.
743      */
744     int mLruProcessActivityStart = 0;
745
746     /**
747      * Where in mLruProcesses that the processes hosting services start.
748      * This is after (lower index) than mLruProcessesActivityStart.
749      */
750     int mLruProcessServiceStart = 0;
751
752     /**
753      * List of processes that should gc as soon as things are idle.
754      */
755     final ArrayList<ProcessRecord> mProcessesToGc = new ArrayList<ProcessRecord>();
756
757     /**
758      * Processes we want to collect PSS data from.
759      */
760     final ArrayList<ProcessRecord> mPendingPssProcesses = new ArrayList<ProcessRecord>();
761
762     private boolean mBinderTransactionTrackingEnabled = false;
763
764     /**
765      * Last time we requested PSS data of all processes.
766      */
767     long mLastFullPssTime = SystemClock.uptimeMillis();
768
769     /**
770      * If set, the next time we collect PSS data we should do a full collection
771      * with data from native processes and the kernel.
772      */
773     boolean mFullPssPending = false;
774
775     /**
776      * This is the process holding what we currently consider to be
777      * the "home" activity.
778      */
779     ProcessRecord mHomeProcess;
780
781     /**
782      * This is the process holding the activity the user last visited that
783      * is in a different process from the one they are currently in.
784      */
785     ProcessRecord mPreviousProcess;
786
787     /**
788      * The time at which the previous process was last visible.
789      */
790     long mPreviousProcessVisibleTime;
791
792     /**
793      * Track all uids that have actively running processes.
794      */
795     final SparseArray<UidRecord> mActiveUids = new SparseArray<>();
796
797     /**
798      * This is for verifying the UID report flow.
799      */
800     static final boolean VALIDATE_UID_STATES = true;
801     final SparseArray<UidRecord> mValidateUids = new SparseArray<>();
802
803     /**
804      * Packages that the user has asked to have run in screen size
805      * compatibility mode instead of filling the screen.
806      */
807     final CompatModePackages mCompatModePackages;
808
809     /**
810      * Set of IntentSenderRecord objects that are currently active.
811      */
812     final HashMap<PendingIntentRecord.Key, WeakReference<PendingIntentRecord>> mIntentSenderRecords
813             = new HashMap<PendingIntentRecord.Key, WeakReference<PendingIntentRecord>>();
814
815     /**
816      * Fingerprints (hashCode()) of stack traces that we've
817      * already logged DropBox entries for.  Guarded by itself.  If
818      * something (rogue user app) forces this over
819      * MAX_DUP_SUPPRESSED_STACKS entries, the contents are cleared.
820      */
821     private final HashSet<Integer> mAlreadyLoggedViolatedStacks = new HashSet<Integer>();
822     private static final int MAX_DUP_SUPPRESSED_STACKS = 5000;
823
824     /**
825      * Strict Mode background batched logging state.
826      *
827      * The string buffer is guarded by itself, and its lock is also
828      * used to determine if another batched write is already
829      * in-flight.
830      */
831     private final StringBuilder mStrictModeBuffer = new StringBuilder();
832
833     /**
834      * Keeps track of all IIntentReceivers that have been registered for broadcasts.
835      * Hash keys are the receiver IBinder, hash value is a ReceiverList.
836      */
837     final HashMap<IBinder, ReceiverList> mRegisteredReceivers = new HashMap<>();
838
839     /**
840      * Resolver for broadcast intents to registered receivers.
841      * Holds BroadcastFilter (subclass of IntentFilter).
842      */
843     final IntentResolver<BroadcastFilter, BroadcastFilter> mReceiverResolver
844             = new IntentResolver<BroadcastFilter, BroadcastFilter>() {
845         @Override
846         protected boolean allowFilterResult(
847                 BroadcastFilter filter, List<BroadcastFilter> dest) {
848             IBinder target = filter.receiverList.receiver.asBinder();
849             for (int i = dest.size() - 1; i >= 0; i--) {
850                 if (dest.get(i).receiverList.receiver.asBinder() == target) {
851                     return false;
852                 }
853             }
854             return true;
855         }
856
857         @Override
858         protected BroadcastFilter newResult(BroadcastFilter filter, int match, int userId) {
859             if (userId == UserHandle.USER_ALL || filter.owningUserId == UserHandle.USER_ALL
860                     || userId == filter.owningUserId) {
861                 return super.newResult(filter, match, userId);
862             }
863             return null;
864         }
865
866         @Override
867         protected BroadcastFilter[] newArray(int size) {
868             return new BroadcastFilter[size];
869         }
870
871         @Override
872         protected boolean isPackageForFilter(String packageName, BroadcastFilter filter) {
873             return packageName.equals(filter.packageName);
874         }
875     };
876
877     /**
878      * State of all active sticky broadcasts per user.  Keys are the action of the
879      * sticky Intent, values are an ArrayList of all broadcasted intents with
880      * that action (which should usually be one).  The SparseArray is keyed
881      * by the user ID the sticky is for, and can include UserHandle.USER_ALL
882      * for stickies that are sent to all users.
883      */
884     final SparseArray<ArrayMap<String, ArrayList<Intent>>> mStickyBroadcasts =
885             new SparseArray<ArrayMap<String, ArrayList<Intent>>>();
886
887     final ActiveServices mServices;
888
889     final static class Association {
890         final int mSourceUid;
891         final String mSourceProcess;
892         final int mTargetUid;
893         final ComponentName mTargetComponent;
894         final String mTargetProcess;
895
896         int mCount;
897         long mTime;
898
899         int mNesting;
900         long mStartTime;
901
902         Association(int sourceUid, String sourceProcess, int targetUid,
903                 ComponentName targetComponent, String targetProcess) {
904             mSourceUid = sourceUid;
905             mSourceProcess = sourceProcess;
906             mTargetUid = targetUid;
907             mTargetComponent = targetComponent;
908             mTargetProcess = targetProcess;
909         }
910     }
911
912     /**
913      * When service association tracking is enabled, this is all of the associations we
914      * have seen.  Mapping is target uid -> target component -> source uid -> source process name
915      * -> association data.
916      */
917     final SparseArray<ArrayMap<ComponentName, SparseArray<ArrayMap<String, Association>>>>
918             mAssociations = new SparseArray<>();
919     boolean mTrackingAssociations;
920
921     /**
922      * Backup/restore process management
923      */
924     String mBackupAppName = null;
925     BackupRecord mBackupTarget = null;
926
927     final ProviderMap mProviderMap;
928
929     /**
930      * List of content providers who have clients waiting for them.  The
931      * application is currently being launched and the provider will be
932      * removed from this list once it is published.
933      */
934     final ArrayList<ContentProviderRecord> mLaunchingProviders
935             = new ArrayList<ContentProviderRecord>();
936
937     /**
938      * File storing persisted {@link #mGrantedUriPermissions}.
939      */
940     private final AtomicFile mGrantFile;
941
942     /** XML constants used in {@link #mGrantFile} */
943     private static final String TAG_URI_GRANTS = "uri-grants";
944     private static final String TAG_URI_GRANT = "uri-grant";
945     private static final String ATTR_USER_HANDLE = "userHandle";
946     private static final String ATTR_SOURCE_USER_ID = "sourceUserId";
947     private static final String ATTR_TARGET_USER_ID = "targetUserId";
948     private static final String ATTR_SOURCE_PKG = "sourcePkg";
949     private static final String ATTR_TARGET_PKG = "targetPkg";
950     private static final String ATTR_URI = "uri";
951     private static final String ATTR_MODE_FLAGS = "modeFlags";
952     private static final String ATTR_CREATED_TIME = "createdTime";
953     private static final String ATTR_PREFIX = "prefix";
954
955     /**
956      * Global set of specific {@link Uri} permissions that have been granted.
957      * This optimized lookup structure maps from {@link UriPermission#targetUid}
958      * to {@link UriPermission#uri} to {@link UriPermission}.
959      */
960     @GuardedBy("this")
961     private final SparseArray<ArrayMap<GrantUri, UriPermission>>
962             mGrantedUriPermissions = new SparseArray<ArrayMap<GrantUri, UriPermission>>();
963
964     public static class GrantUri {
965         public final int sourceUserId;
966         public final Uri uri;
967         public boolean prefix;
968
969         public GrantUri(int sourceUserId, Uri uri, boolean prefix) {
970             this.sourceUserId = sourceUserId;
971             this.uri = uri;
972             this.prefix = prefix;
973         }
974
975         @Override
976         public int hashCode() {
977             int hashCode = 1;
978             hashCode = 31 * hashCode + sourceUserId;
979             hashCode = 31 * hashCode + uri.hashCode();
980             hashCode = 31 * hashCode + (prefix ? 1231 : 1237);
981             return hashCode;
982         }
983
984         @Override
985         public boolean equals(Object o) {
986             if (o instanceof GrantUri) {
987                 GrantUri other = (GrantUri) o;
988                 return uri.equals(other.uri) && (sourceUserId == other.sourceUserId)
989                         && prefix == other.prefix;
990             }
991             return false;
992         }
993
994         @Override
995         public String toString() {
996             String result = Integer.toString(sourceUserId) + " @ " + uri.toString();
997             if (prefix) result += " [prefix]";
998             return result;
999         }
1000
1001         public String toSafeString() {
1002             String result = Integer.toString(sourceUserId) + " @ " + uri.toSafeString();
1003             if (prefix) result += " [prefix]";
1004             return result;
1005         }
1006
1007         public static GrantUri resolve(int defaultSourceUserHandle, Uri uri) {
1008             return new GrantUri(ContentProvider.getUserIdFromUri(uri, defaultSourceUserHandle),
1009                     ContentProvider.getUriWithoutUserId(uri), false);
1010         }
1011     }
1012
1013     CoreSettingsObserver mCoreSettingsObserver;
1014
1015     FontScaleSettingObserver mFontScaleSettingObserver;
1016
1017     private final class FontScaleSettingObserver extends ContentObserver {
1018         private final Uri mFontScaleUri = Settings.System.getUriFor(FONT_SCALE);
1019
1020         public FontScaleSettingObserver() {
1021             super(mHandler);
1022             ContentResolver resolver = mContext.getContentResolver();
1023             resolver.registerContentObserver(mFontScaleUri, false, this, UserHandle.USER_ALL);
1024         }
1025
1026         @Override
1027         public void onChange(boolean selfChange, Uri uri) {
1028             if (mFontScaleUri.equals(uri)) {
1029                 updateFontScaleIfNeeded();
1030             }
1031         }
1032     }
1033
1034     /**
1035      * Thread-local storage used to carry caller permissions over through
1036      * indirect content-provider access.
1037      */
1038     private class Identity {
1039         public final IBinder token;
1040         public final int pid;
1041         public final int uid;
1042
1043         Identity(IBinder _token, int _pid, int _uid) {
1044             token = _token;
1045             pid = _pid;
1046             uid = _uid;
1047         }
1048     }
1049
1050     private static final ThreadLocal<Identity> sCallerIdentity = new ThreadLocal<Identity>();
1051
1052     /**
1053      * All information we have collected about the runtime performance of
1054      * any user id that can impact battery performance.
1055      */
1056     final BatteryStatsService mBatteryStatsService;
1057
1058     /**
1059      * Information about component usage
1060      */
1061     UsageStatsManagerInternal mUsageStatsService;
1062
1063     /**
1064      * Access to DeviceIdleController service.
1065      */
1066     DeviceIdleController.LocalService mLocalDeviceIdleController;
1067
1068     /**
1069      * Information about and control over application operations
1070      */
1071     final AppOpsService mAppOpsService;
1072
1073     /**
1074      * Current configuration information.  HistoryRecord objects are given
1075      * a reference to this object to indicate which configuration they are
1076      * currently running in, so this object must be kept immutable.
1077      */
1078     Configuration mConfiguration = new Configuration();
1079
1080     /**
1081      * Current sequencing integer of the configuration, for skipping old
1082      * configurations.
1083      */
1084     int mConfigurationSeq = 0;
1085
1086     boolean mSuppressResizeConfigChanges = false;
1087
1088     /**
1089      * Hardware-reported OpenGLES version.
1090      */
1091     final int GL_ES_VERSION;
1092
1093     /**
1094      * List of initialization arguments to pass to all processes when binding applications to them.
1095      * For example, references to the commonly used services.
1096      */
1097     HashMap<String, IBinder> mAppBindArgs;
1098
1099     /**
1100      * Temporary to avoid allocations.  Protected by main lock.
1101      */
1102     final StringBuilder mStringBuilder = new StringBuilder(256);
1103
1104     /**
1105      * Used to control how we initialize the service.
1106      */
1107     ComponentName mTopComponent;
1108     String mTopAction = Intent.ACTION_MAIN;
1109     String mTopData;
1110     boolean mProcessesReady = false;
1111     boolean mSystemReady = false;
1112     boolean mBooting = false;
1113     boolean mCallFinishBooting = false;
1114     boolean mBootAnimationComplete = false;
1115     boolean mWaitingUpdate = false;
1116     boolean mDidUpdate = false;
1117     boolean mOnBattery = false;
1118     boolean mLaunchWarningShown = false;
1119
1120     Context mContext;
1121
1122     int mFactoryTest;
1123
1124     boolean mCheckedForSetup;
1125
1126     /**
1127      * The time at which we will allow normal application switches again,
1128      * after a call to {@link #stopAppSwitches()}.
1129      */
1130     long mAppSwitchesAllowedTime;
1131
1132     /**
1133      * This is set to true after the first switch after mAppSwitchesAllowedTime
1134      * is set; any switches after that will clear the time.
1135      */
1136     boolean mDidAppSwitch;
1137
1138     /**
1139      * Last time (in realtime) at which we checked for power usage.
1140      */
1141     long mLastPowerCheckRealtime;
1142
1143     /**
1144      * Last time (in uptime) at which we checked for power usage.
1145      */
1146     long mLastPowerCheckUptime;
1147
1148     /**
1149      * Set while we are wanting to sleep, to prevent any
1150      * activities from being started/resumed.
1151      */
1152     private boolean mSleeping = false;
1153
1154     /**
1155      * The process state used for processes that are running the top activities.
1156      * This changes between TOP and TOP_SLEEPING to following mSleeping.
1157      */
1158     int mTopProcessState = ActivityManager.PROCESS_STATE_TOP;
1159
1160     /**
1161      * Set while we are running a voice interaction.  This overrides
1162      * sleeping while it is active.
1163      */
1164     private IVoiceInteractionSession mRunningVoice;
1165
1166     /**
1167      * For some direct access we need to power manager.
1168      */
1169     PowerManagerInternal mLocalPowerManager;
1170
1171     /**
1172      * We want to hold a wake lock while running a voice interaction session, since
1173      * this may happen with the screen off and we need to keep the CPU running to
1174      * be able to continue to interact with the user.
1175      */
1176     PowerManager.WakeLock mVoiceWakeLock;
1177
1178     /**
1179      * State of external calls telling us if the device is awake or asleep.
1180      */
1181     private int mWakefulness = PowerManagerInternal.WAKEFULNESS_AWAKE;
1182
1183     /**
1184      * A list of tokens that cause the top activity to be put to sleep.
1185      * They are used by components that may hide and block interaction with underlying
1186      * activities.
1187      */
1188     final ArrayList<SleepToken> mSleepTokens = new ArrayList<SleepToken>();
1189
1190     static final int LOCK_SCREEN_HIDDEN = 0;
1191     static final int LOCK_SCREEN_LEAVING = 1;
1192     static final int LOCK_SCREEN_SHOWN = 2;
1193     /**
1194      * State of external call telling us if the lock screen is shown.
1195      */
1196     int mLockScreenShown = LOCK_SCREEN_HIDDEN;
1197
1198     /**
1199      * Set if we are shutting down the system, similar to sleeping.
1200      */
1201     boolean mShuttingDown = false;
1202
1203     /**
1204      * Current sequence id for oom_adj computation traversal.
1205      */
1206     int mAdjSeq = 0;
1207
1208     /**
1209      * Current sequence id for process LRU updating.
1210      */
1211     int mLruSeq = 0;
1212
1213     /**
1214      * Keep track of the non-cached/empty process we last found, to help
1215      * determine how to distribute cached/empty processes next time.
1216      */
1217     int mNumNonCachedProcs = 0;
1218
1219     /**
1220      * Keep track of the number of cached hidden procs, to balance oom adj
1221      * distribution between those and empty procs.
1222      */
1223     int mNumCachedHiddenProcs = 0;
1224
1225     /**
1226      * Keep track of the number of service processes we last found, to
1227      * determine on the next iteration which should be B services.
1228      */
1229     int mNumServiceProcs = 0;
1230     int mNewNumAServiceProcs = 0;
1231     int mNewNumServiceProcs = 0;
1232
1233     /**
1234      * Allow the current computed overall memory level of the system to go down?
1235      * This is set to false when we are killing processes for reasons other than
1236      * memory management, so that the now smaller process list will not be taken as
1237      * an indication that memory is tighter.
1238      */
1239     boolean mAllowLowerMemLevel = false;
1240
1241     /**
1242      * The last computed memory level, for holding when we are in a state that
1243      * processes are going away for other reasons.
1244      */
1245     int mLastMemoryLevel = ProcessStats.ADJ_MEM_FACTOR_NORMAL;
1246
1247     /**
1248      * The last total number of process we have, to determine if changes actually look
1249      * like a shrinking number of process due to lower RAM.
1250      */
1251     int mLastNumProcesses;
1252
1253     /**
1254      * The uptime of the last time we performed idle maintenance.
1255      */
1256     long mLastIdleTime = SystemClock.uptimeMillis();
1257
1258     /**
1259      * Total time spent with RAM that has been added in the past since the last idle time.
1260      */
1261     long mLowRamTimeSinceLastIdle = 0;
1262
1263     /**
1264      * If RAM is currently low, when that horrible situation started.
1265      */
1266     long mLowRamStartTime = 0;
1267
1268     /**
1269      * For reporting to battery stats the current top application.
1270      */
1271     private String mCurResumedPackage = null;
1272     private int mCurResumedUid = -1;
1273
1274     /**
1275      * For reporting to battery stats the apps currently running foreground
1276      * service.  The ProcessMap is package/uid tuples; each of these contain
1277      * an array of the currently foreground processes.
1278      */
1279     final ProcessMap<ArrayList<ProcessRecord>> mForegroundPackages
1280             = new ProcessMap<ArrayList<ProcessRecord>>();
1281
1282     /**
1283      * This is set if we had to do a delayed dexopt of an app before launching
1284      * it, to increase the ANR timeouts in that case.
1285      */
1286     boolean mDidDexOpt;
1287
1288     /**
1289      * Set if the systemServer made a call to enterSafeMode.
1290      */
1291     boolean mSafeMode;
1292
1293     /**
1294      * If true, we are running under a test environment so will sample PSS from processes
1295      * much more rapidly to try to collect better data when the tests are rapidly
1296      * running through apps.
1297      */
1298     boolean mTestPssMode = false;
1299
1300     String mDebugApp = null;
1301     boolean mWaitForDebugger = false;
1302     boolean mDebugTransient = false;
1303     String mOrigDebugApp = null;
1304     boolean mOrigWaitForDebugger = false;
1305     boolean mAlwaysFinishActivities = false;
1306     boolean mLenientBackgroundCheck = false;
1307     boolean mForceResizableActivities;
1308     boolean mSupportsMultiWindow;
1309     boolean mSupportsFreeformWindowManagement;
1310     boolean mSupportsPictureInPicture;
1311     Rect mDefaultPinnedStackBounds;
1312     IActivityController mController = null;
1313     boolean mControllerIsAMonkey = false;
1314     String mProfileApp = null;
1315     ProcessRecord mProfileProc = null;
1316     String mProfileFile;
1317     ParcelFileDescriptor mProfileFd;
1318     int mSamplingInterval = 0;
1319     boolean mAutoStopProfiler = false;
1320     int mProfileType = 0;
1321     final ProcessMap<Pair<Long, String>> mMemWatchProcesses = new ProcessMap<>();
1322     String mMemWatchDumpProcName;
1323     String mMemWatchDumpFile;
1324     int mMemWatchDumpPid;
1325     int mMemWatchDumpUid;
1326     String mTrackAllocationApp = null;
1327     String mNativeDebuggingApp = null;
1328
1329     final long[] mTmpLong = new long[2];
1330
1331     static final class ProcessChangeItem {
1332         static final int CHANGE_ACTIVITIES = 1<<0;
1333         static final int CHANGE_PROCESS_STATE = 1<<1;
1334         int changes;
1335         int uid;
1336         int pid;
1337         int processState;
1338         boolean foregroundActivities;
1339     }
1340
1341     final RemoteCallbackList<IProcessObserver> mProcessObservers = new RemoteCallbackList<>();
1342     ProcessChangeItem[] mActiveProcessChanges = new ProcessChangeItem[5];
1343
1344     final ArrayList<ProcessChangeItem> mPendingProcessChanges = new ArrayList<>();
1345     final ArrayList<ProcessChangeItem> mAvailProcessChanges = new ArrayList<>();
1346
1347     final RemoteCallbackList<IUidObserver> mUidObservers = new RemoteCallbackList<>();
1348     UidRecord.ChangeItem[] mActiveUidChanges = new UidRecord.ChangeItem[5];
1349
1350     final ArrayList<UidRecord.ChangeItem> mPendingUidChanges = new ArrayList<>();
1351     final ArrayList<UidRecord.ChangeItem> mAvailUidChanges = new ArrayList<>();
1352
1353     /**
1354      * Runtime CPU use collection thread.  This object's lock is used to
1355      * perform synchronization with the thread (notifying it to run).
1356      */
1357     final Thread mProcessCpuThread;
1358
1359     /**
1360      * Used to collect per-process CPU use for ANRs, battery stats, etc.
1361      * Must acquire this object's lock when accessing it.
1362      * NOTE: this lock will be held while doing long operations (trawling
1363      * through all processes in /proc), so it should never be acquired by
1364      * any critical paths such as when holding the main activity manager lock.
1365      */
1366     final ProcessCpuTracker mProcessCpuTracker = new ProcessCpuTracker(
1367             MONITOR_THREAD_CPU_USAGE);
1368     final AtomicLong mLastCpuTime = new AtomicLong(0);
1369     final AtomicBoolean mProcessCpuMutexFree = new AtomicBoolean(true);
1370
1371     long mLastWriteTime = 0;
1372
1373     /**
1374      * Used to retain an update lock when the foreground activity is in
1375      * immersive mode.
1376      */
1377     final UpdateLock mUpdateLock = new UpdateLock("immersive");
1378
1379     /**
1380      * Set to true after the system has finished booting.
1381      */
1382     boolean mBooted = false;
1383
1384     int mProcessLimit = ProcessList.MAX_CACHED_APPS;
1385     int mProcessLimitOverride = -1;
1386
1387     WindowManagerService mWindowManager;
1388     final ActivityThread mSystemThread;
1389
1390     private final class AppDeathRecipient implements IBinder.DeathRecipient {
1391         final ProcessRecord mApp;
1392         final int mPid;
1393         final IApplicationThread mAppThread;
1394
1395         AppDeathRecipient(ProcessRecord app, int pid,
1396                 IApplicationThread thread) {
1397             if (DEBUG_ALL) Slog.v(
1398                 TAG, "New death recipient " + this
1399                 + " for thread " + thread.asBinder());
1400             mApp = app;
1401             mPid = pid;
1402             mAppThread = thread;
1403         }
1404
1405         @Override
1406         public void binderDied() {
1407             if (DEBUG_ALL) Slog.v(
1408                 TAG, "Death received in " + this
1409                 + " for thread " + mAppThread.asBinder());
1410             synchronized(ActivityManagerService.this) {
1411                 appDiedLocked(mApp, mPid, mAppThread, true);
1412             }
1413         }
1414     }
1415
1416     static final int SHOW_ERROR_UI_MSG = 1;
1417     static final int SHOW_NOT_RESPONDING_UI_MSG = 2;
1418     static final int SHOW_FACTORY_ERROR_UI_MSG = 3;
1419     static final int UPDATE_CONFIGURATION_MSG = 4;
1420     static final int GC_BACKGROUND_PROCESSES_MSG = 5;
1421     static final int WAIT_FOR_DEBUGGER_UI_MSG = 6;
1422     static final int SERVICE_TIMEOUT_MSG = 12;
1423     static final int UPDATE_TIME_ZONE = 13;
1424     static final int SHOW_UID_ERROR_UI_MSG = 14;
1425     static final int SHOW_FINGERPRINT_ERROR_UI_MSG = 15;
1426     static final int PROC_START_TIMEOUT_MSG = 20;
1427     static final int DO_PENDING_ACTIVITY_LAUNCHES_MSG = 21;
1428     static final int KILL_APPLICATION_MSG = 22;
1429     static final int FINALIZE_PENDING_INTENT_MSG = 23;
1430     static final int POST_HEAVY_NOTIFICATION_MSG = 24;
1431     static final int CANCEL_HEAVY_NOTIFICATION_MSG = 25;
1432     static final int SHOW_STRICT_MODE_VIOLATION_UI_MSG = 26;
1433     static final int CHECK_EXCESSIVE_WAKE_LOCKS_MSG = 27;
1434     static final int CLEAR_DNS_CACHE_MSG = 28;
1435     static final int UPDATE_HTTP_PROXY_MSG = 29;
1436     static final int SHOW_COMPAT_MODE_DIALOG_UI_MSG = 30;
1437     static final int DISPATCH_PROCESSES_CHANGED_UI_MSG = 31;
1438     static final int DISPATCH_PROCESS_DIED_UI_MSG = 32;
1439     static final int REPORT_MEM_USAGE_MSG = 33;
1440     static final int REPORT_USER_SWITCH_MSG = 34;
1441     static final int CONTINUE_USER_SWITCH_MSG = 35;
1442     static final int USER_SWITCH_TIMEOUT_MSG = 36;
1443     static final int IMMERSIVE_MODE_LOCK_MSG = 37;
1444     static final int PERSIST_URI_GRANTS_MSG = 38;
1445     static final int REQUEST_ALL_PSS_MSG = 39;
1446     static final int START_PROFILES_MSG = 40;
1447     static final int UPDATE_TIME = 41;
1448     static final int SYSTEM_USER_START_MSG = 42;
1449     static final int SYSTEM_USER_CURRENT_MSG = 43;
1450     static final int ENTER_ANIMATION_COMPLETE_MSG = 44;
1451     static final int FINISH_BOOTING_MSG = 45;
1452     static final int START_USER_SWITCH_UI_MSG = 46;
1453     static final int SEND_LOCALE_TO_MOUNT_DAEMON_MSG = 47;
1454     static final int DISMISS_DIALOG_UI_MSG = 48;
1455     static final int NOTIFY_TASK_STACK_CHANGE_LISTENERS_MSG = 49;
1456     static final int NOTIFY_CLEARTEXT_NETWORK_MSG = 50;
1457     static final int POST_DUMP_HEAP_NOTIFICATION_MSG = 51;
1458     static final int DELETE_DUMPHEAP_MSG = 52;
1459     static final int FOREGROUND_PROFILE_CHANGED_MSG = 53;
1460     static final int DISPATCH_UIDS_CHANGED_UI_MSG = 54;
1461     static final int REPORT_TIME_TRACKER_MSG = 55;
1462     static final int REPORT_USER_SWITCH_COMPLETE_MSG = 56;
1463     static final int SHUTDOWN_UI_AUTOMATION_CONNECTION_MSG = 57;
1464     static final int APP_BOOST_DEACTIVATE_MSG = 58;
1465     static final int CONTENT_PROVIDER_PUBLISH_TIMEOUT_MSG = 59;
1466     static final int IDLE_UIDS_MSG = 60;
1467     static final int SYSTEM_USER_UNLOCK_MSG = 61;
1468     static final int LOG_STACK_STATE = 62;
1469     static final int VR_MODE_CHANGE_MSG = 63;
1470     static final int NOTIFY_ACTIVITY_PINNED_LISTENERS_MSG = 64;
1471     static final int NOTIFY_PINNED_ACTIVITY_RESTART_ATTEMPT_LISTENERS_MSG = 65;
1472     static final int NOTIFY_PINNED_STACK_ANIMATION_ENDED_LISTENERS_MSG = 66;
1473
1474     static final int FIRST_ACTIVITY_STACK_MSG = 100;
1475     static final int FIRST_BROADCAST_QUEUE_MSG = 200;
1476     static final int FIRST_COMPAT_MODE_MSG = 300;
1477     static final int FIRST_SUPERVISOR_STACK_MSG = 100;
1478
1479     CompatModeDialog mCompatModeDialog;
1480     long mLastMemUsageReportTime = 0;
1481
1482     /**
1483      * Flag whether the current user is a "monkey", i.e. whether
1484      * the UI is driven by a UI automation tool.
1485      */
1486     private boolean mUserIsMonkey;
1487
1488     /** Flag whether the device has a Recents UI */
1489     boolean mHasRecents;
1490
1491     /** The dimensions of the thumbnails in the Recents UI. */
1492     int mThumbnailWidth;
1493     int mThumbnailHeight;
1494
1495     final ServiceThread mHandlerThread;
1496     final MainHandler mHandler;
1497     final UiHandler mUiHandler;
1498     final ProcessStartLogger mProcessStartLogger;
1499
1500     PackageManagerInternal mPackageManagerInt;
1501
1502     final class UiHandler extends Handler {
1503         public UiHandler() {
1504             super(com.android.server.UiThread.get().getLooper(), null, true);
1505         }
1506
1507         @Override
1508         public void handleMessage(Message msg) {
1509             switch (msg.what) {
1510             case SHOW_ERROR_UI_MSG: {
1511                 mAppErrors.handleShowAppErrorUi(msg);
1512                 ensureBootCompleted();
1513             } break;
1514             case SHOW_NOT_RESPONDING_UI_MSG: {
1515                 mAppErrors.handleShowAnrUi(msg);
1516                 ensureBootCompleted();
1517             } break;
1518             case SHOW_STRICT_MODE_VIOLATION_UI_MSG: {
1519                 HashMap<String, Object> data = (HashMap<String, Object>) msg.obj;
1520                 synchronized (ActivityManagerService.this) {
1521                     ProcessRecord proc = (ProcessRecord) data.get("app");
1522                     if (proc == null) {
1523                         Slog.e(TAG, "App not found when showing strict mode dialog.");
1524                         break;
1525                     }
1526                     if (proc.crashDialog != null) {
1527                         Slog.e(TAG, "App already has strict mode dialog: " + proc);
1528                         return;
1529                     }
1530                     AppErrorResult res = (AppErrorResult) data.get("result");
1531                     if (mShowDialogs && !mSleeping && !mShuttingDown) {
1532                         Dialog d = new StrictModeViolationDialog(mContext,
1533                                 ActivityManagerService.this, res, proc);
1534                         d.show();
1535                         proc.crashDialog = d;
1536                     } else {
1537                         // The device is asleep, so just pretend that the user
1538                         // saw a crash dialog and hit "force quit".
1539                         res.set(0);
1540                     }
1541                 }
1542                 ensureBootCompleted();
1543             } break;
1544             case SHOW_FACTORY_ERROR_UI_MSG: {
1545                 Dialog d = new FactoryErrorDialog(
1546                     mContext, msg.getData().getCharSequence("msg"));
1547                 d.show();
1548                 ensureBootCompleted();
1549             } break;
1550             case WAIT_FOR_DEBUGGER_UI_MSG: {
1551                 synchronized (ActivityManagerService.this) {
1552                     ProcessRecord app = (ProcessRecord)msg.obj;
1553                     if (msg.arg1 != 0) {
1554                         if (!app.waitedForDebugger) {
1555                             Dialog d = new AppWaitingForDebuggerDialog(
1556                                     ActivityManagerService.this,
1557                                     mContext, app);
1558                             app.waitDialog = d;
1559                             app.waitedForDebugger = true;
1560                             d.show();
1561                         }
1562                     } else {
1563                         if (app.waitDialog != null) {
1564                             app.waitDialog.dismiss();
1565                             app.waitDialog = null;
1566                         }
1567                     }
1568                 }
1569             } break;
1570             case SHOW_UID_ERROR_UI_MSG: {
1571                 if (mShowDialogs) {
1572                     AlertDialog d = new BaseErrorDialog(mContext);
1573                     d.getWindow().setType(WindowManager.LayoutParams.TYPE_SYSTEM_ERROR);
1574                     d.setCancelable(false);
1575                     d.setTitle(mContext.getText(R.string.android_system_label));
1576                     d.setMessage(mContext.getText(R.string.system_error_wipe_data));
1577                     d.setButton(DialogInterface.BUTTON_POSITIVE, mContext.getText(R.string.ok),
1578                             obtainMessage(DISMISS_DIALOG_UI_MSG, d));
1579                     d.show();
1580                 }
1581             } break;
1582             case SHOW_FINGERPRINT_ERROR_UI_MSG: {
1583                 if (mShowDialogs) {
1584                     AlertDialog d = new BaseErrorDialog(mContext);
1585                     d.getWindow().setType(WindowManager.LayoutParams.TYPE_SYSTEM_ERROR);
1586                     d.setCancelable(false);
1587                     d.setTitle(mContext.getText(R.string.android_system_label));
1588                     d.setMessage(mContext.getText(R.string.system_error_manufacturer));
1589                     d.setButton(DialogInterface.BUTTON_POSITIVE, mContext.getText(R.string.ok),
1590                             obtainMessage(DISMISS_DIALOG_UI_MSG, d));
1591                     d.show();
1592                 }
1593             } break;
1594             case SHOW_COMPAT_MODE_DIALOG_UI_MSG: {
1595                 synchronized (ActivityManagerService.this) {
1596                     ActivityRecord ar = (ActivityRecord) msg.obj;
1597                     if (mCompatModeDialog != null) {
1598                         if (mCompatModeDialog.mAppInfo.packageName.equals(
1599                                 ar.info.applicationInfo.packageName)) {
1600                             return;
1601                         }
1602                         mCompatModeDialog.dismiss();
1603                         mCompatModeDialog = null;
1604                     }
1605                     if (ar != null && false) {
1606                         if (mCompatModePackages.getPackageAskCompatModeLocked(
1607                                 ar.packageName)) {
1608                             int mode = mCompatModePackages.computeCompatModeLocked(
1609                                     ar.info.applicationInfo);
1610                             if (mode == ActivityManager.COMPAT_MODE_DISABLED
1611                                     || mode == ActivityManager.COMPAT_MODE_ENABLED) {
1612                                 mCompatModeDialog = new CompatModeDialog(
1613                                         ActivityManagerService.this, mContext,
1614                                         ar.info.applicationInfo);
1615                                 mCompatModeDialog.show();
1616                             }
1617                         }
1618                     }
1619                 }
1620                 break;
1621             }
1622             case START_USER_SWITCH_UI_MSG: {
1623                 mUserController.showUserSwitchDialog((Pair<UserInfo, UserInfo>) msg.obj);
1624                 break;
1625             }
1626             case DISMISS_DIALOG_UI_MSG: {
1627                 final Dialog d = (Dialog) msg.obj;
1628                 d.dismiss();
1629                 break;
1630             }
1631             case DISPATCH_PROCESSES_CHANGED_UI_MSG: {
1632                 dispatchProcessesChanged();
1633                 break;
1634             }
1635             case DISPATCH_PROCESS_DIED_UI_MSG: {
1636                 final int pid = msg.arg1;
1637                 final int uid = msg.arg2;
1638                 dispatchProcessDied(pid, uid);
1639                 break;
1640             }
1641             case DISPATCH_UIDS_CHANGED_UI_MSG: {
1642                 dispatchUidsChanged();
1643             } break;
1644             }
1645         }
1646     }
1647
1648     final class MainHandler extends Handler {
1649         public MainHandler(Looper looper) {
1650             super(looper, null, true);
1651         }
1652
1653         @Override
1654         public void handleMessage(Message msg) {
1655             switch (msg.what) {
1656             case UPDATE_CONFIGURATION_MSG: {
1657                 final ContentResolver resolver = mContext.getContentResolver();
1658                 Settings.System.putConfigurationForUser(resolver, (Configuration) msg.obj,
1659                         msg.arg1);
1660             } break;
1661             case GC_BACKGROUND_PROCESSES_MSG: {
1662                 synchronized (ActivityManagerService.this) {
1663                     performAppGcsIfAppropriateLocked();
1664                 }
1665             } break;
1666             case SERVICE_TIMEOUT_MSG: {
1667                 if (mDidDexOpt) {
1668                     mDidDexOpt = false;
1669                     Message nmsg = mHandler.obtainMessage(SERVICE_TIMEOUT_MSG);
1670                     nmsg.obj = msg.obj;
1671                     mHandler.sendMessageDelayed(nmsg, ActiveServices.SERVICE_TIMEOUT);
1672                     return;
1673                 }
1674                 mServices.serviceTimeout((ProcessRecord)msg.obj);
1675             } break;
1676             case UPDATE_TIME_ZONE: {
1677                 synchronized (ActivityManagerService.this) {
1678                     for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) {
1679                         ProcessRecord r = mLruProcesses.get(i);
1680                         if (r.thread != null) {
1681                             try {
1682                                 r.thread.updateTimeZone();
1683                             } catch (RemoteException ex) {
1684                                 Slog.w(TAG, "Failed to update time zone for: " + r.info.processName);
1685                             }
1686                         }
1687                     }
1688                 }
1689             } break;
1690             case CLEAR_DNS_CACHE_MSG: {
1691                 synchronized (ActivityManagerService.this) {
1692                     for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) {
1693                         ProcessRecord r = mLruProcesses.get(i);
1694                         if (r.thread != null) {
1695                             try {
1696                                 r.thread.clearDnsCache();
1697                             } catch (RemoteException ex) {
1698                                 Slog.w(TAG, "Failed to clear dns cache for: " + r.info.processName);
1699                             }
1700                         }
1701                     }
1702                 }
1703             } break;
1704             case UPDATE_HTTP_PROXY_MSG: {
1705                 ProxyInfo proxy = (ProxyInfo)msg.obj;
1706                 String host = "";
1707                 String port = "";
1708                 String exclList = "";
1709                 Uri pacFileUrl = Uri.EMPTY;
1710                 if (proxy != null) {
1711                     host = proxy.getHost();
1712                     port = Integer.toString(proxy.getPort());
1713                     exclList = proxy.getExclusionListAsString();
1714                     pacFileUrl = proxy.getPacFileUrl();
1715                 }
1716                 synchronized (ActivityManagerService.this) {
1717                     for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) {
1718                         ProcessRecord r = mLruProcesses.get(i);
1719                         if (r.thread != null) {
1720                             try {
1721                                 r.thread.setHttpProxy(host, port, exclList, pacFileUrl);
1722                             } catch (RemoteException ex) {
1723                                 Slog.w(TAG, "Failed to update http proxy for: " +
1724                                         r.info.processName);
1725                             }
1726                         }
1727                     }
1728                 }
1729             } break;
1730             case PROC_START_TIMEOUT_MSG: {
1731                 if (mDidDexOpt) {
1732                     mDidDexOpt = false;
1733                     Message nmsg = mHandler.obtainMessage(PROC_START_TIMEOUT_MSG);
1734                     nmsg.obj = msg.obj;
1735                     mHandler.sendMessageDelayed(nmsg, PROC_START_TIMEOUT);
1736                     return;
1737                 }
1738                 ProcessRecord app = (ProcessRecord)msg.obj;
1739                 synchronized (ActivityManagerService.this) {
1740                     processStartTimedOutLocked(app);
1741                 }
1742             } break;
1743             case CONTENT_PROVIDER_PUBLISH_TIMEOUT_MSG: {
1744                 ProcessRecord app = (ProcessRecord)msg.obj;
1745                 synchronized (ActivityManagerService.this) {
1746                     processContentProviderPublishTimedOutLocked(app);
1747                 }
1748             } break;
1749             case DO_PENDING_ACTIVITY_LAUNCHES_MSG: {
1750                 synchronized (ActivityManagerService.this) {
1751                     mActivityStarter.doPendingActivityLaunchesLocked(true);
1752                 }
1753             } break;
1754             case KILL_APPLICATION_MSG: {
1755                 synchronized (ActivityManagerService.this) {
1756                     int appid = msg.arg1;
1757                     boolean restart = (msg.arg2 == 1);
1758                     Bundle bundle = (Bundle)msg.obj;
1759                     String pkg = bundle.getString("pkg");
1760                     String reason = bundle.getString("reason");
1761                     forceStopPackageLocked(pkg, appid, restart, false, true, false,
1762                             false, UserHandle.USER_ALL, reason);
1763                 }
1764             } break;
1765             case FINALIZE_PENDING_INTENT_MSG: {
1766                 ((PendingIntentRecord)msg.obj).completeFinalize();
1767             } break;
1768             case POST_HEAVY_NOTIFICATION_MSG: {
1769                 INotificationManager inm = NotificationManager.getService();
1770                 if (inm == null) {
1771                     return;
1772                 }
1773
1774                 ActivityRecord root = (ActivityRecord)msg.obj;
1775                 ProcessRecord process = root.app;
1776                 if (process == null) {
1777                     return;
1778                 }
1779
1780                 try {
1781                     Context context = mContext.createPackageContext(process.info.packageName, 0);
1782                     String text = mContext.getString(R.string.heavy_weight_notification,
1783                             context.getApplicationInfo().loadLabel(context.getPackageManager()));
1784                     Notification notification = new Notification.Builder(context)
1785                             .setSmallIcon(com.android.internal.R.drawable.stat_sys_adb)
1786                             .setWhen(0)
1787                             .setOngoing(true)
1788                             .setTicker(text)
1789                             .setColor(mContext.getColor(
1790                                     com.android.internal.R.color.system_notification_accent_color))
1791                             .setContentTitle(text)
1792                             .setContentText(
1793                                     mContext.getText(R.string.heavy_weight_notification_detail))
1794                             .setContentIntent(PendingIntent.getActivityAsUser(mContext, 0,
1795                                     root.intent, PendingIntent.FLAG_CANCEL_CURRENT, null,
1796                                     new UserHandle(root.userId)))
1797                             .build();
1798                     try {
1799                         int[] outId = new int[1];
1800                         inm.enqueueNotificationWithTag("android", "android", null,
1801                                 R.string.heavy_weight_notification,
1802                                 notification, outId, root.userId);
1803                     } catch (RuntimeException e) {
1804                         Slog.w(ActivityManagerService.TAG,
1805                                 "Error showing notification for heavy-weight app", e);
1806                     } catch (RemoteException e) {
1807                     }
1808                 } catch (NameNotFoundException e) {
1809                     Slog.w(TAG, "Unable to create context for heavy notification", e);
1810                 }
1811             } break;
1812             case CANCEL_HEAVY_NOTIFICATION_MSG: {
1813                 INotificationManager inm = NotificationManager.getService();
1814                 if (inm == null) {
1815                     return;
1816                 }
1817                 try {
1818                     inm.cancelNotificationWithTag("android", null,
1819                             R.string.heavy_weight_notification,  msg.arg1);
1820                 } catch (RuntimeException e) {
1821                     Slog.w(ActivityManagerService.TAG,
1822                             "Error canceling notification for service", e);
1823                 } catch (RemoteException e) {
1824                 }
1825             } break;
1826             case CHECK_EXCESSIVE_WAKE_LOCKS_MSG: {
1827                 synchronized (ActivityManagerService.this) {
1828                     checkExcessivePowerUsageLocked(true);
1829                     removeMessages(CHECK_EXCESSIVE_WAKE_LOCKS_MSG);
1830                     Message nmsg = obtainMessage(CHECK_EXCESSIVE_WAKE_LOCKS_MSG);
1831                     sendMessageDelayed(nmsg, POWER_CHECK_DELAY);
1832                 }
1833             } break;
1834             case REPORT_MEM_USAGE_MSG: {
1835                 final ArrayList<ProcessMemInfo> memInfos = (ArrayList<ProcessMemInfo>)msg.obj;
1836                 Thread thread = new Thread() {
1837                     @Override public void run() {
1838                         reportMemUsage(memInfos);
1839                     }
1840                 };
1841                 thread.start();
1842                 break;
1843             }
1844             case REPORT_USER_SWITCH_MSG: {
1845                 mUserController.dispatchUserSwitch((UserState) msg.obj, msg.arg1, msg.arg2);
1846                 break;
1847             }
1848             case CONTINUE_USER_SWITCH_MSG: {
1849                 mUserController.continueUserSwitch((UserState) msg.obj, msg.arg1, msg.arg2);
1850                 break;
1851             }
1852             case USER_SWITCH_TIMEOUT_MSG: {
1853                 mUserController.timeoutUserSwitch((UserState) msg.obj, msg.arg1, msg.arg2);
1854                 break;
1855             }
1856             case IMMERSIVE_MODE_LOCK_MSG: {
1857                 final boolean nextState = (msg.arg1 != 0);
1858                 if (mUpdateLock.isHeld() != nextState) {
1859                     if (DEBUG_IMMERSIVE) Slog.d(TAG_IMMERSIVE,
1860                             "Applying new update lock state '" + nextState
1861                             + "' for " + (ActivityRecord)msg.obj);
1862                     if (nextState) {
1863                         mUpdateLock.acquire();
1864                     } else {
1865                         mUpdateLock.release();
1866                     }
1867                 }
1868                 break;
1869             }
1870             case PERSIST_URI_GRANTS_MSG: {
1871                 writeGrantedUriPermissions();
1872                 break;
1873             }
1874             case REQUEST_ALL_PSS_MSG: {
1875                 synchronized (ActivityManagerService.this) {
1876                     requestPssAllProcsLocked(SystemClock.uptimeMillis(), true, false);
1877                 }
1878                 break;
1879             }
1880             case START_PROFILES_MSG: {
1881                 synchronized (ActivityManagerService.this) {
1882                     mUserController.startProfilesLocked();
1883                 }
1884                 break;
1885             }
1886             case UPDATE_TIME: {
1887                 synchronized (ActivityManagerService.this) {
1888                     for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) {
1889                         ProcessRecord r = mLruProcesses.get(i);
1890                         if (r.thread != null) {
1891                             try {
1892                                 r.thread.updateTimePrefs(msg.arg1 == 0 ? false : true);
1893                             } catch (RemoteException ex) {
1894                                 Slog.w(TAG, "Failed to update preferences for: " + r.info.processName);
1895                             }
1896                         }
1897                     }
1898                 }
1899                 break;
1900             }
1901             case SYSTEM_USER_START_MSG: {
1902                 mBatteryStatsService.noteEvent(BatteryStats.HistoryItem.EVENT_USER_RUNNING_START,
1903                         Integer.toString(msg.arg1), msg.arg1);
1904                 mSystemServiceManager.startUser(msg.arg1);
1905                 break;
1906             }
1907             case SYSTEM_USER_UNLOCK_MSG: {
1908                 final int userId = msg.arg1;
1909                 mSystemServiceManager.unlockUser(userId);
1910                 synchronized (ActivityManagerService.this) {
1911                     mRecentTasks.loadUserRecentsLocked(userId);
1912                 }
1913                 if (userId == UserHandle.USER_SYSTEM) {
1914                     startPersistentApps(PackageManager.MATCH_DIRECT_BOOT_UNAWARE);
1915                 }
1916                 installEncryptionUnawareProviders(userId);
1917                 break;
1918             }
1919             case SYSTEM_USER_CURRENT_MSG: {
1920                 mBatteryStatsService.noteEvent(
1921                         BatteryStats.HistoryItem.EVENT_USER_FOREGROUND_FINISH,
1922                         Integer.toString(msg.arg2), msg.arg2);
1923                 mBatteryStatsService.noteEvent(
1924                         BatteryStats.HistoryItem.EVENT_USER_FOREGROUND_START,
1925                         Integer.toString(msg.arg1), msg.arg1);
1926                 mSystemServiceManager.switchUser(msg.arg1);
1927                 break;
1928             }
1929             case ENTER_ANIMATION_COMPLETE_MSG: {
1930                 synchronized (ActivityManagerService.this) {
1931                     ActivityRecord r = ActivityRecord.forTokenLocked((IBinder) msg.obj);
1932                     if (r != null && r.app != null && r.app.thread != null) {
1933                         try {
1934                             r.app.thread.scheduleEnterAnimationComplete(r.appToken);
1935                         } catch (RemoteException e) {
1936                         }
1937                     }
1938                 }
1939                 break;
1940             }
1941             case FINISH_BOOTING_MSG: {
1942                 if (msg.arg1 != 0) {
1943                     Trace.traceBegin(Trace.TRACE_TAG_ACTIVITY_MANAGER, "FinishBooting");
1944                     finishBooting();
1945                     Trace.traceEnd(Trace.TRACE_TAG_ACTIVITY_MANAGER);
1946                 }
1947                 if (msg.arg2 != 0) {
1948                     enableScreenAfterBoot();
1949                 }
1950                 break;
1951             }
1952             case SEND_LOCALE_TO_MOUNT_DAEMON_MSG: {
1953                 try {
1954                     Locale l = (Locale) msg.obj;
1955                     IBinder service = ServiceManager.getService("mount");
1956                     IMountService mountService = IMountService.Stub.asInterface(service);
1957                     Log.d(TAG, "Storing locale " + l.toLanguageTag() + " for decryption UI");
1958                     mountService.setField(StorageManager.SYSTEM_LOCALE_KEY, l.toLanguageTag());
1959                 } catch (RemoteException e) {
1960                     Log.e(TAG, "Error storing locale for decryption UI", e);
1961                 }
1962                 break;
1963             }
1964             case NOTIFY_TASK_STACK_CHANGE_LISTENERS_MSG: {
1965                 synchronized (ActivityManagerService.this) {
1966                     for (int i = mTaskStackListeners.beginBroadcast() - 1; i >= 0; i--) {
1967                         try {
1968                             // Make a one-way callback to the listener
1969                             mTaskStackListeners.getBroadcastItem(i).onTaskStackChanged();
1970                         } catch (RemoteException e){
1971                             // Handled by the RemoteCallbackList
1972                         }
1973                     }
1974                     mTaskStackListeners.finishBroadcast();
1975                 }
1976                 break;
1977             }
1978             case NOTIFY_ACTIVITY_PINNED_LISTENERS_MSG: {
1979                 synchronized (ActivityManagerService.this) {
1980                     for (int i = mTaskStackListeners.beginBroadcast() - 1; i >= 0; i--) {
1981                         try {
1982                             // Make a one-way callback to the listener
1983                             mTaskStackListeners.getBroadcastItem(i).onActivityPinned();
1984                         } catch (RemoteException e){
1985                             // Handled by the RemoteCallbackList
1986                         }
1987                     }
1988                     mTaskStackListeners.finishBroadcast();
1989                 }
1990                 break;
1991             }
1992             case NOTIFY_PINNED_ACTIVITY_RESTART_ATTEMPT_LISTENERS_MSG: {
1993                 synchronized (ActivityManagerService.this) {
1994                     for (int i = mTaskStackListeners.beginBroadcast() - 1; i >= 0; i--) {
1995                         try {
1996                             // Make a one-way callback to the listener
1997                             mTaskStackListeners.getBroadcastItem(i).onPinnedActivityRestartAttempt();
1998                         } catch (RemoteException e){
1999                             // Handled by the RemoteCallbackList
2000                         }
2001                     }
2002                     mTaskStackListeners.finishBroadcast();
2003                 }
2004                 break;
2005             }
2006             case NOTIFY_PINNED_STACK_ANIMATION_ENDED_LISTENERS_MSG: {
2007                 synchronized (ActivityManagerService.this) {
2008                     for (int i = mTaskStackListeners.beginBroadcast() - 1; i >= 0; i--) {
2009                         try {
2010                             // Make a one-way callback to the listener
2011                             mTaskStackListeners.getBroadcastItem(i).onPinnedStackAnimationEnded();
2012                         } catch (RemoteException e){
2013                             // Handled by the RemoteCallbackList
2014                         }
2015                     }
2016                     mTaskStackListeners.finishBroadcast();
2017                 }
2018                 break;
2019             }
2020             case NOTIFY_CLEARTEXT_NETWORK_MSG: {
2021                 final int uid = msg.arg1;
2022                 final byte[] firstPacket = (byte[]) msg.obj;
2023
2024                 synchronized (mPidsSelfLocked) {
2025                     for (int i = 0; i < mPidsSelfLocked.size(); i++) {
2026                         final ProcessRecord p = mPidsSelfLocked.valueAt(i);
2027                         if (p.uid == uid) {
2028                             try {
2029                                 p.thread.notifyCleartextNetwork(firstPacket);
2030                             } catch (RemoteException ignored) {
2031                             }
2032                         }
2033                     }
2034                 }
2035                 break;
2036             }
2037             case POST_DUMP_HEAP_NOTIFICATION_MSG: {
2038                 final String procName;
2039                 final int uid;
2040                 final long memLimit;
2041                 final String reportPackage;
2042                 synchronized (ActivityManagerService.this) {
2043                     procName = mMemWatchDumpProcName;
2044                     uid = mMemWatchDumpUid;
2045                     Pair<Long, String> val = mMemWatchProcesses.get(procName, uid);
2046                     if (val == null) {
2047                         val = mMemWatchProcesses.get(procName, 0);
2048                     }
2049                     if (val != null) {
2050                         memLimit = val.first;
2051                         reportPackage = val.second;
2052                     } else {
2053                         memLimit = 0;
2054                         reportPackage = null;
2055                     }
2056                 }
2057                 if (procName == null) {
2058                     return;
2059                 }
2060
2061                 if (DEBUG_PSS) Slog.d(TAG_PSS,
2062                         "Showing dump heap notification from " + procName + "/" + uid);
2063
2064                 INotificationManager inm = NotificationManager.getService();
2065                 if (inm == null) {
2066                     return;
2067                 }
2068
2069                 String text = mContext.getString(R.string.dump_heap_notification, procName);
2070
2071
2072                 Intent deleteIntent = new Intent();
2073                 deleteIntent.setAction(DumpHeapActivity.ACTION_DELETE_DUMPHEAP);
2074                 Intent intent = new Intent();
2075                 intent.setClassName("android", DumpHeapActivity.class.getName());
2076                 intent.putExtra(DumpHeapActivity.KEY_PROCESS, procName);
2077                 intent.putExtra(DumpHeapActivity.KEY_SIZE, memLimit);
2078                 if (reportPackage != null) {
2079                     intent.putExtra(DumpHeapActivity.KEY_DIRECT_LAUNCH, reportPackage);
2080                 }
2081                 int userId = UserHandle.getUserId(uid);
2082                 Notification notification = new Notification.Builder(mContext)
2083                         .setSmallIcon(com.android.internal.R.drawable.stat_sys_adb)
2084                         .setWhen(0)
2085                         .setOngoing(true)
2086                         .setAutoCancel(true)
2087                         .setTicker(text)
2088                         .setColor(mContext.getColor(
2089                                 com.android.internal.R.color.system_notification_accent_color))
2090                         .setContentTitle(text)
2091                         .setContentText(
2092                                 mContext.getText(R.string.dump_heap_notification_detail))
2093                         .setContentIntent(PendingIntent.getActivityAsUser(mContext, 0,
2094                                 intent, PendingIntent.FLAG_CANCEL_CURRENT, null,
2095                                 new UserHandle(userId)))
2096                         .setDeleteIntent(PendingIntent.getBroadcastAsUser(mContext, 0,
2097                                 deleteIntent, 0, UserHandle.SYSTEM))
2098                         .build();
2099
2100                 try {
2101                     int[] outId = new int[1];
2102                     inm.enqueueNotificationWithTag("android", "android", null,
2103                             R.string.dump_heap_notification,
2104                             notification, outId, userId);
2105                 } catch (RuntimeException e) {
2106                     Slog.w(ActivityManagerService.TAG,
2107                             "Error showing notification for dump heap", e);
2108                 } catch (RemoteException e) {
2109                 }
2110             } break;
2111             case DELETE_DUMPHEAP_MSG: {
2112                 revokeUriPermission(ActivityThread.currentActivityThread().getApplicationThread(),
2113                         DumpHeapActivity.JAVA_URI,
2114                         Intent.FLAG_GRANT_READ_URI_PERMISSION
2115                                 | Intent.FLAG_GRANT_WRITE_URI_PERMISSION,
2116                         UserHandle.myUserId());
2117                 synchronized (ActivityManagerService.this) {
2118                     mMemWatchDumpFile = null;
2119                     mMemWatchDumpProcName = null;
2120                     mMemWatchDumpPid = -1;
2121                     mMemWatchDumpUid = -1;
2122                 }
2123             } break;
2124             case FOREGROUND_PROFILE_CHANGED_MSG: {
2125                 mUserController.dispatchForegroundProfileChanged(msg.arg1);
2126             } break;
2127             case REPORT_TIME_TRACKER_MSG: {
2128                 AppTimeTracker tracker = (AppTimeTracker)msg.obj;
2129                 tracker.deliverResult(mContext);
2130             } break;
2131             case REPORT_USER_SWITCH_COMPLETE_MSG: {
2132                 mUserController.dispatchUserSwitchComplete(msg.arg1);
2133             } break;
2134             case SHUTDOWN_UI_AUTOMATION_CONNECTION_MSG: {
2135                 IUiAutomationConnection connection = (IUiAutomationConnection) msg.obj;
2136                 try {
2137                     connection.shutdown();
2138                 } catch (RemoteException e) {
2139                     Slog.w(TAG, "Error shutting down UiAutomationConnection");
2140                 }
2141                 // Only a UiAutomation can set this flag and now that
2142                 // it is finished we make sure it is reset to its default.
2143                 mUserIsMonkey = false;
2144             } break;
2145             case APP_BOOST_DEACTIVATE_MSG: {
2146                 synchronized(ActivityManagerService.this) {
2147                     if (mIsBoosted) {
2148                         if (mBoostStartTime < (SystemClock.uptimeMillis() - APP_BOOST_TIMEOUT)) {
2149                             nativeMigrateFromBoost();
2150                             mIsBoosted = false;
2151                             mBoostStartTime = 0;
2152                         } else {
2153                             Message newmsg = mHandler.obtainMessage(APP_BOOST_DEACTIVATE_MSG);
2154                             mHandler.sendMessageDelayed(newmsg, APP_BOOST_TIMEOUT);
2155                         }
2156                     }
2157                 }
2158             } break;
2159             case IDLE_UIDS_MSG: {
2160                 idleUids();
2161             } break;
2162             case LOG_STACK_STATE: {
2163                 synchronized (ActivityManagerService.this) {
2164                     mStackSupervisor.logStackState();
2165                 }
2166             } break;
2167             case VR_MODE_CHANGE_MSG: {
2168                 VrManagerInternal vrService = LocalServices.getService(VrManagerInternal.class);
2169                 final ActivityRecord r = (ActivityRecord) msg.obj;
2170                 boolean vrMode;
2171                 ComponentName requestedPackage;
2172                 int userId;
2173                 synchronized (ActivityManagerService.this) {
2174                     vrMode = r.requestedVrComponent != null;
2175                     requestedPackage = r.requestedVrComponent;
2176                     userId = r.userId;
2177                     if (mInVrMode != vrMode) {
2178                         mInVrMode = vrMode;
2179                         mShowDialogs = shouldShowDialogs(mConfiguration, mInVrMode);
2180                     }
2181                 }
2182                 vrService.setVrMode(vrMode, requestedPackage, userId);
2183             } break;
2184             }
2185         }
2186     };
2187
2188     static final int COLLECT_PSS_BG_MSG = 1;
2189
2190     final Handler mBgHandler = new Handler(BackgroundThread.getHandler().getLooper()) {
2191         @Override
2192         public void handleMessage(Message msg) {
2193             switch (msg.what) {
2194             case COLLECT_PSS_BG_MSG: {
2195                 long start = SystemClock.uptimeMillis();
2196                 MemInfoReader memInfo = null;
2197                 synchronized (ActivityManagerService.this) {
2198                     if (mFullPssPending) {
2199                         mFullPssPending = false;
2200                         memInfo = new MemInfoReader();
2201                     }
2202                 }
2203                 if (memInfo != null) {
2204                     updateCpuStatsNow();
2205                     long nativeTotalPss = 0;
2206                     synchronized (mProcessCpuTracker) {
2207                         final int N = mProcessCpuTracker.countStats();
2208                         for (int j=0; j<N; j++) {
2209                             ProcessCpuTracker.Stats st = mProcessCpuTracker.getStats(j);
2210                             if (st.vsize <= 0 || st.uid >= Process.FIRST_APPLICATION_UID) {
2211                                 // This is definitely an application process; skip it.
2212                                 continue;
2213                             }
2214                             synchronized (mPidsSelfLocked) {
2215                                 if (mPidsSelfLocked.indexOfKey(st.pid) >= 0) {
2216                                     // This is one of our own processes; skip it.
2217                                     continue;
2218                                 }
2219                             }
2220                             nativeTotalPss += Debug.getPss(st.pid, null, null);
2221                         }
2222                     }
2223                     memInfo.readMemInfo();
2224                     synchronized (ActivityManagerService.this) {
2225                         if (DEBUG_PSS) Slog.d(TAG_PSS, "Collected native and kernel memory in "
2226                                 + (SystemClock.uptimeMillis()-start) + "ms");
2227                         final long cachedKb = memInfo.getCachedSizeKb();
2228                         final long freeKb = memInfo.getFreeSizeKb();
2229                         final long zramKb = memInfo.getZramTotalSizeKb();
2230                         final long kernelKb = memInfo.getKernelUsedSizeKb();
2231                         EventLogTags.writeAmMeminfo(cachedKb*1024, freeKb*1024, zramKb*1024,
2232                                 kernelKb*1024, nativeTotalPss*1024);
2233                         mProcessStats.addSysMemUsageLocked(cachedKb, freeKb, zramKb, kernelKb,
2234                                 nativeTotalPss);
2235                     }
2236                 }
2237
2238                 int num = 0;
2239                 long[] tmp = new long[2];
2240                 do {
2241                     ProcessRecord proc;
2242                     int procState;
2243                     int pid;
2244                     long lastPssTime;
2245                     synchronized (ActivityManagerService.this) {
2246                         if (mPendingPssProcesses.size() <= 0) {
2247                             if (mTestPssMode || DEBUG_PSS) Slog.d(TAG_PSS,
2248                                     "Collected PSS of " + num + " processes in "
2249                                     + (SystemClock.uptimeMillis() - start) + "ms");
2250                             mPendingPssProcesses.clear();
2251                             return;
2252                         }
2253                         proc = mPendingPssProcesses.remove(0);
2254                         procState = proc.pssProcState;
2255                         lastPssTime = proc.lastPssTime;
2256                         if (proc.thread != null && procState == proc.setProcState
2257                                 && (lastPssTime+ProcessList.PSS_SAFE_TIME_FROM_STATE_CHANGE)
2258                                         < SystemClock.uptimeMillis()) {
2259                             pid = proc.pid;
2260                         } else {
2261                             proc = null;
2262                             pid = 0;
2263                         }
2264                     }
2265                     if (proc != null) {
2266                         long pss = Debug.getPss(pid, tmp, null);
2267                         synchronized (ActivityManagerService.this) {
2268                             if (pss != 0 && proc.thread != null && proc.setProcState == procState
2269                                     && proc.pid == pid && proc.lastPssTime == lastPssTime) {
2270                                 num++;
2271                                 recordPssSampleLocked(proc, procState, pss, tmp[0], tmp[1],
2272                                         SystemClock.uptimeMillis());
2273                             }
2274                         }
2275                     }
2276                 } while (true);
2277             }
2278             }
2279         }
2280     };
2281
2282     public void setSystemProcess() {
2283         try {
2284             ServiceManager.addService(Context.ACTIVITY_SERVICE, this, true);
2285             ServiceManager.addService(ProcessStats.SERVICE_NAME, mProcessStats);
2286             ServiceManager.addService("meminfo", new MemBinder(this));
2287             ServiceManager.addService("gfxinfo", new GraphicsBinder(this));
2288             ServiceManager.addService("dbinfo", new DbBinder(this));
2289             if (MONITOR_CPU_USAGE) {
2290                 ServiceManager.addService("cpuinfo", new CpuBinder(this));
2291             }
2292             ServiceManager.addService("permission", new PermissionController(this));
2293             ServiceManager.addService("processinfo", new ProcessInfoService(this));
2294
2295             ApplicationInfo info = mContext.getPackageManager().getApplicationInfo(
2296                     "android", STOCK_PM_FLAGS | MATCH_SYSTEM_ONLY);
2297             mSystemThread.installSystemApplicationInfo(info, getClass().getClassLoader());
2298
2299             synchronized (this) {
2300                 ProcessRecord app = newProcessRecordLocked(info, info.processName, false, 0);
2301                 app.persistent = true;
2302                 app.pid = MY_PID;
2303                 app.maxAdj = ProcessList.SYSTEM_ADJ;
2304                 app.makeActive(mSystemThread.getApplicationThread(), mProcessStats);
2305                 synchronized (mPidsSelfLocked) {
2306                     mPidsSelfLocked.put(app.pid, app);
2307                 }
2308                 updateLruProcessLocked(app, false, null);
2309                 updateOomAdjLocked();
2310             }
2311         } catch (PackageManager.NameNotFoundException e) {
2312             throw new RuntimeException(
2313                     "Unable to find android system package", e);
2314         }
2315     }
2316
2317     public void setWindowManager(WindowManagerService wm) {
2318         mWindowManager = wm;
2319         mStackSupervisor.setWindowManager(wm);
2320         mActivityStarter.setWindowManager(wm);
2321     }
2322
2323     public void setUsageStatsManager(UsageStatsManagerInternal usageStatsManager) {
2324         mUsageStatsService = usageStatsManager;
2325     }
2326
2327     public void startObservingNativeCrashes() {
2328         final NativeCrashListener ncl = new NativeCrashListener(this);
2329         ncl.start();
2330     }
2331
2332     public IAppOpsService getAppOpsService() {
2333         return mAppOpsService;
2334     }
2335
2336     static class MemBinder extends Binder {
2337         ActivityManagerService mActivityManagerService;
2338         MemBinder(ActivityManagerService activityManagerService) {
2339             mActivityManagerService = activityManagerService;
2340         }
2341
2342         @Override
2343         protected void dump(FileDescriptor fd, PrintWriter pw, String[] args) {
2344             if (mActivityManagerService.checkCallingPermission(android.Manifest.permission.DUMP)
2345                     != PackageManager.PERMISSION_GRANTED) {
2346                 pw.println("Permission Denial: can't dump meminfo from from pid="
2347                         + Binder.getCallingPid() + ", uid=" + Binder.getCallingUid()
2348                         + " without permission " + android.Manifest.permission.DUMP);
2349                 return;
2350             }
2351
2352             mActivityManagerService.dumpApplicationMemoryUsage(fd, pw, "  ", args, false, null);
2353         }
2354     }
2355
2356     static class GraphicsBinder extends Binder {
2357         ActivityManagerService mActivityManagerService;
2358         GraphicsBinder(ActivityManagerService activityManagerService) {
2359             mActivityManagerService = activityManagerService;
2360         }
2361
2362         @Override
2363         protected void dump(FileDescriptor fd, PrintWriter pw, String[] args) {
2364             if (mActivityManagerService.checkCallingPermission(android.Manifest.permission.DUMP)
2365                     != PackageManager.PERMISSION_GRANTED) {
2366                 pw.println("Permission Denial: can't dump gfxinfo from from pid="
2367                         + Binder.getCallingPid() + ", uid=" + Binder.getCallingUid()
2368                         + " without permission " + android.Manifest.permission.DUMP);
2369                 return;
2370             }
2371
2372             mActivityManagerService.dumpGraphicsHardwareUsage(fd, pw, args);
2373         }
2374     }
2375
2376     static class DbBinder extends Binder {
2377         ActivityManagerService mActivityManagerService;
2378         DbBinder(ActivityManagerService activityManagerService) {
2379             mActivityManagerService = activityManagerService;
2380         }
2381
2382         @Override
2383         protected void dump(FileDescriptor fd, PrintWriter pw, String[] args) {
2384             if (mActivityManagerService.checkCallingPermission(android.Manifest.permission.DUMP)
2385                     != PackageManager.PERMISSION_GRANTED) {
2386                 pw.println("Permission Denial: can't dump dbinfo from from pid="
2387                         + Binder.getCallingPid() + ", uid=" + Binder.getCallingUid()
2388                         + " without permission " + android.Manifest.permission.DUMP);
2389                 return;
2390             }
2391
2392             mActivityManagerService.dumpDbInfo(fd, pw, args);
2393         }
2394     }
2395
2396     static class CpuBinder extends Binder {
2397         ActivityManagerService mActivityManagerService;
2398         CpuBinder(ActivityManagerService activityManagerService) {
2399             mActivityManagerService = activityManagerService;
2400         }
2401
2402         @Override
2403         protected void dump(FileDescriptor fd, PrintWriter pw, String[] args) {
2404             if (mActivityManagerService.checkCallingPermission(android.Manifest.permission.DUMP)
2405                     != PackageManager.PERMISSION_GRANTED) {
2406                 pw.println("Permission Denial: can't dump cpuinfo from from pid="
2407                         + Binder.getCallingPid() + ", uid=" + Binder.getCallingUid()
2408                         + " without permission " + android.Manifest.permission.DUMP);
2409                 return;
2410             }
2411
2412             synchronized (mActivityManagerService.mProcessCpuTracker) {
2413                 pw.print(mActivityManagerService.mProcessCpuTracker.printCurrentLoad());
2414                 pw.print(mActivityManagerService.mProcessCpuTracker.printCurrentState(
2415                         SystemClock.uptimeMillis()));
2416             }
2417         }
2418     }
2419
2420     public static final class Lifecycle extends SystemService {
2421         private final ActivityManagerService mService;
2422
2423         public Lifecycle(Context context) {
2424             super(context);
2425             mService = new ActivityManagerService(context);
2426         }
2427
2428         @Override
2429         public void onStart() {
2430             mService.start();
2431         }
2432
2433         public ActivityManagerService getService() {
2434             return mService;
2435         }
2436     }
2437
2438     // Note: This method is invoked on the main thread but may need to attach various
2439     // handlers to other threads.  So take care to be explicit about the looper.
2440     public ActivityManagerService(Context systemContext) {
2441         mContext = systemContext;
2442         mFactoryTest = FactoryTest.getMode();
2443         mSystemThread = ActivityThread.currentActivityThread();
2444
2445         Slog.i(TAG, "Memory class: " + ActivityManager.staticGetMemoryClass());
2446
2447         mHandlerThread = new ServiceThread(TAG,
2448                 android.os.Process.THREAD_PRIORITY_FOREGROUND, false /*allowIo*/);
2449         mHandlerThread.start();
2450         mHandler = new MainHandler(mHandlerThread.getLooper());
2451         mUiHandler = new UiHandler();
2452
2453         mProcessStartLogger = new ProcessStartLogger();
2454
2455         mFgBroadcastQueue = new BroadcastQueue(this, mHandler,
2456                 "foreground", BROADCAST_FG_TIMEOUT, false);
2457         mBgBroadcastQueue = new BroadcastQueue(this, mHandler,
2458                 "background", BROADCAST_BG_TIMEOUT, true);
2459         mBroadcastQueues[0] = mFgBroadcastQueue;
2460         mBroadcastQueues[1] = mBgBroadcastQueue;
2461
2462         mServices = new ActiveServices(this);
2463         mProviderMap = new ProviderMap(this);
2464         mAppErrors = new AppErrors(mContext, this);
2465
2466         // TODO: Move creation of battery stats service outside of activity manager service.
2467         File dataDir = Environment.getDataDirectory();
2468         File systemDir = new File(dataDir, "system");
2469         systemDir.mkdirs();
2470         mBatteryStatsService = new BatteryStatsService(systemDir, mHandler);
2471         mBatteryStatsService.getActiveStatistics().readLocked();
2472         mBatteryStatsService.scheduleWriteToDisk();
2473         mOnBattery = DEBUG_POWER ? true
2474                 : mBatteryStatsService.getActiveStatistics().getIsOnBattery();
2475         mBatteryStatsService.getActiveStatistics().setCallback(this);
2476
2477         mProcessStats = new ProcessStatsService(this, new File(systemDir, "procstats"));
2478
2479         mAppOpsService = new AppOpsService(new File(systemDir, "appops.xml"), mHandler);
2480         mAppOpsService.startWatchingMode(AppOpsManager.OP_RUN_IN_BACKGROUND, null,
2481                 new IAppOpsCallback.Stub() {
2482                     @Override public void opChanged(int op, int uid, String packageName) {
2483                         if (op == AppOpsManager.OP_RUN_IN_BACKGROUND && packageName != null) {
2484                             if (mAppOpsService.checkOperation(op, uid, packageName)
2485                                     != AppOpsManager.MODE_ALLOWED) {
2486                                 runInBackgroundDisabled(uid);
2487                             }
2488                         }
2489                     }
2490                 });
2491
2492         mGrantFile = new AtomicFile(new File(systemDir, "urigrants.xml"));
2493
2494         mUserController = new UserController(this);
2495
2496         GL_ES_VERSION = SystemProperties.getInt("ro.opengles.version",
2497             ConfigurationInfo.GL_ES_VERSION_UNDEFINED);
2498
2499         mTrackingAssociations = "1".equals(SystemProperties.get("debug.track-associations"));
2500
2501         mConfiguration.setToDefaults();
2502         mConfiguration.setLocales(LocaleList.getDefault());
2503
2504         mConfigurationSeq = mConfiguration.seq = 1;
2505         mProcessCpuTracker.init();
2506
2507         mCompatModePackages = new CompatModePackages(this, systemDir, mHandler);
2508         mIntentFirewall = new IntentFirewall(new IntentFirewallInterface(), mHandler);
2509         mStackSupervisor = new ActivityStackSupervisor(this);
2510         mActivityStarter = new ActivityStarter(this, mStackSupervisor);
2511         mRecentTasks = new RecentTasks(this, mStackSupervisor);
2512
2513         mProcessCpuThread = new Thread("CpuTracker") {
2514             @Override
2515             public void run() {
2516                 while (true) {
2517                     try {
2518                         try {
2519                             synchronized(this) {
2520                                 final long now = SystemClock.uptimeMillis();
2521                                 long nextCpuDelay = (mLastCpuTime.get()+MONITOR_CPU_MAX_TIME)-now;
2522                                 long nextWriteDelay = (mLastWriteTime+BATTERY_STATS_TIME)-now;
2523                                 //Slog.i(TAG, "Cpu delay=" + nextCpuDelay
2524                                 //        + ", write delay=" + nextWriteDelay);
2525                                 if (nextWriteDelay < nextCpuDelay) {
2526                                     nextCpuDelay = nextWriteDelay;
2527                                 }
2528                                 if (nextCpuDelay > 0) {
2529                                     mProcessCpuMutexFree.set(true);
2530                                     this.wait(nextCpuDelay);
2531                                 }
2532                             }
2533                         } catch (InterruptedException e) {
2534                         }
2535                         updateCpuStatsNow();
2536                     } catch (Exception e) {
2537                         Slog.e(TAG, "Unexpected exception collecting process stats", e);
2538                     }
2539                 }
2540             }
2541         };
2542
2543         Watchdog.getInstance().addMonitor(this);
2544         Watchdog.getInstance().addThread(mHandler);
2545     }
2546
2547     public void setSystemServiceManager(SystemServiceManager mgr) {
2548         mSystemServiceManager = mgr;
2549     }
2550
2551     public void setInstaller(Installer installer) {
2552         mInstaller = installer;
2553     }
2554
2555     private void start() {
2556         Process.removeAllProcessGroups();
2557         mProcessCpuThread.start();
2558
2559         mBatteryStatsService.publish(mContext);
2560         mAppOpsService.publish(mContext);
2561         Slog.d("AppOps", "AppOpsService published");
2562         LocalServices.addService(ActivityManagerInternal.class, new LocalService());
2563     }
2564
2565     void onUserStoppedLocked(int userId) {
2566         mRecentTasks.unloadUserDataFromMemoryLocked(userId);
2567     }
2568
2569     public void initPowerManagement() {
2570         mStackSupervisor.initPowerManagement();
2571         mBatteryStatsService.initPowerManagement();
2572         mLocalPowerManager = LocalServices.getService(PowerManagerInternal.class);
2573         PowerManager pm = (PowerManager)mContext.getSystemService(Context.POWER_SERVICE);
2574         mVoiceWakeLock = pm.newWakeLock(PowerManager.PARTIAL_WAKE_LOCK, "*voice*");
2575         mVoiceWakeLock.setReferenceCounted(false);
2576     }
2577
2578     @Override
2579     public boolean onTransact(int code, Parcel data, Parcel reply, int flags)
2580             throws RemoteException {
2581         if (code == SYSPROPS_TRANSACTION) {
2582             // We need to tell all apps about the system property change.
2583             ArrayList<IBinder> procs = new ArrayList<IBinder>();
2584             synchronized(this) {
2585                 final int NP = mProcessNames.getMap().size();
2586                 for (int ip=0; ip<NP; ip++) {
2587                     SparseArray<ProcessRecord> apps = mProcessNames.getMap().valueAt(ip);
2588                     final int NA = apps.size();
2589                     for (int ia=0; ia<NA; ia++) {
2590                         ProcessRecord app = apps.valueAt(ia);
2591                         if (app.thread != null) {
2592                             procs.add(app.thread.asBinder());
2593                         }
2594                     }
2595                 }
2596             }
2597
2598             int N = procs.size();
2599             for (int i=0; i<N; i++) {
2600                 Parcel data2 = Parcel.obtain();
2601                 try {
2602                     procs.get(i).transact(IBinder.SYSPROPS_TRANSACTION, data2, null, 0);
2603                 } catch (RemoteException e) {
2604                 }
2605                 data2.recycle();
2606             }
2607         }
2608         try {
2609             return super.onTransact(code, data, reply, flags);
2610         } catch (RuntimeException e) {
2611             // The activity manager only throws security exceptions, so let's
2612             // log all others.
2613             if (!(e instanceof SecurityException)) {
2614                 Slog.wtf(TAG, "Activity Manager Crash", e);
2615             }
2616             throw e;
2617         }
2618     }
2619
2620     void updateCpuStats() {
2621         final long now = SystemClock.uptimeMillis();
2622         if (mLastCpuTime.get() >= now - MONITOR_CPU_MIN_TIME) {
2623             return;
2624         }
2625         if (mProcessCpuMutexFree.compareAndSet(true, false)) {
2626             synchronized (mProcessCpuThread) {
2627                 mProcessCpuThread.notify();
2628             }
2629         }
2630     }
2631
2632     void updateCpuStatsNow() {
2633         synchronized (mProcessCpuTracker) {
2634             mProcessCpuMutexFree.set(false);
2635             final long now = SystemClock.uptimeMillis();
2636             boolean haveNewCpuStats = false;
2637
2638             if (MONITOR_CPU_USAGE &&
2639                     mLastCpuTime.get() < (now-MONITOR_CPU_MIN_TIME)) {
2640                 mLastCpuTime.set(now);
2641                 mProcessCpuTracker.update();
2642                 if (mProcessCpuTracker.hasGoodLastStats()) {
2643                     haveNewCpuStats = true;
2644                     //Slog.i(TAG, mProcessCpu.printCurrentState());
2645                     //Slog.i(TAG, "Total CPU usage: "
2646                     //        + mProcessCpu.getTotalCpuPercent() + "%");
2647
2648                     // Slog the cpu usage if the property is set.
2649                     if ("true".equals(SystemProperties.get("events.cpu"))) {
2650                         int user = mProcessCpuTracker.getLastUserTime();
2651                         int system = mProcessCpuTracker.getLastSystemTime();
2652                         int iowait = mProcessCpuTracker.getLastIoWaitTime();
2653                         int irq = mProcessCpuTracker.getLastIrqTime();
2654                         int softIrq = mProcessCpuTracker.getLastSoftIrqTime();
2655                         int idle = mProcessCpuTracker.getLastIdleTime();
2656
2657                         int total = user + system + iowait + irq + softIrq + idle;
2658                         if (total == 0) total = 1;
2659
2660                         EventLog.writeEvent(EventLogTags.CPU,
2661                                 ((user+system+iowait+irq+softIrq) * 100) / total,
2662                                 (user * 100) / total,
2663                                 (system * 100) / total,
2664                                 (iowait * 100) / total,
2665                                 (irq * 100) / total,
2666                                 (softIrq * 100) / total);
2667                     }
2668                 }
2669             }
2670
2671             final BatteryStatsImpl bstats = mBatteryStatsService.getActiveStatistics();
2672             synchronized(bstats) {
2673                 synchronized(mPidsSelfLocked) {
2674                     if (haveNewCpuStats) {
2675                         if (bstats.startAddingCpuLocked()) {
2676                             int totalUTime = 0;
2677                             int totalSTime = 0;
2678                             final int N = mProcessCpuTracker.countStats();
2679                             for (int i=0; i<N; i++) {
2680                                 ProcessCpuTracker.Stats st = mProcessCpuTracker.getStats(i);
2681                                 if (!st.working) {
2682                                     continue;
2683                                 }
2684                                 ProcessRecord pr = mPidsSelfLocked.get(st.pid);
2685                                 totalUTime += st.rel_utime;
2686                                 totalSTime += st.rel_stime;
2687                                 if (pr != null) {
2688                                     BatteryStatsImpl.Uid.Proc ps = pr.curProcBatteryStats;
2689                                     if (ps == null || !ps.isActive()) {
2690                                         pr.curProcBatteryStats = ps = bstats.getProcessStatsLocked(
2691                                                 pr.info.uid, pr.processName);
2692                                     }
2693                                     ps.addCpuTimeLocked(st.rel_utime, st.rel_stime);
2694                                     pr.curCpuTime += st.rel_utime + st.rel_stime;
2695                                 } else {
2696                                     BatteryStatsImpl.Uid.Proc ps = st.batteryStats;
2697                                     if (ps == null || !ps.isActive()) {
2698                                         st.batteryStats = ps = bstats.getProcessStatsLocked(
2699                                                 bstats.mapUid(st.uid), st.name);
2700                                     }
2701                                     ps.addCpuTimeLocked(st.rel_utime, st.rel_stime);
2702                                 }
2703                             }
2704                             final int userTime = mProcessCpuTracker.getLastUserTime();
2705                             final int systemTime = mProcessCpuTracker.getLastSystemTime();
2706                             final int iowaitTime = mProcessCpuTracker.getLastIoWaitTime();
2707                             final int irqTime = mProcessCpuTracker.getLastIrqTime();
2708                             final int softIrqTime = mProcessCpuTracker.getLastSoftIrqTime();
2709                             final int idleTime = mProcessCpuTracker.getLastIdleTime();
2710                             bstats.finishAddingCpuLocked(totalUTime, totalSTime, userTime,
2711                                     systemTime, iowaitTime, irqTime, softIrqTime, idleTime);
2712                         }
2713                     }
2714                 }
2715
2716                 if (mLastWriteTime < (now-BATTERY_STATS_TIME)) {
2717                     mLastWriteTime = now;
2718                     mBatteryStatsService.scheduleWriteToDisk();
2719                 }
2720             }
2721         }
2722     }
2723
2724     @Override
2725     public void batteryNeedsCpuUpdate() {
2726         updateCpuStatsNow();
2727     }
2728
2729     @Override
2730     public void batteryPowerChanged(boolean onBattery) {
2731         // When plugging in, update the CPU stats first before changing
2732         // the plug state.
2733         updateCpuStatsNow();
2734         synchronized (this) {
2735             synchronized(mPidsSelfLocked) {
2736                 mOnBattery = DEBUG_POWER ? true : onBattery;
2737             }
2738         }
2739     }
2740
2741     @Override
2742     public void batterySendBroadcast(Intent intent) {
2743         broadcastIntentLocked(null, null, intent, null, null, 0, null, null, null,
2744                 AppOpsManager.OP_NONE, null, false, false,
2745                 -1, Process.SYSTEM_UID, UserHandle.USER_ALL);
2746     }
2747
2748     /**
2749      * Initialize the application bind args. These are passed to each
2750      * process when the bindApplication() IPC is sent to the process. They're
2751      * lazily setup to make sure the services are running when they're asked for.
2752      */
2753     private HashMap<String, IBinder> getCommonServicesLocked(boolean isolated) {
2754         if (mAppBindArgs == null) {
2755             mAppBindArgs = new HashMap<>();
2756
2757             // Isolated processes won't get this optimization, so that we don't
2758             // violate the rules about which services they have access to.
2759             if (!isolated) {
2760                 // Setup the application init args
2761                 mAppBindArgs.put("package", ServiceManager.getService("package"));
2762                 mAppBindArgs.put("window", ServiceManager.getService("window"));
2763                 mAppBindArgs.put(Context.ALARM_SERVICE,
2764                         ServiceManager.getService(Context.ALARM_SERVICE));
2765             }
2766         }
2767         return mAppBindArgs;
2768     }
2769
2770     boolean setFocusedActivityLocked(ActivityRecord r, String reason) {
2771         if (r == null || mFocusedActivity == r) {
2772             return false;
2773         }
2774
2775         if (!r.isFocusable()) {
2776             if (DEBUG_FOCUS) Slog.d(TAG_FOCUS, "setFocusedActivityLocked: unfocusable r=" + r);
2777             return false;
2778         }
2779
2780         if (DEBUG_FOCUS) Slog.d(TAG_FOCUS, "setFocusedActivityLocked: r=" + r);
2781
2782         final boolean wasDoingSetFocusedActivity = mDoingSetFocusedActivity;
2783         if (wasDoingSetFocusedActivity) Slog.w(TAG,
2784                 "setFocusedActivityLocked: called recursively, r=" + r + ", reason=" + reason);
2785         mDoingSetFocusedActivity = true;
2786
2787         final ActivityRecord last = mFocusedActivity;
2788         mFocusedActivity = r;
2789         if (r.task.isApplicationTask()) {
2790             if (mCurAppTimeTracker != r.appTimeTracker) {
2791                 // We are switching app tracking.  Complete the current one.
2792                 if (mCurAppTimeTracker != null) {
2793                     mCurAppTimeTracker.stop();
2794                     mHandler.obtainMessage(
2795                             REPORT_TIME_TRACKER_MSG, mCurAppTimeTracker).sendToTarget();
2796                     mStackSupervisor.clearOtherAppTimeTrackers(r.appTimeTracker);
2797                     mCurAppTimeTracker = null;
2798                 }
2799                 if (r.appTimeTracker != null) {
2800                     mCurAppTimeTracker = r.appTimeTracker;
2801                     startTimeTrackingFocusedActivityLocked();
2802                 }
2803             } else {
2804                 startTimeTrackingFocusedActivityLocked();
2805             }
2806         } else {
2807             r.appTimeTracker = null;
2808         }
2809         // TODO: VI Maybe r.task.voiceInteractor || r.voiceInteractor != null
2810         // TODO: Probably not, because we don't want to resume voice on switching
2811         // back to this activity
2812         if (r.task.voiceInteractor != null) {
2813             startRunningVoiceLocked(r.task.voiceSession, r.info.applicationInfo.uid);
2814         } else {
2815             finishRunningVoiceLocked();
2816             IVoiceInteractionSession session;
2817             if (last != null && ((session = last.task.voiceSession) != null
2818                     || (session = last.voiceSession) != null)) {
2819                 // We had been in a voice interaction session, but now focused has
2820                 // move to something different.  Just finish the session, we can't
2821                 // return to it and retain the proper state and synchronization with
2822                 // the voice interaction service.
2823                 finishVoiceTask(session);
2824             }
2825         }
2826         if (mStackSupervisor.moveActivityStackToFront(r, reason + " setFocusedActivity")) {
2827             mWindowManager.setFocusedApp(r.appToken, true);
2828         }
2829         applyUpdateLockStateLocked(r);
2830         applyUpdateVrModeLocked(r);
2831         if (mFocusedActivity.userId != mLastFocusedUserId) {
2832             mHandler.removeMessages(FOREGROUND_PROFILE_CHANGED_MSG);
2833             mHandler.obtainMessage(
2834                     FOREGROUND_PROFILE_CHANGED_MSG, mFocusedActivity.userId, 0).sendToTarget();
2835             mLastFocusedUserId = mFocusedActivity.userId;
2836         }
2837
2838         // Log a warning if the focused app is changed during the process. This could
2839         // indicate a problem of the focus setting logic!
2840         if (mFocusedActivity != r) Slog.w(TAG,
2841                 "setFocusedActivityLocked: r=" + r + " but focused to " + mFocusedActivity);
2842         mDoingSetFocusedActivity = wasDoingSetFocusedActivity;
2843
2844         EventLogTags.writeAmFocusedActivity(
2845                 mFocusedActivity == null ? -1 : mFocusedActivity.userId,
2846                 mFocusedActivity == null ? "NULL" : mFocusedActivity.shortComponentName,
2847                 reason);
2848         return true;
2849     }
2850
2851     final void resetFocusedActivityIfNeededLocked(ActivityRecord goingAway) {
2852         if (mFocusedActivity != goingAway) {
2853             return;
2854         }
2855
2856         final ActivityStack focusedStack = mStackSupervisor.getFocusedStack();
2857         if (focusedStack != null) {
2858             final ActivityRecord top = focusedStack.topActivity();
2859             if (top != null && top.userId != mLastFocusedUserId) {
2860                 mHandler.removeMessages(FOREGROUND_PROFILE_CHANGED_MSG);
2861                 mHandler.sendMessage(
2862                         mHandler.obtainMessage(FOREGROUND_PROFILE_CHANGED_MSG, top.userId, 0));
2863                 mLastFocusedUserId = top.userId;
2864             }
2865         }
2866
2867         // Try to move focus to another activity if possible.
2868         if (setFocusedActivityLocked(
2869                 focusedStack.topRunningActivityLocked(), "resetFocusedActivityIfNeeded")) {
2870             return;
2871         }
2872
2873         if (DEBUG_FOCUS) Slog.d(TAG_FOCUS, "resetFocusedActivityIfNeeded: Setting focus to NULL "
2874                 + "prev mFocusedActivity=" + mFocusedActivity + " goingAway=" + goingAway);
2875         mFocusedActivity = null;
2876         EventLogTags.writeAmFocusedActivity(-1, "NULL", "resetFocusedActivityIfNeeded");
2877     }
2878
2879     @Override
2880     public void setFocusedStack(int stackId) {
2881         enforceCallingPermission(MANAGE_ACTIVITY_STACKS, "setFocusedStack()");
2882         if (DEBUG_FOCUS) Slog.d(TAG_FOCUS, "setFocusedStack: stackId=" + stackId);
2883         final long callingId = Binder.clearCallingIdentity();
2884         try {
2885             synchronized (this) {
2886                 final ActivityStack stack = mStackSupervisor.getStack(stackId);
2887                 if (stack == null) {
2888                     return;
2889                 }
2890                 final ActivityRecord r = stack.topRunningActivityLocked();
2891                 if (setFocusedActivityLocked(r, "setFocusedStack")) {
2892                     mStackSupervisor.resumeFocusedStackTopActivityLocked();
2893                 }
2894             }
2895         } finally {
2896             Binder.restoreCallingIdentity(callingId);
2897         }
2898     }
2899
2900     @Override
2901     public void setFocusedTask(int taskId) {
2902         enforceCallingPermission(MANAGE_ACTIVITY_STACKS, "setFocusedTask()");
2903         if (DEBUG_FOCUS) Slog.d(TAG_FOCUS, "setFocusedTask: taskId=" + taskId);
2904         final long callingId = Binder.clearCallingIdentity();
2905         try {
2906             synchronized (this) {
2907                 final TaskRecord task = mStackSupervisor.anyTaskForIdLocked(taskId);
2908                 if (task == null) {
2909                     return;
2910                 }
2911                 final ActivityRecord r = task.topRunningActivityLocked();
2912                 if (setFocusedActivityLocked(r, "setFocusedTask")) {
2913                     mStackSupervisor.resumeFocusedStackTopActivityLocked();
2914                 }
2915             }
2916         } finally {
2917             Binder.restoreCallingIdentity(callingId);
2918         }
2919     }
2920
2921     /** Sets the task stack listener that gets callbacks when a task stack changes. */
2922     @Override
2923     public void registerTaskStackListener(ITaskStackListener listener) throws RemoteException {
2924         enforceCallingPermission(MANAGE_ACTIVITY_STACKS, "registerTaskStackListener()");
2925         synchronized (this) {
2926             if (listener != null) {
2927                 mTaskStackListeners.register(listener);
2928             }
2929         }
2930     }
2931
2932     @Override
2933     public void notifyActivityDrawn(IBinder token) {
2934         if (DEBUG_VISIBILITY) Slog.d(TAG_VISIBILITY, "notifyActivityDrawn: token=" + token);
2935         synchronized (this) {
2936             ActivityRecord r = mStackSupervisor.isInAnyStackLocked(token);
2937             if (r != null) {
2938                 r.task.stack.notifyActivityDrawnLocked(r);
2939             }
2940         }
2941     }
2942
2943     final void applyUpdateLockStateLocked(ActivityRecord r) {
2944         // Modifications to the UpdateLock state are done on our handler, outside
2945         // the activity manager's locks.  The new state is determined based on the
2946         // state *now* of the relevant activity record.  The object is passed to
2947         // the handler solely for logging detail, not to be consulted/modified.
2948         final boolean nextState = r != null && r.immersive;
2949         mHandler.sendMessage(
2950                 mHandler.obtainMessage(IMMERSIVE_MODE_LOCK_MSG, (nextState) ? 1 : 0, 0, r));
2951     }
2952
2953     final void applyUpdateVrModeLocked(ActivityRecord r) {
2954         mHandler.sendMessage(
2955                 mHandler.obtainMessage(VR_MODE_CHANGE_MSG, 0, 0, r));
2956     }
2957
2958     final void showAskCompatModeDialogLocked(ActivityRecord r) {
2959         Message msg = Message.obtain();
2960         msg.what = SHOW_COMPAT_MODE_DIALOG_UI_MSG;
2961         msg.obj = r.task.askedCompatMode ? null : r;
2962         mUiHandler.sendMessage(msg);
2963     }
2964
2965     private int updateLruProcessInternalLocked(ProcessRecord app, long now, int index,
2966             String what, Object obj, ProcessRecord srcApp) {
2967         app.lastActivityTime = now;
2968
2969         if (app.activities.size() > 0) {
2970             // Don't want to touch dependent processes that are hosting activities.
2971             return index;
2972         }
2973
2974         int lrui = mLruProcesses.lastIndexOf(app);
2975         if (lrui < 0) {
2976             Slog.wtf(TAG, "Adding dependent process " + app + " not on LRU list: "
2977                     + what + " " + obj + " from " + srcApp);
2978             return index;
2979         }
2980
2981         if (lrui >= index) {
2982             // Don't want to cause this to move dependent processes *back* in the
2983             // list as if they were less frequently used.
2984             return index;
2985         }
2986
2987         if (lrui >= mLruProcessActivityStart) {
2988             // Don't want to touch dependent processes that are hosting activities.
2989             return index;
2990         }
2991
2992         mLruProcesses.remove(lrui);
2993         if (index > 0) {
2994             index--;
2995         }
2996         if (DEBUG_LRU) Slog.d(TAG_LRU, "Moving dep from " + lrui + " to " + index
2997                 + " in LRU list: " + app);
2998         mLruProcesses.add(index, app);
2999         return index;
3000     }
3001
3002     static void killProcessGroup(int uid, int pid) {
3003         Trace.traceBegin(Trace.TRACE_TAG_ACTIVITY_MANAGER, "killProcessGroup");
3004         Process.killProcessGroup(uid, pid);
3005         Trace.traceEnd(Trace.TRACE_TAG_ACTIVITY_MANAGER);
3006     }
3007
3008     final void removeLruProcessLocked(ProcessRecord app) {
3009         int lrui = mLruProcesses.lastIndexOf(app);
3010         if (lrui >= 0) {
3011             if (!app.killed) {
3012                 Slog.wtfStack(TAG, "Removing process that hasn't been killed: " + app);
3013                 Process.killProcessQuiet(app.pid);
3014                 killProcessGroup(app.info.uid, app.pid);
3015             }
3016             if (lrui <= mLruProcessActivityStart) {
3017                 mLruProcessActivityStart--;
3018             }
3019             if (lrui <= mLruProcessServiceStart) {
3020                 mLruProcessServiceStart--;
3021             }
3022             mLruProcesses.remove(lrui);
3023         }
3024     }
3025
3026     final void updateLruProcessLocked(ProcessRecord app, boolean activityChange,
3027             ProcessRecord client) {
3028         final boolean hasActivity = app.activities.size() > 0 || app.hasClientActivities
3029                 || app.treatLikeActivity;
3030         final boolean hasService = false; // not impl yet. app.services.size() > 0;
3031         if (!activityChange && hasActivity) {
3032             // The process has activities, so we are only allowing activity-based adjustments
3033             // to move it.  It should be kept in the front of the list with other
3034             // processes that have activities, and we don't want those to change their
3035             // order except due to activity operations.
3036             return;
3037         }
3038
3039         mLruSeq++;
3040         final long now = SystemClock.uptimeMillis();
3041         app.lastActivityTime = now;
3042
3043         // First a quick reject: if the app is already at the position we will
3044         // put it, then there is nothing to do.
3045         if (hasActivity) {
3046             final int N = mLruProcesses.size();
3047             if (N > 0 && mLruProcesses.get(N-1) == app) {
3048                 if (DEBUG_LRU) Slog.d(TAG_LRU, "Not moving, already top activity: " + app);
3049                 return;
3050             }
3051         } else {
3052             if (mLruProcessServiceStart > 0
3053                     && mLruProcesses.get(mLruProcessServiceStart-1) == app) {
3054                 if (DEBUG_LRU) Slog.d(TAG_LRU, "Not moving, already top other: " + app);
3055                 return;
3056             }
3057         }
3058
3059         int lrui = mLruProcesses.lastIndexOf(app);
3060
3061         if (app.persistent && lrui >= 0) {
3062             // We don't care about the position of persistent processes, as long as
3063             // they are in the list.
3064             if (DEBUG_LRU) Slog.d(TAG_LRU, "Not moving, persistent: " + app);
3065             return;
3066         }
3067
3068         /* In progress: compute new position first, so we can avoid doing work
3069            if the process is not actually going to move.  Not yet working.
3070         int addIndex;
3071         int nextIndex;
3072         boolean inActivity = false, inService = false;
3073         if (hasActivity) {
3074             // Process has activities, put it at the very tipsy-top.
3075             addIndex = mLruProcesses.size();
3076             nextIndex = mLruProcessServiceStart;
3077             inActivity = true;
3078         } else if (hasService) {
3079             // Process has services, put it at the top of the service list.
3080             addIndex = mLruProcessActivityStart;
3081             nextIndex = mLruProcessServiceStart;
3082             inActivity = true;
3083             inService = true;
3084         } else  {
3085             // Process not otherwise of interest, it goes to the top of the non-service area.
3086             addIndex = mLruProcessServiceStart;
3087             if (client != null) {
3088                 int clientIndex = mLruProcesses.lastIndexOf(client);
3089                 if (clientIndex < 0) Slog.d(TAG, "Unknown client " + client + " when updating "
3090                         + app);
3091                 if (clientIndex >= 0 && addIndex > clientIndex) {
3092                     addIndex = clientIndex;
3093                 }
3094             }
3095             nextIndex = addIndex > 0 ? addIndex-1 : addIndex;
3096         }
3097
3098         Slog.d(TAG, "Update LRU at " + lrui + " to " + addIndex + " (act="
3099                 + mLruProcessActivityStart + "): " + app);
3100         */
3101
3102         if (lrui >= 0) {
3103             if (lrui < mLruProcessActivityStart) {
3104                 mLruProcessActivityStart--;
3105             }
3106             if (lrui < mLruProcessServiceStart) {
3107                 mLruProcessServiceStart--;
3108             }
3109             /*
3110             if (addIndex > lrui) {
3111                 addIndex--;
3112             }
3113             if (nextIndex > lrui) {
3114                 nextIndex--;
3115             }
3116             */
3117             mLruProcesses.remove(lrui);
3118         }
3119
3120         /*
3121         mLruProcesses.add(addIndex, app);
3122         if (inActivity) {
3123             mLruProcessActivityStart++;
3124         }
3125         if (inService) {
3126             mLruProcessActivityStart++;
3127         }
3128         */
3129
3130         int nextIndex;
3131         if (hasActivity) {
3132             final int N = mLruProcesses.size();
3133             if (app.activities.size() == 0 && mLruProcessActivityStart < (N - 1)) {
3134                 // Process doesn't have activities, but has clients with
3135                 // activities...  move it up, but one below the top (the top
3136                 // should always have a real activity).
3137                 if (DEBUG_LRU) Slog.d(TAG_LRU,
3138                         "Adding to second-top of LRU activity list: " + app);
3139                 mLruProcesses.add(N - 1, app);
3140                 // To keep it from spamming the LRU list (by making a bunch of clients),
3141                 // we will push down any other entries owned by the app.
3142                 final int uid = app.info.uid;
3143                 for (int i = N - 2; i > mLruProcessActivityStart; i--) {
3144                     ProcessRecord subProc = mLruProcesses.get(i);
3145                     if (subProc.info.uid == uid) {
3146                         // We want to push this one down the list.  If the process after
3147                         // it is for the same uid, however, don't do so, because we don't
3148                         // want them internally to be re-ordered.
3149                         if (mLruProcesses.get(i - 1).info.uid != uid) {
3150                             if (DEBUG_LRU) Slog.d(TAG_LRU,
3151                                     "Pushing uid " + uid + " swapping at " + i + ": "
3152                                     + mLruProcesses.get(i) + " : " + mLruProcesses.get(i - 1));
3153                             ProcessRecord tmp = mLruProcesses.get(i);
3154                             mLruProcesses.set(i, mLruProcesses.get(i - 1));
3155                             mLruProcesses.set(i - 1, tmp);
3156                             i--;
3157                         }
3158                     } else {
3159                         // A gap, we can stop here.
3160                         break;
3161                     }
3162                 }
3163             } else {
3164                 // Process has activities, put it at the very tipsy-top.
3165                 if (DEBUG_LRU) Slog.d(TAG_LRU, "Adding to top of LRU activity list: " + app);
3166                 mLruProcesses.add(app);
3167             }
3168             nextIndex = mLruProcessServiceStart;
3169         } else if (hasService) {
3170             // Process has services, put it at the top of the service list.
3171             if (DEBUG_LRU) Slog.d(TAG_LRU, "Adding to top of LRU service list: " + app);
3172             mLruProcesses.add(mLruProcessActivityStart, app);
3173             nextIndex = mLruProcessServiceStart;
3174             mLruProcessActivityStart++;
3175         } else  {
3176             // Process not otherwise of interest, it goes to the top of the non-service area.
3177             int index = mLruProcessServiceStart;
3178             if (client != null) {
3179                 // If there is a client, don't allow the process to be moved up higher
3180                 // in the list than that client.
3181                 int clientIndex = mLruProcesses.lastIndexOf(client);
3182                 if (DEBUG_LRU && clientIndex < 0) Slog.d(TAG_LRU, "Unknown client " + client
3183                         + " when updating " + app);
3184                 if (clientIndex <= lrui) {
3185                     // Don't allow the client index restriction to push it down farther in the
3186                     // list than it already is.
3187                     clientIndex = lrui;
3188                 }
3189                 if (clientIndex >= 0 && index > clientIndex) {
3190                     index = clientIndex;
3191                 }
3192             }
3193             if (DEBUG_LRU) Slog.d(TAG_LRU, "Adding at " + index + " of LRU list: " + app);
3194             mLruProcesses.add(index, app);
3195             nextIndex = index-1;
3196             mLruProcessActivityStart++;
3197             mLruProcessServiceStart++;
3198         }
3199
3200         // If the app is currently using a content provider or service,
3201         // bump those processes as well.
3202         for (int j=app.connections.size()-1; j>=0; j--) {
3203             ConnectionRecord cr = app.connections.valueAt(j);
3204             if (cr.binding != null && !cr.serviceDead && cr.binding.service != null
3205                     && cr.binding.service.app != null
3206                     && cr.binding.service.app.lruSeq != mLruSeq
3207                     && !cr.binding.service.app.persistent) {
3208                 nextIndex = updateLruProcessInternalLocked(cr.binding.service.app, now, nextIndex,
3209                         "service connection", cr, app);
3210             }
3211         }
3212         for (int j=app.conProviders.size()-1; j>=0; j--) {
3213             ContentProviderRecord cpr = app.conProviders.get(j).provider;
3214             if (cpr.proc != null && cpr.proc.lruSeq != mLruSeq && !cpr.proc.persistent) {
3215                 nextIndex = updateLruProcessInternalLocked(cpr.proc, now, nextIndex,
3216                         "provider reference", cpr, app);
3217             }
3218         }
3219     }
3220
3221     final ProcessRecord getProcessRecordLocked(String processName, int uid, boolean keepIfLarge) {
3222         if (uid == Process.SYSTEM_UID) {
3223             // The system gets to run in any process.  If there are multiple
3224             // processes with the same uid, just pick the first (this
3225             // should never happen).
3226             SparseArray<ProcessRecord> procs = mProcessNames.getMap().get(processName);
3227             if (procs == null) return null;
3228             final int procCount = procs.size();
3229             for (int i = 0; i < procCount; i++) {
3230                 final int procUid = procs.keyAt(i);
3231                 if (UserHandle.isApp(procUid) || !UserHandle.isSameUser(procUid, uid)) {
3232                     // Don't use an app process or different user process for system component.
3233                     continue;
3234                 }
3235                 return procs.valueAt(i);
3236             }
3237         }
3238         ProcessRecord proc = mProcessNames.get(processName, uid);
3239         if (false && proc != null && !keepIfLarge
3240                 && proc.setProcState >= ActivityManager.PROCESS_STATE_CACHED_EMPTY
3241                 && proc.lastCachedPss >= 4000) {
3242             // Turn this condition on to cause killing to happen regularly, for testing.
3243             if (proc.baseProcessTracker != null) {
3244                 proc.baseProcessTracker.reportCachedKill(proc.pkgList, proc.lastCachedPss);
3245             }
3246             proc.kill(Long.toString(proc.lastCachedPss) + "k from cached", true);
3247         } else if (proc != null && !keepIfLarge
3248                 && mLastMemoryLevel > ProcessStats.ADJ_MEM_FACTOR_NORMAL
3249                 && proc.setProcState >= ActivityManager.PROCESS_STATE_CACHED_EMPTY) {
3250             if (DEBUG_PSS) Slog.d(TAG_PSS, "May not keep " + proc + ": pss=" + proc.lastCachedPss);
3251             if (proc.lastCachedPss >= mProcessList.getCachedRestoreThresholdKb()) {
3252                 if (proc.baseProcessTracker != null) {
3253                     proc.baseProcessTracker.reportCachedKill(proc.pkgList, proc.lastCachedPss);
3254                 }
3255                 proc.kill(Long.toString(proc.lastCachedPss) + "k from cached", true);
3256             }
3257         }
3258         return proc;
3259     }
3260
3261     void notifyPackageUse(String packageName) {
3262         IPackageManager pm = AppGlobals.getPackageManager();
3263         try {
3264             pm.notifyPackageUse(packageName);
3265         } catch (RemoteException e) {
3266         }
3267     }
3268
3269     boolean isNextTransitionForward() {
3270         int transit = mWindowManager.getPendingAppTransition();
3271         return transit == TRANSIT_ACTIVITY_OPEN
3272                 || transit == TRANSIT_TASK_OPEN
3273                 || transit == TRANSIT_TASK_TO_FRONT;
3274     }
3275
3276     int startIsolatedProcess(String entryPoint, String[] entryPointArgs,
3277             String processName, String abiOverride, int uid, Runnable crashHandler) {
3278         synchronized(this) {
3279             ApplicationInfo info = new ApplicationInfo();
3280             // In general the ApplicationInfo.uid isn't neccesarily equal to ProcessRecord.uid.
3281             // For isolated processes, the former contains the parent's uid and the latter the
3282             // actual uid of the isolated process.
3283             // In the special case introduced by this method (which is, starting an isolated
3284             // process directly from the SystemServer without an actual parent app process) the
3285             // closest thing to a parent's uid is SYSTEM_UID.
3286             // The only important thing here is to keep AI.uid != PR.uid, in order to trigger
3287             // the |isolated| logic in the ProcessRecord constructor.
3288             info.uid = Process.SYSTEM_UID;
3289             info.processName = processName;
3290             info.className = entryPoint;
3291             info.packageName = "android";
3292             ProcessRecord proc = startProcessLocked(processName, info /* info */,
3293                     false /* knownToBeDead */, 0 /* intentFlags */, ""  /* hostingType */,
3294                     null /* hostingName */, true /* allowWhileBooting */, true /* isolated */,
3295                     uid, true /* keepIfLarge */, abiOverride, entryPoint, entryPointArgs,
3296                     crashHandler);
3297             return proc != null ? proc.pid : 0;
3298         }
3299     }
3300
3301     final ProcessRecord startProcessLocked(String processName,
3302             ApplicationInfo info, boolean knownToBeDead, int intentFlags,
3303             String hostingType, ComponentName hostingName, boolean allowWhileBooting,
3304             boolean isolated, boolean keepIfLarge) {
3305         return startProcessLocked(processName, info, knownToBeDead, intentFlags, hostingType,
3306                 hostingName, allowWhileBooting, isolated, 0 /* isolatedUid */, keepIfLarge,
3307                 null /* ABI override */, null /* entryPoint */, null /* entryPointArgs */,
3308                 null /* crashHandler */);
3309     }
3310
3311     final ProcessRecord startProcessLocked(String processName, ApplicationInfo info,
3312             boolean knownToBeDead, int intentFlags, String hostingType, ComponentName hostingName,
3313             boolean allowWhileBooting, boolean isolated, int isolatedUid, boolean keepIfLarge,
3314             String abiOverride, String entryPoint, String[] entryPointArgs, Runnable crashHandler) {
3315         long startTime = SystemClock.elapsedRealtime();
3316         ProcessRecord app;
3317         if (!isolated) {
3318             app = getProcessRecordLocked(processName, info.uid, keepIfLarge);
3319             checkTime(startTime, "startProcess: after getProcessRecord");
3320
3321             if ((intentFlags & Intent.FLAG_FROM_BACKGROUND) != 0) {
3322                 // If we are in the background, then check to see if this process
3323                 // is bad.  If so, we will just silently fail.
3324                 if (mAppErrors.isBadProcessLocked(info)) {
3325                     if (DEBUG_PROCESSES) Slog.v(TAG, "Bad process: " + info.uid
3326                             + "/" + info.processName);
3327                     return null;
3328                 }
3329             } else {
3330                 // When the user is explicitly starting a process, then clear its
3331                 // crash count so that we won't make it bad until they see at
3332                 // least one crash dialog again, and make the process good again
3333                 // if it had been bad.
3334                 if (DEBUG_PROCESSES) Slog.v(TAG, "Clearing bad process: " + info.uid
3335                         + "/" + info.processName);
3336                 mAppErrors.resetProcessCrashTimeLocked(info);
3337                 if (mAppErrors.isBadProcessLocked(info)) {
3338                     EventLog.writeEvent(EventLogTags.AM_PROC_GOOD,
3339                             UserHandle.getUserId(info.uid), info.uid,
3340                             info.processName);
3341                     mAppErrors.clearBadProcessLocked(info);
3342                     if (app != null) {
3343                         app.bad = false;
3344                     }
3345                 }
3346             }
3347         } else {
3348             // If this is an isolated process, it can't re-use an existing process.
3349             app = null;
3350         }
3351
3352         // app launch boost for big.little configurations
3353         // use cpusets to migrate freshly launched tasks to big cores
3354         synchronized(ActivityManagerService.this) {
3355             nativeMigrateToBoost();
3356             mIsBoosted = true;
3357             mBoostStartTime = SystemClock.uptimeMillis();
3358             Message msg = mHandler.obtainMessage(APP_BOOST_DEACTIVATE_MSG);
3359             mHandler.sendMessageDelayed(msg, APP_BOOST_MESSAGE_DELAY);
3360         }
3361
3362         // We don't have to do anything more if:
3363         // (1) There is an existing application record; and
3364         // (2) The caller doesn't think it is dead, OR there is no thread
3365         //     object attached to it so we know it couldn't have crashed; and
3366         // (3) There is a pid assigned to it, so it is either starting or
3367         //     already running.
3368         if (DEBUG_PROCESSES) Slog.v(TAG_PROCESSES, "startProcess: name=" + processName
3369                 + " app=" + app + " knownToBeDead=" + knownToBeDead
3370                 + " thread=" + (app != null ? app.thread : null)
3371                 + " pid=" + (app != null ? app.pid : -1));
3372         if (app != null && app.pid > 0) {
3373             if (!knownToBeDead || app.thread == null) {
3374                 // We already have the app running, or are waiting for it to
3375                 // come up (we have a pid but not yet its thread), so keep it.
3376                 if (DEBUG_PROCESSES) Slog.v(TAG_PROCESSES, "App already running: " + app);
3377                 // If this is a new package in the process, add the package to the list
3378                 app.addPackage(info.packageName, info.versionCode, mProcessStats);
3379                 checkTime(startTime, "startProcess: done, added package to proc");
3380                 return app;
3381             }
3382
3383             // An application record is attached to a previous process,
3384             // clean it up now.
3385             if (DEBUG_PROCESSES || DEBUG_CLEANUP) Slog.v(TAG_PROCESSES, "App died: " + app);
3386             checkTime(startTime, "startProcess: bad proc running, killing");
3387             killProcessGroup(app.info.uid, app.pid);
3388             handleAppDiedLocked(app, true, true);
3389             checkTime(startTime, "startProcess: done killing old proc");
3390         }
3391
3392         String hostingNameStr = hostingName != null
3393                 ? hostingName.flattenToShortString() : null;
3394
3395         if (app == null) {
3396             checkTime(startTime, "startProcess: creating new process record");
3397             app = newProcessRecordLocked(info, processName, isolated, isolatedUid);
3398             if (app == null) {
3399                 Slog.w(TAG, "Failed making new process record for "
3400                         + processName + "/" + info.uid + " isolated=" + isolated);
3401                 return null;
3402             }
3403             app.crashHandler = crashHandler;
3404             checkTime(startTime, "startProcess: done creating new process record");
3405         } else {
3406             // If this is a new package in the process, add the package to the list
3407             app.addPackage(info.packageName, info.versionCode, mProcessStats);
3408             checkTime(startTime, "startProcess: added package to existing proc");
3409         }
3410
3411         // If the system is not ready yet, then hold off on starting this
3412         // process until it is.
3413         if (!mProcessesReady
3414                 && !isAllowedWhileBooting(info)
3415                 && !allowWhileBooting) {
3416             if (!mProcessesOnHold.contains(app)) {
3417                 mProcessesOnHold.add(app);
3418             }
3419             if (DEBUG_PROCESSES) Slog.v(TAG_PROCESSES,
3420                     "System not ready, putting on hold: " + app);
3421             checkTime(startTime, "startProcess: returning with proc on hold");
3422             return app;
3423         }
3424
3425         checkTime(startTime, "startProcess: stepping in to startProcess");
3426         startProcessLocked(
3427                 app, hostingType, hostingNameStr, abiOverride, entryPoint, entryPointArgs);
3428         checkTime(startTime, "startProcess: done starting proc!");
3429         return (app.pid != 0) ? app : null;
3430     }
3431
3432     boolean isAllowedWhileBooting(ApplicationInfo ai) {
3433         return (ai.flags&ApplicationInfo.FLAG_PERSISTENT) != 0;
3434     }
3435
3436     private final void startProcessLocked(ProcessRecord app,
3437             String hostingType, String hostingNameStr) {
3438         startProcessLocked(app, hostingType, hostingNameStr, null /* abiOverride */,
3439                 null /* entryPoint */, null /* entryPointArgs */);
3440     }
3441
3442     private final void startProcessLocked(ProcessRecord app, String hostingType,
3443             String hostingNameStr, String abiOverride, String entryPoint, String[] entryPointArgs) {
3444         long startTime = SystemClock.elapsedRealtime();
3445         if (app.pid > 0 && app.pid != MY_PID) {
3446             checkTime(startTime, "startProcess: removing from pids map");
3447             synchronized (mPidsSelfLocked) {
3448                 mPidsSelfLocked.remove(app.pid);
3449                 mHandler.removeMessages(PROC_START_TIMEOUT_MSG, app);
3450             }
3451             checkTime(startTime, "startProcess: done removing from pids map");
3452             app.setPid(0);
3453         }
3454
3455         if (DEBUG_PROCESSES && mProcessesOnHold.contains(app)) Slog.v(TAG_PROCESSES,
3456                 "startProcessLocked removing on hold: " + app);
3457         mProcessesOnHold.remove(app);
3458
3459         checkTime(startTime, "startProcess: starting to update cpu stats");
3460         updateCpuStats();
3461         checkTime(startTime, "startProcess: done updating cpu stats");
3462
3463         try {
3464             try {
3465                 final int userId = UserHandle.getUserId(app.uid);
3466                 AppGlobals.getPackageManager().checkPackageStartable(app.info.packageName, userId);
3467             } catch (RemoteException e) {
3468                 throw e.rethrowAsRuntimeException();
3469             }
3470
3471             int uid = app.uid;
3472             int[] gids = null;
3473             int mountExternal = Zygote.MOUNT_EXTERNAL_NONE;
3474             if (!app.isolated) {
3475                 int[] permGids = null;
3476                 try {
3477                     checkTime(startTime, "startProcess: getting gids from package manager");
3478                     final IPackageManager pm = AppGlobals.getPackageManager();
3479                     permGids = pm.getPackageGids(app.info.packageName,
3480                             MATCH_DEBUG_TRIAGED_MISSING, app.userId);
3481                     MountServiceInternal mountServiceInternal = LocalServices.getService(
3482                             MountServiceInternal.class);
3483                     mountExternal = mountServiceInternal.getExternalStorageMountMode(uid,
3484                             app.info.packageName);
3485                 } catch (RemoteException e) {
3486                     throw e.rethrowAsRuntimeException();
3487                 }
3488
3489                 /*
3490                  * Add shared application and profile GIDs so applications can share some
3491                  * resources like shared libraries and access user-wide resources
3492                  */
3493                 if (ArrayUtils.isEmpty(permGids)) {
3494                     gids = new int[2];
3495                 } else {
3496                     gids = new int[permGids.length + 2];
3497                     System.arraycopy(permGids, 0, gids, 2, permGids.length);
3498                 }
3499                 gids[0] = UserHandle.getSharedAppGid(UserHandle.getAppId(uid));
3500                 gids[1] = UserHandle.getUserGid(UserHandle.getUserId(uid));
3501             }
3502             checkTime(startTime, "startProcess: building args");
3503             if (mFactoryTest != FactoryTest.FACTORY_TEST_OFF) {
3504                 if (mFactoryTest == FactoryTest.FACTORY_TEST_LOW_LEVEL
3505                         && mTopComponent != null
3506                         && app.processName.equals(mTopComponent.getPackageName())) {
3507                     uid = 0;
3508                 }
3509                 if (mFactoryTest == FactoryTest.FACTORY_TEST_HIGH_LEVEL
3510                         && (app.info.flags&ApplicationInfo.FLAG_FACTORY_TEST) != 0) {
3511                     uid = 0;
3512                 }
3513             }
3514             int debugFlags = 0;
3515             if ((app.info.flags & ApplicationInfo.FLAG_DEBUGGABLE) != 0) {
3516                 debugFlags |= Zygote.DEBUG_ENABLE_DEBUGGER;
3517                 // Also turn on CheckJNI for debuggable apps. It's quite
3518                 // awkward to turn on otherwise.
3519                 debugFlags |= Zygote.DEBUG_ENABLE_CHECKJNI;
3520             }
3521             // Run the app in safe mode if its manifest requests so or the
3522             // system is booted in safe mode.
3523             if ((app.info.flags & ApplicationInfo.FLAG_VM_SAFE_MODE) != 0 ||
3524                 mSafeMode == true) {
3525                 debugFlags |= Zygote.DEBUG_ENABLE_SAFEMODE;
3526             }
3527             if ("1".equals(SystemProperties.get("debug.checkjni"))) {
3528                 debugFlags |= Zygote.DEBUG_ENABLE_CHECKJNI;
3529             }
3530             String genDebugInfoProperty = SystemProperties.get("debug.generate-debug-info");
3531             if ("true".equals(genDebugInfoProperty)) {
3532                 debugFlags |= Zygote.DEBUG_GENERATE_DEBUG_INFO;
3533             }
3534             if ("1".equals(SystemProperties.get("debug.jni.logging"))) {
3535                 debugFlags |= Zygote.DEBUG_ENABLE_JNI_LOGGING;
3536             }
3537             if ("1".equals(SystemProperties.get("debug.assert"))) {
3538                 debugFlags |= Zygote.DEBUG_ENABLE_ASSERT;
3539             }
3540             if (mNativeDebuggingApp != null && mNativeDebuggingApp.equals(app.processName)) {
3541                 // Enable all debug flags required by the native debugger.
3542                 debugFlags |= Zygote.DEBUG_ALWAYS_JIT;          // Don't interpret anything
3543                 debugFlags |= Zygote.DEBUG_GENERATE_DEBUG_INFO; // Generate debug info
3544                 debugFlags |= Zygote.DEBUG_NATIVE_DEBUGGABLE;   // Disbale optimizations
3545                 mNativeDebuggingApp = null;
3546             }
3547
3548             String requiredAbi = (abiOverride != null) ? abiOverride : app.info.primaryCpuAbi;
3549             if (requiredAbi == null) {
3550                 requiredAbi = Build.SUPPORTED_ABIS[0];
3551             }
3552
3553             String instructionSet = null;
3554             if (app.info.primaryCpuAbi != null) {
3555                 instructionSet = VMRuntime.getInstructionSet(app.info.primaryCpuAbi);
3556             }
3557
3558             app.gids = gids;
3559             app.requiredAbi = requiredAbi;
3560             app.instructionSet = instructionSet;
3561
3562             // Start the process.  It will either succeed and return a result containing
3563             // the PID of the new process, or else throw a RuntimeException.
3564             boolean isActivityProcess = (entryPoint == null);
3565             if (entryPoint == null) entryPoint = "android.app.ActivityThread";
3566             Trace.traceBegin(Trace.TRACE_TAG_ACTIVITY_MANAGER, "Start proc: " +
3567                     app.processName);
3568             checkTime(startTime, "startProcess: asking zygote to start proc");
3569             Process.ProcessStartResult startResult = Process.start(entryPoint,
3570                     app.processName, uid, uid, gids, debugFlags, mountExternal,
3571                     app.info.targetSdkVersion, app.info.seinfo, requiredAbi, instructionSet,
3572                     app.info.dataDir, entryPointArgs);
3573             checkTime(startTime, "startProcess: returned from zygote!");
3574             Trace.traceEnd(Trace.TRACE_TAG_ACTIVITY_MANAGER);
3575
3576             if (app.isolated) {
3577                 mBatteryStatsService.addIsolatedUid(app.uid, app.info.uid);
3578             }
3579             mBatteryStatsService.noteProcessStart(app.processName, app.info.uid);
3580             checkTime(startTime, "startProcess: done updating battery stats");
3581
3582             EventLog.writeEvent(EventLogTags.AM_PROC_START,
3583                     UserHandle.getUserId(uid), startResult.pid, uid,
3584                     app.processName, hostingType,
3585                     hostingNameStr != null ? hostingNameStr : "");
3586
3587             mProcessStartLogger.logIfNeededLocked(app, startResult);
3588
3589             if (app.persistent) {
3590                 Watchdog.getInstance().processStarted(app.processName, startResult.pid);
3591             }
3592
3593             if (DEBUG_PROCESSES) {
3594                 checkTime(startTime, "startProcess: building log message");
3595                 StringBuilder buf = mStringBuilder;
3596                 buf.setLength(0);
3597                 buf.append("Start proc ");
3598                 buf.append(startResult.pid);
3599                 buf.append(':');
3600                 buf.append(app.processName);
3601                 buf.append('/');
3602                 UserHandle.formatUid(buf, uid);
3603                 if (!isActivityProcess) {
3604                     buf.append(" [");
3605                     buf.append(entryPoint);
3606                     buf.append("]");
3607                 }
3608                 buf.append(" for ");
3609                 buf.append(hostingType);
3610                 if (hostingNameStr != null) {
3611                     buf.append(" ");
3612                     buf.append(hostingNameStr);
3613                 }
3614                 Slog.i(TAG, buf.toString());
3615             }
3616             app.setPid(startResult.pid);
3617             app.usingWrapper = startResult.usingWrapper;
3618             app.removed = false;
3619             app.killed = false;
3620             app.killedByAm = false;
3621             checkTime(startTime, "startProcess: starting to update pids map");
3622             synchronized (mPidsSelfLocked) {
3623                 this.mPidsSelfLocked.put(startResult.pid, app);
3624                 if (isActivityProcess) {
3625                     Message msg = mHandler.obtainMessage(PROC_START_TIMEOUT_MSG);
3626                     msg.obj = app;
3627                     mHandler.sendMessageDelayed(msg, startResult.usingWrapper
3628                             ? PROC_START_TIMEOUT_WITH_WRAPPER : PROC_START_TIMEOUT);
3629                 }
3630             }
3631             checkTime(startTime, "startProcess: done updating pids map");
3632         } catch (RuntimeException e) {
3633             // XXX do better error recovery.
3634             app.setPid(0);
3635             mBatteryStatsService.noteProcessFinish(app.processName, app.info.uid);
3636             if (app.isolated) {
3637                 mBatteryStatsService.removeIsolatedUid(app.uid, app.info.uid);
3638             }
3639             Slog.e(TAG, "Failure starting process " + app.processName, e);
3640         }
3641     }
3642
3643     void updateUsageStats(ActivityRecord component, boolean resumed) {
3644         if (DEBUG_SWITCH) Slog.d(TAG_SWITCH,
3645                 "updateUsageStats: comp=" + component + "res=" + resumed);
3646         final BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
3647         if (resumed) {
3648             if (mUsageStatsService != null) {
3649                 mUsageStatsService.reportEvent(component.realActivity, component.userId,
3650                         UsageEvents.Event.MOVE_TO_FOREGROUND);
3651             }
3652             synchronized (stats) {
3653                 stats.noteActivityResumedLocked(component.app.uid);
3654             }
3655         } else {
3656             if (mUsageStatsService != null) {
3657                 mUsageStatsService.reportEvent(component.realActivity, component.userId,
3658                         UsageEvents.Event.MOVE_TO_BACKGROUND);
3659             }
3660             synchronized (stats) {
3661                 stats.noteActivityPausedLocked(component.app.uid);
3662             }
3663         }
3664     }
3665
3666     Intent getHomeIntent() {
3667         Intent intent = new Intent(mTopAction, mTopData != null ? Uri.parse(mTopData) : null);
3668         intent.setComponent(mTopComponent);
3669         intent.addFlags(Intent.FLAG_DEBUG_TRIAGED_MISSING);
3670         if (mFactoryTest != FactoryTest.FACTORY_TEST_LOW_LEVEL) {
3671             intent.addCategory(Intent.CATEGORY_HOME);
3672         }
3673         return intent;
3674     }
3675
3676     boolean startHomeActivityLocked(int userId, String reason) {
3677         if (mFactoryTest == FactoryTest.FACTORY_TEST_LOW_LEVEL
3678                 && mTopAction == null) {
3679             // We are running in factory test mode, but unable to find
3680             // the factory test app, so just sit around displaying the
3681             // error message and don't try to start anything.
3682             return false;
3683         }
3684         Intent intent = getHomeIntent();
3685         ActivityInfo aInfo = resolveActivityInfo(intent, STOCK_PM_FLAGS, userId);
3686         if (aInfo != null) {
3687             intent.setComponent(new ComponentName(aInfo.applicationInfo.packageName, aInfo.name));
3688             // Don't do this if the home app is currently being
3689             // instrumented.
3690             aInfo = new ActivityInfo(aInfo);
3691             aInfo.applicationInfo = getAppInfoForUser(aInfo.applicationInfo, userId);
3692             ProcessRecord app = getProcessRecordLocked(aInfo.processName,
3693                     aInfo.applicationInfo.uid, true);
3694             if (app == null || app.instrumentationClass == null) {
3695                 intent.setFlags(intent.getFlags() | Intent.FLAG_ACTIVITY_NEW_TASK);
3696                 mActivityStarter.startHomeActivityLocked(intent, aInfo, reason);
3697             }
3698         }
3699
3700         return true;
3701     }
3702
3703     private ActivityInfo resolveActivityInfo(Intent intent, int flags, int userId) {
3704         ActivityInfo ai = null;
3705         ComponentName comp = intent.getComponent();
3706         try {
3707             if (comp != null) {
3708                 // Factory test.
3709                 ai = AppGlobals.getPackageManager().getActivityInfo(comp, flags, userId);
3710             } else {
3711                 ResolveInfo info = AppGlobals.getPackageManager().resolveIntent(
3712                         intent,
3713                         intent.resolveTypeIfNeeded(mContext.getContentResolver()),
3714                         flags, userId);
3715
3716                 if (info != null) {
3717                     ai = info.activityInfo;
3718                 }
3719             }
3720         } catch (RemoteException e) {
3721             // ignore
3722         }
3723
3724         return ai;
3725     }
3726
3727     /**
3728      * Starts the "new version setup screen" if appropriate.
3729      */
3730     void startSetupActivityLocked() {
3731         // Only do this once per boot.
3732         if (mCheckedForSetup) {
3733             return;
3734         }
3735
3736         // We will show this screen if the current one is a different
3737         // version than the last one shown, and we are not running in
3738         // low-level factory test mode.
3739         final ContentResolver resolver = mContext.getContentResolver();
3740         if (mFactoryTest != FactoryTest.FACTORY_TEST_LOW_LEVEL &&
3741                 Settings.Global.getInt(resolver,
3742                         Settings.Global.DEVICE_PROVISIONED, 0) != 0) {
3743             mCheckedForSetup = true;
3744
3745             // See if we should be showing the platform update setup UI.
3746             final Intent intent = new Intent(Intent.ACTION_UPGRADE_SETUP);
3747             final List<ResolveInfo> ris = mContext.getPackageManager().queryIntentActivities(intent,
3748                     PackageManager.MATCH_SYSTEM_ONLY | PackageManager.GET_META_DATA);
3749             if (!ris.isEmpty()) {
3750                 final ResolveInfo ri = ris.get(0);
3751                 String vers = ri.activityInfo.metaData != null
3752                         ? ri.activityInfo.metaData.getString(Intent.METADATA_SETUP_VERSION)
3753                         : null;
3754                 if (vers == null && ri.activityInfo.applicationInfo.metaData != null) {
3755                     vers = ri.activityInfo.applicationInfo.metaData.getString(
3756                             Intent.METADATA_SETUP_VERSION);
3757                 }
3758                 String lastVers = Settings.Secure.getString(
3759                         resolver, Settings.Secure.LAST_SETUP_SHOWN);
3760                 if (vers != null && !vers.equals(lastVers)) {
3761                     intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
3762                     intent.setComponent(new ComponentName(
3763                             ri.activityInfo.packageName, ri.activityInfo.name));
3764                     mActivityStarter.startActivityLocked(null, intent, null /*ephemeralIntent*/,
3765                             null, ri.activityInfo, null /*rInfo*/, null, null, null, null, 0, 0, 0,
3766                             null, 0, 0, 0, null, false, false, null, null, null);
3767                 }
3768             }
3769         }
3770     }
3771
3772     CompatibilityInfo compatibilityInfoForPackageLocked(ApplicationInfo ai) {
3773         return mCompatModePackages.compatibilityInfoForPackageLocked(ai);
3774     }
3775
3776     void enforceNotIsolatedCaller(String caller) {
3777         if (UserHandle.isIsolated(Binder.getCallingUid())) {
3778             throw new SecurityException("Isolated process not allowed to call " + caller);
3779         }
3780     }
3781
3782     void enforceShellRestriction(String restriction, int userHandle) {
3783         if (Binder.getCallingUid() == Process.SHELL_UID) {
3784             if (userHandle < 0 || mUserController.hasUserRestriction(restriction, userHandle)) {
3785                 throw new SecurityException("Shell does not have permission to access user "
3786                         + userHandle);
3787             }
3788         }
3789     }
3790
3791     @Override
3792     public int getFrontActivityScreenCompatMode() {
3793         enforceNotIsolatedCaller("getFrontActivityScreenCompatMode");
3794         synchronized (this) {
3795             return mCompatModePackages.getFrontActivityScreenCompatModeLocked();
3796         }
3797     }
3798
3799     @Override
3800     public void setFrontActivityScreenCompatMode(int mode) {
3801         enforceCallingPermission(android.Manifest.permission.SET_SCREEN_COMPATIBILITY,
3802                 "setFrontActivityScreenCompatMode");
3803         synchronized (this) {
3804             mCompatModePackages.setFrontActivityScreenCompatModeLocked(mode);
3805         }
3806     }
3807
3808     @Override
3809     public int getPackageScreenCompatMode(String packageName) {
3810         enforceNotIsolatedCaller("getPackageScreenCompatMode");
3811         synchronized (this) {
3812             return mCompatModePackages.getPackageScreenCompatModeLocked(packageName);
3813         }
3814     }
3815
3816     @Override
3817     public void setPackageScreenCompatMode(String packageName, int mode) {
3818         enforceCallingPermission(android.Manifest.permission.SET_SCREEN_COMPATIBILITY,
3819                 "setPackageScreenCompatMode");
3820         synchronized (this) {
3821             mCompatModePackages.setPackageScreenCompatModeLocked(packageName, mode);
3822         }
3823     }
3824
3825     @Override
3826     public boolean getPackageAskScreenCompat(String packageName) {
3827         enforceNotIsolatedCaller("getPackageAskScreenCompat");
3828         synchronized (this) {
3829             return mCompatModePackages.getPackageAskCompatModeLocked(packageName);
3830         }
3831     }
3832
3833     @Override
3834     public void setPackageAskScreenCompat(String packageName, boolean ask) {
3835         enforceCallingPermission(android.Manifest.permission.SET_SCREEN_COMPATIBILITY,
3836                 "setPackageAskScreenCompat");
3837         synchronized (this) {
3838             mCompatModePackages.setPackageAskCompatModeLocked(packageName, ask);
3839         }
3840     }
3841
3842     private boolean hasUsageStatsPermission(String callingPackage) {
3843         final int mode = mAppOpsService.checkOperation(AppOpsManager.OP_GET_USAGE_STATS,
3844                 Binder.getCallingUid(), callingPackage);
3845         if (mode == AppOpsManager.MODE_DEFAULT) {
3846             return checkCallingPermission(Manifest.permission.PACKAGE_USAGE_STATS)
3847                     == PackageManager.PERMISSION_GRANTED;
3848         }
3849         return mode == AppOpsManager.MODE_ALLOWED;
3850     }
3851
3852     @Override
3853     public int getPackageProcessState(String packageName, String callingPackage) {
3854         if (!hasUsageStatsPermission(callingPackage)) {
3855             enforceCallingPermission(android.Manifest.permission.GET_PACKAGE_IMPORTANCE,
3856                     "getPackageProcessState");
3857         }
3858
3859         int procState = ActivityManager.PROCESS_STATE_NONEXISTENT;
3860         synchronized (this) {
3861             for (int i=mLruProcesses.size()-1; i>=0; i--) {
3862                 final ProcessRecord proc = mLruProcesses.get(i);
3863                 if (procState == ActivityManager.PROCESS_STATE_NONEXISTENT
3864                         || procState > proc.setProcState) {
3865                     boolean found = false;
3866                     for (int j=proc.pkgList.size()-1; j>=0 && !found; j--) {
3867                         if (proc.pkgList.keyAt(j).equals(packageName)) {
3868                             procState = proc.setProcState;
3869                             found = true;
3870                         }
3871                     }
3872                     if (proc.pkgDeps != null && !found) {
3873                         for (int j=proc.pkgDeps.size()-1; j>=0; j--) {
3874                             if (proc.pkgDeps.valueAt(j).equals(packageName)) {
3875                                 procState = proc.setProcState;
3876                                 break;
3877                             }
3878                         }
3879                     }
3880                 }
3881             }
3882         }
3883         return procState;
3884     }
3885
3886     @Override
3887     public boolean setProcessMemoryTrimLevel(String process, int userId, int level) {
3888         synchronized (this) {
3889             final ProcessRecord app = findProcessLocked(process, userId, "setProcessMemoryTrimLevel");
3890             if (app == null) {
3891                 return false;
3892             }
3893             if (app.trimMemoryLevel < level && app.thread != null &&
3894                     (level < ComponentCallbacks2.TRIM_MEMORY_UI_HIDDEN ||
3895                             app.curProcState >= ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND)) {
3896                 try {
3897                     app.thread.scheduleTrimMemory(level);
3898                     app.trimMemoryLevel = level;
3899                     return true;
3900                 } catch (RemoteException e) {
3901                     // Fallthrough to failure case.
3902                 }
3903             }
3904         }
3905         return false;
3906     }
3907
3908     private void dispatchProcessesChanged() {
3909         int N;
3910         synchronized (this) {
3911             N = mPendingProcessChanges.size();
3912             if (mActiveProcessChanges.length < N) {
3913                 mActiveProcessChanges = new ProcessChangeItem[N];
3914             }
3915             mPendingProcessChanges.toArray(mActiveProcessChanges);
3916             mPendingProcessChanges.clear();
3917             if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG_PROCESS_OBSERVERS,
3918                     "*** Delivering " + N + " process changes");
3919         }
3920
3921         int i = mProcessObservers.beginBroadcast();
3922         while (i > 0) {
3923             i--;
3924             final IProcessObserver observer = mProcessObservers.getBroadcastItem(i);
3925             if (observer != null) {
3926                 try {
3927                     for (int j=0; j<N; j++) {
3928                         ProcessChangeItem item = mActiveProcessChanges[j];
3929                         if ((item.changes&ProcessChangeItem.CHANGE_ACTIVITIES) != 0) {
3930                             if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG_PROCESS_OBSERVERS,
3931                                     "ACTIVITIES CHANGED pid=" + item.pid + " uid="
3932                                     + item.uid + ": " + item.foregroundActivities);
3933                             observer.onForegroundActivitiesChanged(item.pid, item.uid,
3934                                     item.foregroundActivities);
3935                         }
3936                         if ((item.changes&ProcessChangeItem.CHANGE_PROCESS_STATE) != 0) {
3937                             if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG_PROCESS_OBSERVERS,
3938                                     "PROCSTATE CHANGED pid=" + item.pid + " uid=" + item.uid
3939                                     + ": " + item.processState);
3940                             observer.onProcessStateChanged(item.pid, item.uid, item.processState);
3941                         }
3942                     }
3943                 } catch (RemoteException e) {
3944                 }
3945             }
3946         }
3947         mProcessObservers.finishBroadcast();
3948
3949         synchronized (this) {
3950             for (int j=0; j<N; j++) {
3951                 mAvailProcessChanges.add(mActiveProcessChanges[j]);
3952             }
3953         }
3954     }
3955
3956     private void dispatchProcessDied(int pid, int uid) {
3957         int i = mProcessObservers.beginBroadcast();
3958         while (i > 0) {
3959             i--;
3960             final IProcessObserver observer = mProcessObservers.getBroadcastItem(i);
3961             if (observer != null) {
3962                 try {
3963                     observer.onProcessDied(pid, uid);
3964                 } catch (RemoteException e) {
3965                 }
3966             }
3967         }
3968         mProcessObservers.finishBroadcast();
3969     }
3970
3971     private void dispatchUidsChanged() {
3972         int N;
3973         synchronized (this) {
3974             N = mPendingUidChanges.size();
3975             if (mActiveUidChanges.length < N) {
3976                 mActiveUidChanges = new UidRecord.ChangeItem[N];
3977             }
3978             for (int i=0; i<N; i++) {
3979                 final UidRecord.ChangeItem change = mPendingUidChanges.get(i);
3980                 mActiveUidChanges[i] = change;
3981                 if (change.uidRecord != null) {
3982                     change.uidRecord.pendingChange = null;
3983                     change.uidRecord = null;
3984                 }
3985             }
3986             mPendingUidChanges.clear();
3987             if (DEBUG_UID_OBSERVERS) Slog.i(TAG_UID_OBSERVERS,
3988                     "*** Delivering " + N + " uid changes");
3989         }
3990
3991         if (mLocalPowerManager != null) {
3992             for (int j=0; j<N; j++) {
3993                 UidRecord.ChangeItem item = mActiveUidChanges[j];
3994                 if (item.change == UidRecord.CHANGE_GONE
3995                         || item.change == UidRecord.CHANGE_GONE_IDLE) {
3996                     mLocalPowerManager.uidGone(item.uid);
3997                 } else {
3998                     mLocalPowerManager.updateUidProcState(item.uid, item.processState);
3999                 }
4000             }
4001         }
4002
4003         int i = mUidObservers.beginBroadcast();
4004         while (i > 0) {
4005             i--;
4006             final IUidObserver observer = mUidObservers.getBroadcastItem(i);
4007             final int which = (Integer)mUidObservers.getBroadcastCookie(i);
4008             if (observer != null) {
4009                 try {
4010                     for (int j=0; j<N; j++) {
4011                         UidRecord.ChangeItem item = mActiveUidChanges[j];
4012                         final int change = item.change;
4013                         UidRecord validateUid = null;
4014                         if (VALIDATE_UID_STATES && i == 0) {
4015                             validateUid = mValidateUids.get(item.uid);
4016                             if (validateUid == null && change != UidRecord.CHANGE_GONE
4017                                     && change != UidRecord.CHANGE_GONE_IDLE) {
4018                                 validateUid = new UidRecord(item.uid);
4019                                 mValidateUids.put(item.uid, validateUid);
4020                             }
4021                         }
4022                         if (change == UidRecord.CHANGE_IDLE
4023                                 || change == UidRecord.CHANGE_GONE_IDLE) {
4024                             if ((which & ActivityManager.UID_OBSERVER_IDLE) != 0) {
4025                                 if (DEBUG_UID_OBSERVERS) Slog.i(TAG_UID_OBSERVERS,
4026                                         "UID idle uid=" + item.uid);
4027                                 observer.onUidIdle(item.uid);
4028                             }
4029                             if (VALIDATE_UID_STATES && i == 0) {
4030                                 if (validateUid != null) {
4031                                     validateUid.idle = true;
4032                                 }
4033                             }
4034                         } else if (change == UidRecord.CHANGE_ACTIVE) {
4035                             if ((which & ActivityManager.UID_OBSERVER_ACTIVE) != 0) {
4036                                 if (DEBUG_UID_OBSERVERS) Slog.i(TAG_UID_OBSERVERS,
4037                                         "UID active uid=" + item.uid);
4038                                 observer.onUidActive(item.uid);
4039                             }
4040                             if (VALIDATE_UID_STATES && i == 0) {
4041                                 validateUid.idle = false;
4042                             }
4043                         }
4044                         if (change == UidRecord.CHANGE_GONE
4045                                 || change == UidRecord.CHANGE_GONE_IDLE) {
4046                             if ((which & ActivityManager.UID_OBSERVER_GONE) != 0) {
4047                                 if (DEBUG_UID_OBSERVERS) Slog.i(TAG_UID_OBSERVERS,
4048                                         "UID gone uid=" + item.uid);
4049                                 observer.onUidGone(item.uid);
4050                             }
4051                             if (VALIDATE_UID_STATES && i == 0) {
4052                                 if (validateUid != null) {
4053                                     mValidateUids.remove(item.uid);
4054                                 }
4055                             }
4056                         } else {
4057                             if ((which & ActivityManager.UID_OBSERVER_PROCSTATE) != 0) {
4058                                 if (DEBUG_UID_OBSERVERS) Slog.i(TAG_UID_OBSERVERS,
4059                                         "UID CHANGED uid=" + item.uid
4060                                                 + ": " + item.processState);
4061                                 observer.onUidStateChanged(item.uid, item.processState);
4062                             }
4063                             if (VALIDATE_UID_STATES && i == 0) {
4064                                 validateUid.curProcState = validateUid.setProcState
4065                                         = item.processState;
4066                             }
4067                         }
4068                     }
4069                 } catch (RemoteException e) {
4070                 }
4071             }
4072         }
4073         mUidObservers.finishBroadcast();
4074
4075         synchronized (this) {
4076             for (int j=0; j<N; j++) {
4077                 mAvailUidChanges.add(mActiveUidChanges[j]);
4078             }
4079         }
4080     }
4081
4082     @Override
4083     public final int startActivity(IApplicationThread caller, String callingPackage,
4084             Intent intent, String resolvedType, IBinder resultTo, String resultWho, int requestCode,
4085             int startFlags, ProfilerInfo profilerInfo, Bundle bOptions) {
4086         return startActivityAsUser(caller, callingPackage, intent, resolvedType, resultTo,
4087                 resultWho, requestCode, startFlags, profilerInfo, bOptions,
4088                 UserHandle.getCallingUserId());
4089     }
4090
4091     final int startActivity(Intent intent, ActivityStackSupervisor.ActivityContainer container) {
4092         enforceNotIsolatedCaller("ActivityContainer.startActivity");
4093         final int userId = mUserController.handleIncomingUser(Binder.getCallingPid(),
4094                 Binder.getCallingUid(), mStackSupervisor.mCurrentUser, false,
4095                 ActivityManagerService.ALLOW_FULL_ONLY, "ActivityContainer", null);
4096
4097         // TODO: Switch to user app stacks here.
4098         String mimeType = intent.getType();
4099         final Uri data = intent.getData();
4100         if (mimeType == null && data != null && "content".equals(data.getScheme())) {
4101             mimeType = getProviderMimeType(data, userId);
4102         }
4103         container.checkEmbeddedAllowedInner(userId, intent, mimeType);
4104
4105         intent.addFlags(FORCE_NEW_TASK_FLAGS);
4106         return mActivityStarter.startActivityMayWait(null, -1, null, intent, mimeType, null, null, null,
4107                 null, 0, 0, null, null, null, null, false, userId, container, null);
4108     }
4109
4110     @Override
4111     public final int startActivityAsUser(IApplicationThread caller, String callingPackage,
4112             Intent intent, String resolvedType, IBinder resultTo, String resultWho, int requestCode,
4113             int startFlags, ProfilerInfo profilerInfo, Bundle bOptions, int userId) {
4114         enforceNotIsolatedCaller("startActivity");
4115         userId = mUserController.handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(),
4116                 userId, false, ALLOW_FULL_ONLY, "startActivity", null);
4117         // TODO: Switch to user app stacks here.
4118         return mActivityStarter.startActivityMayWait(caller, -1, callingPackage, intent,
4119                 resolvedType, null, null, resultTo, resultWho, requestCode, startFlags,
4120                 profilerInfo, null, null, bOptions, false, userId, null, null);
4121     }
4122
4123     @Override
4124     public final int startActivityAsCaller(IApplicationThread caller, String callingPackage,
4125             Intent intent, String resolvedType, IBinder resultTo, String resultWho, int requestCode,
4126             int startFlags, ProfilerInfo profilerInfo, Bundle bOptions, boolean ignoreTargetSecurity,
4127             int userId) {
4128
4129         // This is very dangerous -- it allows you to perform a start activity (including
4130         // permission grants) as any app that may launch one of your own activities.  So
4131         // we will only allow this to be done from activities that are part of the core framework,
4132         // and then only when they are running as the system.
4133         final ActivityRecord sourceRecord;
4134         final int targetUid;
4135         final String targetPackage;
4136         synchronized (this) {
4137             if (resultTo == null) {
4138                 throw new SecurityException("Must be called from an activity");
4139             }
4140             sourceRecord = mStackSupervisor.isInAnyStackLocked(resultTo);
4141             if (sourceRecord == null) {
4142                 throw new SecurityException("Called with bad activity token: " + resultTo);
4143             }
4144             if (!sourceRecord.info.packageName.equals("android")) {
4145                 throw new SecurityException(
4146                         "Must be called from an activity that is declared in the android package");
4147             }
4148             if (sourceRecord.app == null) {
4149                 throw new SecurityException("Called without a process attached to activity");
4150             }
4151             if (UserHandle.getAppId(sourceRecord.app.uid) != Process.SYSTEM_UID) {
4152                 // This is still okay, as long as this activity is running under the
4153                 // uid of the original calling activity.
4154                 if (sourceRecord.app.uid != sourceRecord.launchedFromUid) {
4155                     throw new SecurityException(
4156                             "Calling activity in uid " + sourceRecord.app.uid
4157                                     + " must be system uid or original calling uid "
4158                                     + sourceRecord.launchedFromUid);
4159                 }
4160             }
4161             if (ignoreTargetSecurity) {
4162                 if (intent.getComponent() == null) {
4163                     throw new SecurityException(
4164                             "Component must be specified with ignoreTargetSecurity");
4165                 }
4166                 if (intent.getSelector() != null) {
4167                     throw new SecurityException(
4168                             "Selector not allowed with ignoreTargetSecurity");
4169                 }
4170             }
4171             targetUid = sourceRecord.launchedFromUid;
4172             targetPackage = sourceRecord.launchedFromPackage;
4173         }
4174
4175         if (userId == UserHandle.USER_NULL) {
4176             userId = UserHandle.getUserId(sourceRecord.app.uid);
4177         }
4178
4179         // TODO: Switch to user app stacks here.
4180         try {
4181             int ret = mActivityStarter.startActivityMayWait(null, targetUid, targetPackage, intent,
4182                     resolvedType, null, null, resultTo, resultWho, requestCode, startFlags, null,
4183                     null, null, bOptions, ignoreTargetSecurity, userId, null, null);
4184             return ret;
4185         } catch (SecurityException e) {
4186             // XXX need to figure out how to propagate to original app.
4187             // A SecurityException here is generally actually a fault of the original
4188             // calling activity (such as a fairly granting permissions), so propagate it
4189             // back to them.
4190             /*
4191             StringBuilder msg = new StringBuilder();
4192             msg.append("While launching");
4193             msg.append(intent.toString());
4194             msg.append(": ");
4195             msg.append(e.getMessage());
4196             */
4197             throw e;
4198         }
4199     }
4200
4201     @Override
4202     public final WaitResult startActivityAndWait(IApplicationThread caller, String callingPackage,
4203             Intent intent, String resolvedType, IBinder resultTo, String resultWho, int requestCode,
4204             int startFlags, ProfilerInfo profilerInfo, Bundle bOptions, int userId) {
4205         enforceNotIsolatedCaller("startActivityAndWait");
4206         userId = mUserController.handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(),
4207                 userId, false, ALLOW_FULL_ONLY, "startActivityAndWait", null);
4208         WaitResult res = new WaitResult();
4209         // TODO: Switch to user app stacks here.
4210         mActivityStarter.startActivityMayWait(caller, -1, callingPackage, intent, resolvedType,
4211                 null, null, resultTo, resultWho, requestCode, startFlags, profilerInfo, res, null,
4212                 bOptions, false, userId, null, null);
4213         return res;
4214     }
4215
4216     @Override
4217     public final int startActivityWithConfig(IApplicationThread caller, String callingPackage,
4218             Intent intent, String resolvedType, IBinder resultTo, String resultWho, int requestCode,
4219             int startFlags, Configuration config, Bundle bOptions, int userId) {
4220         enforceNotIsolatedCaller("startActivityWithConfig");
4221         userId = mUserController.handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(),
4222                 userId, false, ALLOW_FULL_ONLY, "startActivityWithConfig", null);
4223         // TODO: Switch to user app stacks here.
4224         int ret = mActivityStarter.startActivityMayWait(caller, -1, callingPackage, intent,
4225                 resolvedType, null, null, resultTo, resultWho, requestCode, startFlags,
4226                 null, null, config, bOptions, false, userId, null, null);
4227         return ret;
4228     }
4229
4230     @Override
4231     public int startActivityIntentSender(IApplicationThread caller, IntentSender intent,
4232             Intent fillInIntent, String resolvedType, IBinder resultTo, String resultWho,
4233             int requestCode, int flagsMask, int flagsValues, Bundle bOptions)
4234             throws TransactionTooLargeException {
4235         enforceNotIsolatedCaller("startActivityIntentSender");
4236         // Refuse possible leaked file descriptors
4237         if (fillInIntent != null && fillInIntent.hasFileDescriptors()) {
4238             throw new IllegalArgumentException("File descriptors passed in Intent");
4239         }
4240
4241         IIntentSender sender = intent.getTarget();
4242         if (!(sender instanceof PendingIntentRecord)) {
4243             throw new IllegalArgumentException("Bad PendingIntent object");
4244         }
4245
4246         PendingIntentRecord pir = (PendingIntentRecord)sender;
4247
4248         synchronized (this) {
4249             // If this is coming from the currently resumed activity, it is
4250             // effectively saying that app switches are allowed at this point.
4251             final ActivityStack stack = getFocusedStack();
4252             if (stack.mResumedActivity != null &&
4253                     stack.mResumedActivity.info.applicationInfo.uid == Binder.getCallingUid()) {
4254                 mAppSwitchesAllowedTime = 0;
4255             }
4256         }
4257         int ret = pir.sendInner(0, fillInIntent, resolvedType, null, null,
4258                 resultTo, resultWho, requestCode, flagsMask, flagsValues, bOptions, null);
4259         return ret;
4260     }
4261
4262     @Override
4263     public int startVoiceActivity(String callingPackage, int callingPid, int callingUid,
4264             Intent intent, String resolvedType, IVoiceInteractionSession session,
4265             IVoiceInteractor interactor, int startFlags, ProfilerInfo profilerInfo,
4266             Bundle bOptions, int userId) {
4267         if (checkCallingPermission(Manifest.permission.BIND_VOICE_INTERACTION)
4268                 != PackageManager.PERMISSION_GRANTED) {
4269             String msg = "Permission Denial: startVoiceActivity() from pid="
4270                     + Binder.getCallingPid()
4271                     + ", uid=" + Binder.getCallingUid()
4272                     + " requires " + android.Manifest.permission.BIND_VOICE_INTERACTION;
4273             Slog.w(TAG, msg);
4274             throw new SecurityException(msg);
4275         }
4276         if (session == null || interactor == null) {
4277             throw new NullPointerException("null session or interactor");
4278         }
4279         userId = mUserController.handleIncomingUser(callingPid, callingUid, userId, false,
4280                 ALLOW_FULL_ONLY, "startVoiceActivity", null);
4281         // TODO: Switch to user app stacks here.
4282         return mActivityStarter.startActivityMayWait(null, callingUid, callingPackage, intent,
4283                 resolvedType, session, interactor, null, null, 0, startFlags, profilerInfo, null,
4284                 null, bOptions, false, userId, null, null);
4285     }
4286
4287     @Override
4288     public void startLocalVoiceInteraction(IBinder callingActivity, Bundle options)
4289             throws RemoteException {
4290         Slog.i(TAG, "Activity tried to startVoiceInteraction");
4291         synchronized (this) {
4292             ActivityRecord activity = getFocusedStack().topActivity();
4293             if (ActivityRecord.forTokenLocked(callingActivity) != activity) {
4294                 throw new SecurityException("Only focused activity can call startVoiceInteraction");
4295             }
4296             if (mRunningVoice != null || activity.task.voiceSession != null
4297                     || activity.voiceSession != null) {
4298                 Slog.w(TAG, "Already in a voice interaction, cannot start new voice interaction");
4299                 return;
4300             }
4301             if (activity.pendingVoiceInteractionStart) {
4302                 Slog.w(TAG, "Pending start of voice interaction already.");
4303                 return;
4304             }
4305             activity.pendingVoiceInteractionStart = true;
4306         }
4307         LocalServices.getService(VoiceInteractionManagerInternal.class)
4308                 .startLocalVoiceInteraction(callingActivity, options);
4309     }
4310
4311     @Override
4312     public void stopLocalVoiceInteraction(IBinder callingActivity) throws RemoteException {
4313         LocalServices.getService(VoiceInteractionManagerInternal.class)
4314                 .stopLocalVoiceInteraction(callingActivity);
4315     }
4316
4317     @Override
4318     public boolean supportsLocalVoiceInteraction() throws RemoteException {
4319         return LocalServices.getService(VoiceInteractionManagerInternal.class)
4320                 .supportsLocalVoiceInteraction();
4321     }
4322
4323     void onLocalVoiceInteractionStartedLocked(IBinder activity,
4324             IVoiceInteractionSession voiceSession, IVoiceInteractor voiceInteractor) {
4325         ActivityRecord activityToCallback = ActivityRecord.forTokenLocked(activity);
4326         if (activityToCallback == null) return;
4327         activityToCallback.setVoiceSessionLocked(voiceSession);
4328
4329         // Inform the activity
4330         try {
4331             activityToCallback.app.thread.scheduleLocalVoiceInteractionStarted(activity,
4332                     voiceInteractor);
4333             long token = Binder.clearCallingIdentity();
4334             try {
4335                 startRunningVoiceLocked(voiceSession, activityToCallback.appInfo.uid);
4336             } finally {
4337                 Binder.restoreCallingIdentity(token);
4338             }
4339             // TODO: VI Should we cache the activity so that it's easier to find later
4340             // rather than scan through all the stacks and activities?
4341         } catch (RemoteException re) {
4342             activityToCallback.clearVoiceSessionLocked();
4343             // TODO: VI Should this terminate the voice session?
4344         }
4345     }
4346
4347     @Override
4348     public void setVoiceKeepAwake(IVoiceInteractionSession session, boolean keepAwake) {
4349         synchronized (this) {
4350             if (mRunningVoice != null && mRunningVoice.asBinder() == session.asBinder()) {
4351                 if (keepAwake) {
4352                     mVoiceWakeLock.acquire();
4353                 } else {
4354                     mVoiceWakeLock.release();
4355                 }
4356             }
4357         }
4358     }
4359
4360     @Override
4361     public boolean startNextMatchingActivity(IBinder callingActivity,
4362             Intent intent, Bundle bOptions) {
4363         // Refuse possible leaked file descriptors
4364         if (intent != null && intent.hasFileDescriptors() == true) {
4365             throw new IllegalArgumentException("File descriptors passed in Intent");
4366         }
4367         ActivityOptions options = ActivityOptions.fromBundle(bOptions);
4368
4369         synchronized (this) {
4370             final ActivityRecord r = ActivityRecord.isInStackLocked(callingActivity);
4371             if (r == null) {
4372                 ActivityOptions.abort(options);
4373                 return false;
4374             }
4375             if (r.app == null || r.app.thread == null) {
4376                 // The caller is not running...  d'oh!
4377                 ActivityOptions.abort(options);
4378                 return false;
4379             }
4380             intent = new Intent(intent);
4381             // The caller is not allowed to change the data.
4382             intent.setDataAndType(r.intent.getData(), r.intent.getType());
4383             // And we are resetting to find the next component...
4384             intent.setComponent(null);
4385
4386             final boolean debug = ((intent.getFlags() & Intent.FLAG_DEBUG_LOG_RESOLUTION) != 0);
4387
4388             ActivityInfo aInfo = null;
4389             try {
4390                 List<ResolveInfo> resolves =
4391                     AppGlobals.getPackageManager().queryIntentActivities(
4392                             intent, r.resolvedType,
4393                             PackageManager.MATCH_DEFAULT_ONLY | STOCK_PM_FLAGS,
4394                             UserHandle.getCallingUserId()).getList();
4395
4396                 // Look for the original activity in the list...
4397                 final int N = resolves != null ? resolves.size() : 0;
4398                 for (int i=0; i<N; i++) {
4399                     ResolveInfo rInfo = resolves.get(i);
4400                     if (rInfo.activityInfo.packageName.equals(r.packageName)
4401                             && rInfo.activityInfo.name.equals(r.info.name)) {
4402                         // We found the current one...  the next matching is
4403                         // after it.
4404                         i++;
4405                         if (i<N) {
4406                             aInfo = resolves.get(i).activityInfo;
4407                         }
4408                         if (debug) {
4409                             Slog.v(TAG, "Next matching activity: found current " + r.packageName
4410                                     + "/" + r.info.name);
4411                             Slog.v(TAG, "Next matching activity: next is " + ((aInfo == null)
4412                                     ? "null" : aInfo.packageName + "/" + aInfo.name));
4413                         }
4414                         break;
4415                     }
4416                 }
4417             } catch (RemoteException e) {
4418             }
4419
4420             if (aInfo == null) {
4421                 // Nobody who is next!
4422                 ActivityOptions.abort(options);
4423                 if (debug) Slog.d(TAG, "Next matching activity: nothing found");
4424                 return false;
4425             }
4426
4427             intent.setComponent(new ComponentName(
4428                     aInfo.applicationInfo.packageName, aInfo.name));
4429             intent.setFlags(intent.getFlags()&~(
4430                     Intent.FLAG_ACTIVITY_FORWARD_RESULT|
4431                     Intent.FLAG_ACTIVITY_CLEAR_TOP|
4432                     Intent.FLAG_ACTIVITY_MULTIPLE_TASK|
4433                     Intent.FLAG_ACTIVITY_NEW_TASK));
4434
4435             // Okay now we need to start the new activity, replacing the
4436             // currently running activity.  This is a little tricky because
4437             // we want to start the new one as if the current one is finished,
4438             // but not finish the current one first so that there is no flicker.
4439             // And thus...
4440             final boolean wasFinishing = r.finishing;
4441             r.finishing = true;
4442
4443             // Propagate reply information over to the new activity.
4444             final ActivityRecord resultTo = r.resultTo;
4445             final String resultWho = r.resultWho;
4446             final int requestCode = r.requestCode;
4447             r.resultTo = null;
4448             if (resultTo != null) {
4449                 resultTo.removeResultsLocked(r, resultWho, requestCode);
4450             }
4451
4452             final long origId = Binder.clearCallingIdentity();
4453             int res = mActivityStarter.startActivityLocked(r.app.thread, intent,
4454                     null /*ephemeralIntent*/, r.resolvedType, aInfo, null /*rInfo*/, null,
4455                     null, resultTo != null ? resultTo.appToken : null, resultWho, requestCode, -1,
4456                     r.launchedFromUid, r.launchedFromPackage, -1, r.launchedFromUid, 0, options,
4457                     false, false, null, null, null);
4458             Binder.restoreCallingIdentity(origId);
4459
4460             r.finishing = wasFinishing;
4461             if (res != ActivityManager.START_SUCCESS) {
4462                 return false;
4463             }
4464             return true;
4465         }
4466     }
4467
4468     @Override
4469     public final int startActivityFromRecents(int taskId, Bundle bOptions) {
4470         if (checkCallingPermission(START_TASKS_FROM_RECENTS) != PackageManager.PERMISSION_GRANTED) {
4471             String msg = "Permission Denial: startActivityFromRecents called without " +
4472                     START_TASKS_FROM_RECENTS;
4473             Slog.w(TAG, msg);
4474             throw new SecurityException(msg);
4475         }
4476         final long origId = Binder.clearCallingIdentity();
4477         try {
4478             return startActivityFromRecentsInner(taskId, bOptions);
4479         } finally {
4480             Binder.restoreCallingIdentity(origId);
4481         }
4482     }
4483
4484     final int startActivityFromRecentsInner(int taskId, Bundle bOptions) {
4485         final TaskRecord task;
4486         final int callingUid;
4487         final String callingPackage;
4488         final Intent intent;
4489         final int userId;
4490         synchronized (this) {
4491             final ActivityOptions activityOptions = (bOptions != null)
4492                     ? new ActivityOptions(bOptions) : null;
4493             final int launchStackId = (activityOptions != null)
4494                     ? activityOptions.getLaunchStackId() : INVALID_STACK_ID;
4495
4496             if (launchStackId == HOME_STACK_ID) {
4497                 throw new IllegalArgumentException("startActivityFromRecentsInner: Task "
4498                         + taskId + " can't be launch in the home stack.");
4499             }
4500             task = mStackSupervisor.anyTaskForIdLocked(taskId, RESTORE_FROM_RECENTS, launchStackId);
4501             if (task == null) {
4502                 throw new IllegalArgumentException(
4503                         "startActivityFromRecentsInner: Task " + taskId + " not found.");
4504             }
4505
4506             if (launchStackId != INVALID_STACK_ID) {
4507                 if (launchStackId == DOCKED_STACK_ID && activityOptions != null) {
4508                     mWindowManager.setDockedStackCreateState(
4509                             activityOptions.getDockCreateMode(), null /* initialBounds */);
4510                 }
4511                 if (task.stack.mStackId != launchStackId) {
4512                     mStackSupervisor.moveTaskToStackLocked(
4513                             taskId, launchStackId, ON_TOP, FORCE_FOCUS, "startActivityFromRecents",
4514                             ANIMATE);
4515                 }
4516             }
4517
4518             // If the user must confirm credentials (e.g. when first launching a work app and the
4519             // Work Challenge is present) let startActivityInPackage handle the intercepting.
4520             if (!mUserController.shouldConfirmCredentials(task.userId)
4521                     && task.getRootActivity() != null) {
4522                 moveTaskToFrontLocked(task.taskId, 0, bOptions);
4523                 return ActivityManager.START_TASK_TO_FRONT;
4524             }
4525             callingUid = task.mCallingUid;
4526             callingPackage = task.mCallingPackage;
4527             intent = task.intent;
4528             intent.addFlags(Intent.FLAG_ACTIVITY_LAUNCHED_FROM_HISTORY);
4529             userId = task.userId;
4530         }
4531         return startActivityInPackage(callingUid, callingPackage, intent, null, null, null, 0, 0,
4532                 bOptions, userId, null, task);
4533     }
4534
4535     final int startActivityInPackage(int uid, String callingPackage,
4536             Intent intent, String resolvedType, IBinder resultTo,
4537             String resultWho, int requestCode, int startFlags, Bundle bOptions, int userId,
4538             IActivityContainer container, TaskRecord inTask) {
4539
4540         userId = mUserController.handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(),
4541                 userId, false, ALLOW_FULL_ONLY, "startActivityInPackage", null);
4542
4543         // TODO: Switch to user app stacks here.
4544         int ret = mActivityStarter.startActivityMayWait(null, uid, callingPackage, intent,
4545                 resolvedType, null, null, resultTo, resultWho, requestCode, startFlags,
4546                 null, null, null, bOptions, false, userId, container, inTask);
4547         return ret;
4548     }
4549
4550     @Override
4551     public final int startActivities(IApplicationThread caller, String callingPackage,
4552             Intent[] intents, String[] resolvedTypes, IBinder resultTo, Bundle bOptions,
4553             int userId) {
4554         enforceNotIsolatedCaller("startActivities");
4555         userId = mUserController.handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(),
4556                 userId, false, ALLOW_FULL_ONLY, "startActivity", null);
4557         // TODO: Switch to user app stacks here.
4558         int ret = mActivityStarter.startActivities(caller, -1, callingPackage, intents,
4559                 resolvedTypes, resultTo, bOptions, userId);
4560         return ret;
4561     }
4562
4563     final int startActivitiesInPackage(int uid, String callingPackage,
4564             Intent[] intents, String[] resolvedTypes, IBinder resultTo,
4565             Bundle bOptions, int userId) {
4566
4567         userId = mUserController.handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(),
4568                 userId, false, ALLOW_FULL_ONLY, "startActivityInPackage", null);
4569         // TODO: Switch to user app stacks here.
4570         int ret = mActivityStarter.startActivities(null, uid, callingPackage, intents, resolvedTypes,
4571                 resultTo, bOptions, userId);
4572         return ret;
4573     }
4574
4575     @Override
4576     public void reportActivityFullyDrawn(IBinder token) {
4577         synchronized (this) {
4578             ActivityRecord r = ActivityRecord.isInStackLocked(token);
4579             if (r == null) {
4580                 return;
4581             }
4582             r.reportFullyDrawnLocked();
4583         }
4584     }
4585
4586     @Override
4587     public void setRequestedOrientation(IBinder token, int requestedOrientation) {
4588         synchronized (this) {
4589             ActivityRecord r = ActivityRecord.isInStackLocked(token);
4590             if (r == null) {
4591                 return;
4592             }
4593             TaskRecord task = r.task;
4594             if (task != null && (!task.mFullscreen || !task.stack.mFullscreen)) {
4595                 // Fixed screen orientation isn't supported when activities aren't in full screen
4596                 // mode.
4597                 return;
4598             }
4599             final long origId = Binder.clearCallingIdentity();
4600             mWindowManager.setAppOrientation(r.appToken, requestedOrientation);
4601             Configuration config = mWindowManager.updateOrientationFromAppTokens(
4602                     mConfiguration, r.mayFreezeScreenLocked(r.app) ? r.appToken : null);
4603             if (config != null) {
4604                 r.frozenBeforeDestroy = true;
4605                 if (!updateConfigurationLocked(config, r, false)) {
4606                     mStackSupervisor.resumeFocusedStackTopActivityLocked();
4607                 }
4608             }
4609             Binder.restoreCallingIdentity(origId);
4610         }
4611     }
4612
4613     @Override
4614     public int getRequestedOrientation(IBinder token) {
4615         synchronized (this) {
4616             ActivityRecord r = ActivityRecord.isInStackLocked(token);
4617             if (r == null) {
4618                 return ActivityInfo.SCREEN_ORIENTATION_UNSPECIFIED;
4619             }
4620             return mWindowManager.getAppOrientation(r.appToken);
4621         }
4622     }
4623
4624     /**
4625      * This is the internal entry point for handling Activity.finish().
4626      *
4627      * @param token The Binder token referencing the Activity we want to finish.
4628      * @param resultCode Result code, if any, from this Activity.
4629      * @param resultData Result data (Intent), if any, from this Activity.
4630      * @param finishTask Whether to finish the task associated with this Activity.
4631      *
4632      * @return Returns true if the activity successfully finished, or false if it is still running.
4633      */
4634     @Override
4635     public final boolean finishActivity(IBinder token, int resultCode, Intent resultData,
4636             int finishTask) {
4637         // Refuse possible leaked file descriptors
4638         if (resultData != null && resultData.hasFileDescriptors() == true) {
4639             throw new IllegalArgumentException("File descriptors passed in Intent");
4640         }
4641
4642         synchronized(this) {
4643             ActivityRecord r = ActivityRecord.isInStackLocked(token);
4644             if (r == null) {
4645                 return true;
4646             }
4647             // Keep track of the root activity of the task before we finish it
4648             TaskRecord tr = r.task;
4649             ActivityRecord rootR = tr.getRootActivity();
4650             if (rootR == null) {
4651                 Slog.w(TAG, "Finishing task with all activities already finished");
4652             }
4653             // Do not allow task to finish if last task in lockTask mode. Launchable priv-apps can
4654             // finish.
4655             if (tr.mLockTaskAuth != LOCK_TASK_AUTH_LAUNCHABLE_PRIV && rootR == r &&
4656                     mStackSupervisor.isLastLockedTask(tr)) {
4657                 Slog.i(TAG, "Not finishing task in lock task mode");
4658                 mStackSupervisor.showLockTaskToast();
4659                 return false;
4660             }
4661             if (mController != null) {
4662                 // Find the first activity that is not finishing.
4663                 ActivityRecord next = r.task.stack.topRunningActivityLocked(token, 0);
4664                 if (next != null) {
4665                     // ask watcher if this is allowed
4666                     boolean resumeOK = true;
4667                     try {
4668                         resumeOK = mController.activityResuming(next.packageName);
4669                     } catch (RemoteException e) {
4670                         mController = null;
4671                         Watchdog.getInstance().setActivityController(null);
4672                     }
4673
4674                     if (!resumeOK) {
4675                         Slog.i(TAG, "Not finishing activity because controller resumed");
4676                         return false;
4677                     }
4678                 }
4679             }
4680             final long origId = Binder.clearCallingIdentity();
4681             try {
4682                 boolean res;
4683                 final boolean finishWithRootActivity =
4684                         finishTask == Activity.FINISH_TASK_WITH_ROOT_ACTIVITY;
4685                 if (finishTask == Activity.FINISH_TASK_WITH_ACTIVITY
4686                         || (finishWithRootActivity && r == rootR)) {
4687                     // If requested, remove the task that is associated to this activity only if it
4688                     // was the root activity in the task. The result code and data is ignored
4689                     // because we don't support returning them across task boundaries. Also, to
4690                     // keep backwards compatibility we remove the task from recents when finishing
4691                     // task with root activity.
4692                     res = removeTaskByIdLocked(tr.taskId, false, finishWithRootActivity);
4693                     if (!res) {
4694                         Slog.i(TAG, "Removing task failed to finish activity");
4695                     }
4696                 } else {
4697                     res = tr.stack.requestFinishActivityLocked(token, resultCode,
4698                             resultData, "app-request", true);
4699                     if (!res) {
4700                         Slog.i(TAG, "Failed to finish by app-request");
4701                     }
4702                 }
4703                 return res;
4704             } finally {
4705                 Binder.restoreCallingIdentity(origId);
4706             }
4707         }
4708     }
4709
4710     @Override
4711     public final void finishHeavyWeightApp() {
4712         if (checkCallingPermission(android.Manifest.permission.FORCE_STOP_PACKAGES)
4713                 != PackageManager.PERMISSION_GRANTED) {
4714             String msg = "Permission Denial: finishHeavyWeightApp() from pid="
4715                     + Binder.getCallingPid()
4716                     + ", uid=" + Binder.getCallingUid()
4717                     + " requires " + android.Manifest.permission.FORCE_STOP_PACKAGES;
4718             Slog.w(TAG, msg);
4719             throw new SecurityException(msg);
4720         }
4721
4722         synchronized(this) {
4723             if (mHeavyWeightProcess == null) {
4724                 return;
4725             }
4726
4727             ArrayList<ActivityRecord> activities = new ArrayList<>(mHeavyWeightProcess.activities);
4728             for (int i = 0; i < activities.size(); i++) {
4729                 ActivityRecord r = activities.get(i);
4730                 if (!r.finishing && r.isInStackLocked()) {
4731                     r.task.stack.finishActivityLocked(r, Activity.RESULT_CANCELED,
4732                             null, "finish-heavy", true);
4733                 }
4734             }
4735
4736             mHandler.sendMessage(mHandler.obtainMessage(CANCEL_HEAVY_NOTIFICATION_MSG,
4737                     mHeavyWeightProcess.userId, 0));
4738             mHeavyWeightProcess = null;
4739         }
4740     }
4741
4742     @Override
4743     public void crashApplication(int uid, int initialPid, String packageName,
4744             String message) {
4745         if (checkCallingPermission(android.Manifest.permission.FORCE_STOP_PACKAGES)
4746                 != PackageManager.PERMISSION_GRANTED) {
4747             String msg = "Permission Denial: crashApplication() from pid="
4748                     + Binder.getCallingPid()
4749                     + ", uid=" + Binder.getCallingUid()
4750                     + " requires " + android.Manifest.permission.FORCE_STOP_PACKAGES;
4751             Slog.w(TAG, msg);
4752             throw new SecurityException(msg);
4753         }
4754
4755         synchronized(this) {
4756             mAppErrors.scheduleAppCrashLocked(uid, initialPid, packageName, message);
4757         }
4758     }
4759
4760     @Override
4761     public final void finishSubActivity(IBinder token, String resultWho,
4762             int requestCode) {
4763         synchronized(this) {
4764             final long origId = Binder.clearCallingIdentity();
4765             ActivityRecord r = ActivityRecord.isInStackLocked(token);
4766             if (r != null) {
4767                 r.task.stack.finishSubActivityLocked(r, resultWho, requestCode);
4768             }
4769             Binder.restoreCallingIdentity(origId);
4770         }
4771     }
4772
4773     @Override
4774     public boolean finishActivityAffinity(IBinder token) {
4775         synchronized(this) {
4776             final long origId = Binder.clearCallingIdentity();
4777             try {
4778                 ActivityRecord r = ActivityRecord.isInStackLocked(token);
4779                 if (r == null) {
4780                     return false;
4781                 }
4782
4783                 // Do not allow task to finish if last task in lockTask mode. Launchable priv-apps
4784                 // can finish.
4785                 final TaskRecord task = r.task;
4786                 if (task.mLockTaskAuth != LOCK_TASK_AUTH_LAUNCHABLE_PRIV &&
4787                         mStackSupervisor.isLastLockedTask(task) && task.getRootActivity() == r) {
4788                     mStackSupervisor.showLockTaskToast();
4789                     return false;
4790                 }
4791                 return task.stack.finishActivityAffinityLocked(r);
4792             } finally {
4793                 Binder.restoreCallingIdentity(origId);
4794             }
4795         }
4796     }
4797
4798     @Override
4799     public void finishVoiceTask(IVoiceInteractionSession session) {
4800         synchronized (this) {
4801             final long origId = Binder.clearCallingIdentity();
4802             try {
4803                 // TODO: VI Consider treating local voice interactions and voice tasks
4804                 // differently here
4805                 mStackSupervisor.finishVoiceTask(session);
4806             } finally {
4807                 Binder.restoreCallingIdentity(origId);
4808             }
4809         }
4810
4811     }
4812
4813     @Override
4814     public boolean releaseActivityInstance(IBinder token) {
4815         synchronized(this) {
4816             final long origId = Binder.clearCallingIdentity();
4817             try {
4818                 ActivityRecord r = ActivityRecord.isInStackLocked(token);
4819                 if (r == null) {
4820                     return false;
4821                 }
4822                 return r.task.stack.safelyDestroyActivityLocked(r, "app-req");
4823             } finally {
4824                 Binder.restoreCallingIdentity(origId);
4825             }
4826         }
4827     }
4828
4829     @Override
4830     public void releaseSomeActivities(IApplicationThread appInt) {
4831         synchronized(this) {
4832             final long origId = Binder.clearCallingIdentity();
4833             try {
4834                 ProcessRecord app = getRecordForAppLocked(appInt);
4835                 mStackSupervisor.releaseSomeActivitiesLocked(app, "low-mem");
4836             } finally {
4837                 Binder.restoreCallingIdentity(origId);
4838             }
4839         }
4840     }
4841
4842     @Override
4843     public boolean willActivityBeVisible(IBinder token) {
4844         synchronized(this) {
4845             ActivityStack stack = ActivityRecord.getStackLocked(token);
4846             if (stack != null) {
4847                 return stack.willActivityBeVisibleLocked(token);
4848             }
4849             return false;
4850         }
4851     }
4852
4853     @Override
4854     public void overridePendingTransition(IBinder token, String packageName,
4855             int enterAnim, int exitAnim) {
4856         synchronized(this) {
4857             ActivityRecord self = ActivityRecord.isInStackLocked(token);
4858             if (self == null) {
4859                 return;
4860             }
4861
4862             final long origId = Binder.clearCallingIdentity();
4863
4864             if (self.state == ActivityState.RESUMED
4865                     || self.state == ActivityState.PAUSING) {
4866                 mWindowManager.overridePendingAppTransition(packageName,
4867                         enterAnim, exitAnim, null);
4868             }
4869
4870             Binder.restoreCallingIdentity(origId);
4871         }
4872     }
4873
4874     /**
4875      * Main function for removing an existing process from the activity manager
4876      * as a result of that process going away.  Clears out all connections
4877      * to the process.
4878      */
4879     private final void handleAppDiedLocked(ProcessRecord app,
4880             boolean restarting, boolean allowRestart) {
4881         int pid = app.pid;
4882         boolean kept = cleanUpApplicationRecordLocked(app, restarting, allowRestart, -1);
4883         if (!kept && !restarting) {
4884             removeLruProcessLocked(app);
4885             if (pid > 0) {
4886                 ProcessList.remove(pid);
4887             }
4888         }
4889
4890         if (mProfileProc == app) {
4891             clearProfilerLocked();
4892         }
4893
4894         // Remove this application's activities from active lists.
4895         boolean hasVisibleActivities = mStackSupervisor.handleAppDiedLocked(app);
4896
4897         app.activities.clear();
4898
4899         if (app.instrumentationClass != null) {
4900             Slog.w(TAG, "Crash of app " + app.processName
4901                   + " running instrumentation " + app.instrumentationClass);
4902             Bundle info = new Bundle();
4903             info.putString("shortMsg", "Process crashed.");
4904             finishInstrumentationLocked(app, Activity.RESULT_CANCELED, info);
4905         }
4906
4907         if (!restarting && hasVisibleActivities
4908                 && !mStackSupervisor.resumeFocusedStackTopActivityLocked()) {
4909             // If there was nothing to resume, and we are not already restarting this process, but
4910             // there is a visible activity that is hosted by the process...  then make sure all
4911             // visible activities are running, taking care of restarting this process.
4912             mStackSupervisor.ensureActivitiesVisibleLocked(null, 0, !PRESERVE_WINDOWS);
4913         }
4914     }
4915
4916     private final int getLRURecordIndexForAppLocked(IApplicationThread thread) {
4917         IBinder threadBinder = thread.asBinder();
4918         // Find the application record.
4919         for (int i=mLruProcesses.size()-1; i>=0; i--) {
4920             ProcessRecord rec = mLruProcesses.get(i);
4921             if (rec.thread != null && rec.thread.asBinder() == threadBinder) {
4922                 return i;
4923             }
4924         }
4925         return -1;
4926     }
4927
4928     final ProcessRecord getRecordForAppLocked(
4929             IApplicationThread thread) {
4930         if (thread == null) {
4931             return null;
4932         }
4933
4934         int appIndex = getLRURecordIndexForAppLocked(thread);
4935         return appIndex >= 0 ? mLruProcesses.get(appIndex) : null;
4936     }
4937
4938     final void doLowMemReportIfNeededLocked(ProcessRecord dyingProc) {
4939         // If there are no longer any background processes running,
4940         // and the app that died was not running instrumentation,
4941         // then tell everyone we are now low on memory.
4942         boolean haveBg = false;
4943         for (int i=mLruProcesses.size()-1; i>=0; i--) {
4944             ProcessRecord rec = mLruProcesses.get(i);
4945             if (rec.thread != null
4946                     && rec.setProcState >= ActivityManager.PROCESS_STATE_CACHED_ACTIVITY) {
4947                 haveBg = true;
4948                 break;
4949             }
4950         }
4951
4952         if (!haveBg) {
4953             boolean doReport = "1".equals(SystemProperties.get(SYSTEM_DEBUGGABLE, "0"));
4954             if (doReport) {
4955                 long now = SystemClock.uptimeMillis();
4956                 if (now < (mLastMemUsageReportTime+5*60*1000)) {
4957                     doReport = false;
4958                 } else {
4959                     mLastMemUsageReportTime = now;
4960                 }
4961             }
4962             final ArrayList<ProcessMemInfo> memInfos
4963                     = doReport ? new ArrayList<ProcessMemInfo>(mLruProcesses.size()) : null;
4964             EventLog.writeEvent(EventLogTags.AM_LOW_MEMORY, mLruProcesses.size());
4965             long now = SystemClock.uptimeMillis();
4966             for (int i=mLruProcesses.size()-1; i>=0; i--) {
4967                 ProcessRecord rec = mLruProcesses.get(i);
4968                 if (rec == dyingProc || rec.thread == null) {
4969                     continue;
4970                 }
4971                 if (doReport) {
4972                     memInfos.add(new ProcessMemInfo(rec.processName, rec.pid, rec.setAdj,
4973                             rec.setProcState, rec.adjType, rec.makeAdjReason()));
4974                 }
4975                 if ((rec.lastLowMemory+GC_MIN_INTERVAL) <= now) {
4976                     // The low memory report is overriding any current
4977                     // state for a GC request.  Make sure to do
4978                     // heavy/important/visible/foreground processes first.
4979                     if (rec.setAdj <= ProcessList.HEAVY_WEIGHT_APP_ADJ) {
4980                         rec.lastRequestedGc = 0;
4981                     } else {
4982                         rec.lastRequestedGc = rec.lastLowMemory;
4983                     }
4984                     rec.reportLowMemory = true;
4985                     rec.lastLowMemory = now;
4986                     mProcessesToGc.remove(rec);
4987                     addProcessToGcListLocked(rec);
4988                 }
4989             }
4990             if (doReport) {
4991                 Message msg = mHandler.obtainMessage(REPORT_MEM_USAGE_MSG, memInfos);
4992                 mHandler.sendMessage(msg);
4993             }
4994             scheduleAppGcsLocked();
4995         }
4996     }
4997
4998     final void appDiedLocked(ProcessRecord app) {
4999        appDiedLocked(app, app.pid, app.thread, false);
5000     }
5001
5002     final void appDiedLocked(ProcessRecord app, int pid, IApplicationThread thread,
5003             boolean fromBinderDied) {
5004         // First check if this ProcessRecord is actually active for the pid.
5005         synchronized (mPidsSelfLocked) {
5006             ProcessRecord curProc = mPidsSelfLocked.get(pid);
5007             if (curProc != app) {
5008                 Slog.w(TAG, "Spurious death for " + app + ", curProc for " + pid + ": " + curProc);
5009                 return;
5010             }
5011         }
5012
5013         BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
5014         synchronized (stats) {
5015             stats.noteProcessDiedLocked(app.info.uid, pid);
5016         }
5017
5018         if (!app.killed) {
5019             if (!fromBinderDied) {
5020                 Process.killProcessQuiet(pid);
5021             }
5022             killProcessGroup(app.info.uid, pid);
5023             app.killed = true;
5024         }
5025
5026         // Clean up already done if the process has been re-started.
5027         if (app.pid == pid && app.thread != null &&
5028                 app.thread.asBinder() == thread.asBinder()) {
5029             boolean doLowMem = app.instrumentationClass == null;
5030             boolean doOomAdj = doLowMem;
5031             if (!app.killedByAm) {
5032                 Slog.i(TAG, "Process " + app.processName + " (pid " + pid
5033                         + ") has died");
5034                 mAllowLowerMemLevel = true;
5035             } else {
5036                 // Note that we always want to do oom adj to update our state with the
5037                 // new number of procs.
5038                 mAllowLowerMemLevel = false;
5039                 doLowMem = false;
5040             }
5041             EventLog.writeEvent(EventLogTags.AM_PROC_DIED, app.userId, app.pid, app.processName);
5042             if (DEBUG_CLEANUP) Slog.v(TAG_CLEANUP,
5043                 "Dying app: " + app + ", pid: " + pid + ", thread: " + thread.asBinder());
5044             handleAppDiedLocked(app, false, true);
5045
5046             if (doOomAdj) {
5047                 updateOomAdjLocked();
5048             }
5049             if (doLowMem) {
5050                 doLowMemReportIfNeededLocked(app);
5051             }
5052         } else if (app.pid != pid) {
5053             // A new process has already been started.
5054             Slog.i(TAG, "Process " + app.processName + " (pid " + pid
5055                     + ") has died and restarted (pid " + app.pid + ").");
5056             EventLog.writeEvent(EventLogTags.AM_PROC_DIED, app.userId, app.pid, app.processName);
5057         } else if (DEBUG_PROCESSES) {
5058             Slog.d(TAG_PROCESSES, "Received spurious death notification for thread "
5059                     + thread.asBinder());
5060         }
5061     }
5062
5063     /**
5064      * If a stack trace dump file is configured, dump process stack traces.
5065      * @param clearTraces causes the dump file to be erased prior to the new
5066      *    traces being written, if true; when false, the new traces will be
5067      *    appended to any existing file content.
5068      * @param firstPids of dalvik VM processes to dump stack traces for first
5069      * @param lastPids of dalvik VM processes to dump stack traces for last
5070      * @param nativeProcs optional list of native process names to dump stack crawls
5071      * @return file containing stack traces, or null if no dump file is configured
5072      */
5073     public static File dumpStackTraces(boolean clearTraces, ArrayList<Integer> firstPids,
5074             ProcessCpuTracker processCpuTracker, SparseArray<Boolean> lastPids, String[] nativeProcs) {
5075         String tracesPath = SystemProperties.get("dalvik.vm.stack-trace-file", null);
5076         if (tracesPath == null || tracesPath.length() == 0) {
5077             return null;
5078         }
5079
5080         File tracesFile = new File(tracesPath);
5081         try {
5082             if (clearTraces && tracesFile.exists()) tracesFile.delete();
5083             tracesFile.createNewFile();
5084             FileUtils.setPermissions(tracesFile.getPath(), 0666, -1, -1); // -rw-rw-rw-
5085         } catch (IOException e) {
5086             Slog.w(TAG, "Unable to prepare ANR traces file: " + tracesPath, e);
5087             return null;
5088         }
5089
5090         dumpStackTraces(tracesPath, firstPids, processCpuTracker, lastPids, nativeProcs);
5091         return tracesFile;
5092     }
5093
5094     private static void dumpStackTraces(String tracesPath, ArrayList<Integer> firstPids,
5095             ProcessCpuTracker processCpuTracker, SparseArray<Boolean> lastPids, String[] nativeProcs) {
5096         // Use a FileObserver to detect when traces finish writing.
5097         // The order of traces is considered important to maintain for legibility.
5098         FileObserver observer = new FileObserver(tracesPath, FileObserver.CLOSE_WRITE) {
5099             @Override
5100             public synchronized void onEvent(int event, String path) { notify(); }
5101         };
5102
5103         try {
5104             observer.startWatching();
5105
5106             // First collect all of the stacks of the most important pids.
5107             if (firstPids != null) {
5108                 try {
5109                     int num = firstPids.size();
5110                     for (int i = 0; i < num; i++) {
5111                         synchronized (observer) {
5112                             if (DEBUG_ANR) Slog.d(TAG, "Collecting stacks for pid "
5113                                     + firstPids.get(i));
5114                             final long sime = SystemClock.elapsedRealtime();
5115                             Process.sendSignal(firstPids.get(i), Process.SIGNAL_QUIT);
5116                             observer.wait(1000);  // Wait for write-close, give up after 1 sec
5117                             if (DEBUG_ANR) Slog.d(TAG, "Done with pid " + firstPids.get(i)
5118                                     + " in " + (SystemClock.elapsedRealtime()-sime) + "ms");
5119                         }
5120                     }
5121                 } catch (InterruptedException e) {
5122                     Slog.wtf(TAG, e);
5123                 }
5124             }
5125
5126             // Next collect the stacks of the native pids
5127             if (nativeProcs != null) {
5128                 int[] pids = Process.getPidsForCommands(nativeProcs);
5129                 if (pids != null) {
5130                     for (int pid : pids) {
5131                         if (DEBUG_ANR) Slog.d(TAG, "Collecting stacks for native pid " + pid);
5132                         final long sime = SystemClock.elapsedRealtime();
5133                         Debug.dumpNativeBacktraceToFile(pid, tracesPath);
5134                         if (DEBUG_ANR) Slog.d(TAG, "Done with native pid " + pid
5135                                 + " in " + (SystemClock.elapsedRealtime()-sime) + "ms");
5136                     }
5137                 }
5138             }
5139
5140             // Lastly, measure CPU usage.
5141             if (processCpuTracker != null) {
5142                 processCpuTracker.init();
5143                 System.gc();
5144                 processCpuTracker.update();
5145                 try {
5146                     synchronized (processCpuTracker) {
5147                         processCpuTracker.wait(500); // measure over 1/2 second.
5148                     }
5149                 } catch (InterruptedException e) {
5150                 }
5151                 processCpuTracker.update();
5152
5153                 // We'll take the stack crawls of just the top apps using CPU.
5154                 final int N = processCpuTracker.countWorkingStats();
5155                 int numProcs = 0;
5156                 for (int i=0; i<N && numProcs<5; i++) {
5157                     ProcessCpuTracker.Stats stats = processCpuTracker.getWorkingStats(i);
5158                     if (lastPids.indexOfKey(stats.pid) >= 0) {
5159                         numProcs++;
5160                         try {
5161                             synchronized (observer) {
5162                                 if (DEBUG_ANR) Slog.d(TAG, "Collecting stacks for extra pid "
5163                                         + stats.pid);
5164                                 final long stime = SystemClock.elapsedRealtime();
5165                                 Process.sendSignal(stats.pid, Process.SIGNAL_QUIT);
5166                                 observer.wait(1000);  // Wait for write-close, give up after 1 sec
5167                                 if (DEBUG_ANR) Slog.d(TAG, "Done with extra pid " + stats.pid
5168                                         + " in " + (SystemClock.elapsedRealtime()-stime) + "ms");
5169                             }
5170                         } catch (InterruptedException e) {
5171                             Slog.wtf(TAG, e);
5172                         }
5173                     } else if (DEBUG_ANR) {
5174                         Slog.d(TAG, "Skipping next CPU consuming process, not a java proc: "
5175                                 + stats.pid);
5176                     }
5177                 }
5178             }
5179         } finally {
5180             observer.stopWatching();
5181         }
5182     }
5183
5184     final void logAppTooSlow(ProcessRecord app, long startTime, String msg) {
5185         if (true || IS_USER_BUILD) {
5186             return;
5187         }
5188         String tracesPath = SystemProperties.get("dalvik.vm.stack-trace-file", null);
5189         if (tracesPath == null || tracesPath.length() == 0) {
5190             return;
5191         }
5192
5193         StrictMode.ThreadPolicy oldPolicy = StrictMode.allowThreadDiskReads();
5194         StrictMode.allowThreadDiskWrites();
5195         try {
5196             final File tracesFile = new File(tracesPath);
5197             final File tracesDir = tracesFile.getParentFile();
5198             final File tracesTmp = new File(tracesDir, "__tmp__");
5199             try {
5200                 if (tracesFile.exists()) {
5201                     tracesTmp.delete();
5202                     tracesFile.renameTo(tracesTmp);
5203                 }
5204                 StringBuilder sb = new StringBuilder();
5205                 Time tobj = new Time();
5206                 tobj.set(System.currentTimeMillis());
5207                 sb.append(tobj.format("%Y-%m-%d %H:%M:%S"));
5208                 sb.append(": ");
5209                 TimeUtils.formatDuration(SystemClock.uptimeMillis()-startTime, sb);
5210                 sb.append(" since ");
5211                 sb.append(msg);
5212                 FileOutputStream fos = new FileOutputStream(tracesFile);
5213                 fos.write(sb.toString().getBytes());
5214                 if (app == null) {
5215                     fos.write("\n*** No application process!".getBytes());
5216                 }
5217                 fos.close();
5218                 FileUtils.setPermissions(tracesFile.getPath(), 0666, -1, -1); // -rw-rw-rw-
5219             } catch (IOException e) {
5220                 Slog.w(TAG, "Unable to prepare slow app traces file: " + tracesPath, e);
5221                 return;
5222             }
5223
5224             if (app != null) {
5225                 ArrayList<Integer> firstPids = new ArrayList<Integer>();
5226                 firstPids.add(app.pid);
5227                 dumpStackTraces(tracesPath, firstPids, null, null, null);
5228             }
5229
5230             File lastTracesFile = null;
5231             File curTracesFile = null;
5232             for (int i=9; i>=0; i--) {
5233                 String name = String.format(Locale.US, "slow%02d.txt", i);
5234                 curTracesFile = new File(tracesDir, name);
5235                 if (curTracesFile.exists()) {
5236                     if (lastTracesFile != null) {
5237                         curTracesFile.renameTo(lastTracesFile);
5238                     } else {
5239                         curTracesFile.delete();
5240                     }
5241                 }
5242                 lastTracesFile = curTracesFile;
5243             }
5244             tracesFile.renameTo(curTracesFile);
5245             if (tracesTmp.exists()) {
5246                 tracesTmp.renameTo(tracesFile);
5247             }
5248         } finally {
5249             StrictMode.setThreadPolicy(oldPolicy);
5250         }
5251     }
5252
5253     final void showLaunchWarningLocked(final ActivityRecord cur, final ActivityRecord next) {
5254         if (!mLaunchWarningShown) {
5255             mLaunchWarningShown = true;
5256             mUiHandler.post(new Runnable() {
5257                 @Override
5258                 public void run() {
5259                     synchronized (ActivityManagerService.this) {
5260                         final Dialog d = new LaunchWarningWindow(mContext, cur, next);
5261                         d.show();
5262                         mUiHandler.postDelayed(new Runnable() {
5263                             @Override
5264                             public void run() {
5265                                 synchronized (ActivityManagerService.this) {
5266                                     d.dismiss();
5267                                     mLaunchWarningShown = false;
5268                                 }
5269                             }
5270                         }, 4000);
5271                     }
5272                 }
5273             });
5274         }
5275     }
5276
5277     @Override
5278     public boolean clearApplicationUserData(final String packageName,
5279             final IPackageDataObserver observer, int userId) {
5280         enforceNotIsolatedCaller("clearApplicationUserData");
5281         int uid = Binder.getCallingUid();
5282         int pid = Binder.getCallingPid();
5283         userId = mUserController.handleIncomingUser(pid, uid, userId, false,
5284                 ALLOW_FULL_ONLY, "clearApplicationUserData", null);
5285
5286         final DevicePolicyManagerInternal dpmi = LocalServices
5287                 .getService(DevicePolicyManagerInternal.class);
5288         if (dpmi != null && dpmi.hasDeviceOwnerOrProfileOwner(packageName, userId)) {
5289             throw new SecurityException("Cannot clear data for a device owner or a profile owner");
5290         }
5291
5292         long callingId = Binder.clearCallingIdentity();
5293         try {
5294             IPackageManager pm = AppGlobals.getPackageManager();
5295             int pkgUid = -1;
5296             synchronized(this) {
5297                 try {
5298                     pkgUid = pm.getPackageUid(packageName, MATCH_UNINSTALLED_PACKAGES, userId);
5299                 } catch (RemoteException e) {
5300                 }
5301                 if (pkgUid == -1) {
5302                     Slog.w(TAG, "Invalid packageName: " + packageName);
5303                     if (observer != null) {
5304                         try {
5305                             observer.onRemoveCompleted(packageName, false);
5306                         } catch (RemoteException e) {
5307                             Slog.i(TAG, "Observer no longer exists.");
5308                         }
5309                     }
5310                     return false;
5311                 }
5312                 if (uid == pkgUid || checkComponentPermission(
5313                         android.Manifest.permission.CLEAR_APP_USER_DATA,
5314                         pid, uid, -1, true)
5315                         == PackageManager.PERMISSION_GRANTED) {
5316                     forceStopPackageLocked(packageName, pkgUid, "clear data");
5317                 } else {
5318                     throw new SecurityException("PID " + pid + " does not have permission "
5319                             + android.Manifest.permission.CLEAR_APP_USER_DATA + " to clear data"
5320                                     + " of package " + packageName);
5321                 }
5322
5323                 // Remove all tasks match the cleared application package and user
5324                 for (int i = mRecentTasks.size() - 1; i >= 0; i--) {
5325                     final TaskRecord tr = mRecentTasks.get(i);
5326                     final String taskPackageName =
5327                             tr.getBaseIntent().getComponent().getPackageName();
5328                     if (tr.userId != userId) continue;
5329                     if (!taskPackageName.equals(packageName)) continue;
5330                     removeTaskByIdLocked(tr.taskId, false, REMOVE_FROM_RECENTS);
5331                 }
5332             }
5333
5334             try {
5335                 // Clear application user data
5336                 pm.clearApplicationUserData(packageName, observer, userId);
5337
5338                 synchronized(this) {
5339                     // Remove all permissions granted from/to this package
5340                     removeUriPermissionsForPackageLocked(packageName, userId, true);
5341                 }
5342
5343                 // Remove all zen rules created by this package; revoke it's zen access.
5344                 INotificationManager inm = NotificationManager.getService();
5345                 inm.removeAutomaticZenRules(packageName);
5346                 inm.setNotificationPolicyAccessGranted(packageName, false);
5347
5348                 Intent intent = new Intent(Intent.ACTION_PACKAGE_DATA_CLEARED,
5349                         Uri.fromParts("package", packageName, null));
5350                 intent.putExtra(Intent.EXTRA_UID, pkgUid);
5351                 intent.putExtra(Intent.EXTRA_USER_HANDLE, UserHandle.getUserId(pkgUid));
5352                 broadcastIntentInPackage("android", Process.SYSTEM_UID, intent,
5353                         null, null, 0, null, null, null, null, false, false, userId);
5354             } catch (RemoteException e) {
5355             }
5356         } finally {
5357             Binder.restoreCallingIdentity(callingId);
5358         }
5359         return true;
5360     }
5361
5362     @Override
5363     public void killBackgroundProcesses(final String packageName, int userId) {
5364         if (checkCallingPermission(android.Manifest.permission.KILL_BACKGROUND_PROCESSES)
5365                 != PackageManager.PERMISSION_GRANTED &&
5366                 checkCallingPermission(android.Manifest.permission.RESTART_PACKAGES)
5367                         != PackageManager.PERMISSION_GRANTED) {
5368             String msg = "Permission Denial: killBackgroundProcesses() from pid="
5369                     + Binder.getCallingPid()
5370                     + ", uid=" + Binder.getCallingUid()
5371                     + " requires " + android.Manifest.permission.KILL_BACKGROUND_PROCESSES;
5372             Slog.w(TAG, msg);
5373             throw new SecurityException(msg);
5374         }
5375
5376         userId = mUserController.handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(),
5377                 userId, true, ALLOW_FULL_ONLY, "killBackgroundProcesses", null);
5378         long callingId = Binder.clearCallingIdentity();
5379         try {
5380             IPackageManager pm = AppGlobals.getPackageManager();
5381             synchronized(this) {
5382                 int appId = -1;
5383                 try {
5384                     appId = UserHandle.getAppId(
5385                             pm.getPackageUid(packageName, MATCH_DEBUG_TRIAGED_MISSING, userId));
5386                 } catch (RemoteException e) {
5387                 }
5388                 if (appId == -1) {
5389                     Slog.w(TAG, "Invalid packageName: " + packageName);
5390                     return;
5391                 }
5392                 killPackageProcessesLocked(packageName, appId, userId,
5393                         ProcessList.SERVICE_ADJ, false, true, true, false, "kill background");
5394             }
5395         } finally {
5396             Binder.restoreCallingIdentity(callingId);
5397         }
5398     }
5399
5400     @Override
5401     public void killAllBackgroundProcesses() {
5402         if (checkCallingPermission(android.Manifest.permission.KILL_BACKGROUND_PROCESSES)
5403                 != PackageManager.PERMISSION_GRANTED) {
5404             final String msg = "Permission Denial: killAllBackgroundProcesses() from pid="
5405                     + Binder.getCallingPid() + ", uid=" + Binder.getCallingUid()
5406                     + " requires " + android.Manifest.permission.KILL_BACKGROUND_PROCESSES;
5407             Slog.w(TAG, msg);
5408             throw new SecurityException(msg);
5409         }
5410
5411         final long callingId = Binder.clearCallingIdentity();
5412         try {
5413             synchronized (this) {
5414                 final ArrayList<ProcessRecord> procs = new ArrayList<>();
5415                 final int NP = mProcessNames.getMap().size();
5416                 for (int ip = 0; ip < NP; ip++) {
5417                     final SparseArray<ProcessRecord> apps = mProcessNames.getMap().valueAt(ip);
5418                     final int NA = apps.size();
5419                     for (int ia = 0; ia < NA; ia++) {
5420                         final ProcessRecord app = apps.valueAt(ia);
5421                         if (app.persistent) {
5422                             // We don't kill persistent processes.
5423                             continue;
5424                         }
5425                         if (app.removed) {
5426                             procs.add(app);
5427                         } else if (app.setAdj >= ProcessList.CACHED_APP_MIN_ADJ) {
5428                             app.removed = true;
5429                             procs.add(app);
5430                         }
5431                     }
5432                 }
5433
5434                 final int N = procs.size();
5435                 for (int i = 0; i < N; i++) {
5436                     removeProcessLocked(procs.get(i), false, true, "kill all background");
5437                 }
5438
5439                 mAllowLowerMemLevel = true;
5440
5441                 updateOomAdjLocked();
5442                 doLowMemReportIfNeededLocked(null);
5443             }
5444         } finally {
5445             Binder.restoreCallingIdentity(callingId);
5446         }
5447     }
5448
5449     /**
5450      * Kills all background processes, except those matching any of the
5451      * specified properties.
5452      *
5453      * @param minTargetSdk the target SDK version at or above which to preserve
5454      *                     processes, or {@code -1} to ignore the target SDK
5455      * @param maxProcState the process state at or below which to preserve
5456      *                     processes, or {@code -1} to ignore the process state
5457      */
5458     private void killAllBackgroundProcessesExcept(int minTargetSdk, int maxProcState) {
5459         if (checkCallingPermission(android.Manifest.permission.KILL_BACKGROUND_PROCESSES)
5460                 != PackageManager.PERMISSION_GRANTED) {
5461             final String msg = "Permission Denial: killAllBackgroundProcessesExcept() from pid="
5462                     + Binder.getCallingPid() + ", uid=" + Binder.getCallingUid()
5463                     + " requires " + android.Manifest.permission.KILL_BACKGROUND_PROCESSES;
5464             Slog.w(TAG, msg);
5465             throw new SecurityException(msg);
5466         }
5467
5468         final long callingId = Binder.clearCallingIdentity();
5469         try {
5470             synchronized (this) {
5471                 final ArrayList<ProcessRecord> procs = new ArrayList<>();
5472                 final int NP = mProcessNames.getMap().size();
5473                 for (int ip = 0; ip < NP; ip++) {
5474                     final SparseArray<ProcessRecord> apps = mProcessNames.getMap().valueAt(ip);
5475                     final int NA = apps.size();
5476                     for (int ia = 0; ia < NA; ia++) {
5477                         final ProcessRecord app = apps.valueAt(ia);
5478                         if (app.removed) {
5479                             procs.add(app);
5480                         } else if ((minTargetSdk < 0 || app.info.targetSdkVersion < minTargetSdk)
5481                                 && (maxProcState < 0 || app.setProcState > maxProcState)) {
5482                             app.removed = true;
5483                             procs.add(app);
5484                         }
5485                     }
5486                 }
5487
5488                 final int N = procs.size();
5489                 for (int i = 0; i < N; i++) {
5490                     removeProcessLocked(procs.get(i), false, true, "kill all background except");
5491                 }
5492             }
5493         } finally {
5494             Binder.restoreCallingIdentity(callingId);
5495         }
5496     }
5497
5498     @Override
5499     public void forceStopPackage(final String packageName, int userId) {
5500         if (checkCallingPermission(android.Manifest.permission.FORCE_STOP_PACKAGES)
5501                 != PackageManager.PERMISSION_GRANTED) {
5502             String msg = "Permission Denial: forceStopPackage() from pid="
5503                     + Binder.getCallingPid()
5504                     + ", uid=" + Binder.getCallingUid()
5505                     + " requires " + android.Manifest.permission.FORCE_STOP_PACKAGES;
5506             Slog.w(TAG, msg);
5507             throw new SecurityException(msg);
5508         }
5509         final int callingPid = Binder.getCallingPid();
5510         userId = mUserController.handleIncomingUser(callingPid, Binder.getCallingUid(),
5511                 userId, true, ALLOW_FULL_ONLY, "forceStopPackage", null);
5512         long callingId = Binder.clearCallingIdentity();
5513         try {
5514             IPackageManager pm = AppGlobals.getPackageManager();
5515             synchronized(this) {
5516                 int[] users = userId == UserHandle.USER_ALL
5517                         ? mUserController.getUsers() : new int[] { userId };
5518                 for (int user : users) {
5519                     int pkgUid = -1;
5520                     try {
5521                         pkgUid = pm.getPackageUid(packageName, MATCH_DEBUG_TRIAGED_MISSING,
5522                                 user);
5523                     } catch (RemoteException e) {
5524                     }
5525                     if (pkgUid == -1) {
5526                         Slog.w(TAG, "Invalid packageName: " + packageName);
5527                         continue;
5528                     }
5529                     try {
5530                         pm.setPackageStoppedState(packageName, true, user);
5531                     } catch (RemoteException e) {
5532                     } catch (IllegalArgumentException e) {
5533                         Slog.w(TAG, "Failed trying to unstop package "
5534                                 + packageName + ": " + e);
5535                     }
5536                     if (mUserController.isUserRunningLocked(user, 0)) {
5537                         forceStopPackageLocked(packageName, pkgUid, "from pid " + callingPid);
5538                     }
5539                 }
5540             }
5541         } finally {
5542             Binder.restoreCallingIdentity(callingId);
5543         }
5544     }
5545
5546     @Override
5547     public void addPackageDependency(String packageName) {
5548         synchronized (this) {
5549             int callingPid = Binder.getCallingPid();
5550             if (callingPid == Process.myPid()) {
5551                 //  Yeah, um, no.
5552                 return;
5553             }
5554             ProcessRecord proc;
5555             synchronized (mPidsSelfLocked) {
5556                 proc = mPidsSelfLocked.get(Binder.getCallingPid());
5557             }
5558             if (proc != null) {
5559                 if (proc.pkgDeps == null) {
5560                     proc.pkgDeps = new ArraySet<String>(1);
5561                 }
5562                 proc.pkgDeps.add(packageName);
5563             }
5564         }
5565     }
5566
5567     /*
5568      * The pkg name and app id have to be specified.
5569      */
5570     @Override
5571     public void killApplicationWithAppId(String pkg, int appid, String reason) {
5572         if (pkg == null) {
5573             return;
5574         }
5575         // Make sure the uid is valid.
5576         if (appid < 0) {
5577             Slog.w(TAG, "Invalid appid specified for pkg : " + pkg);
5578             return;
5579         }
5580         int callerUid = Binder.getCallingUid();
5581         // Only the system server can kill an application
5582         if (UserHandle.getAppId(callerUid) == Process.SYSTEM_UID) {
5583             // Post an aysnc message to kill the application
5584             Message msg = mHandler.obtainMessage(KILL_APPLICATION_MSG);
5585             msg.arg1 = appid;
5586             msg.arg2 = 0;
5587             Bundle bundle = new Bundle();
5588             bundle.putString("pkg", pkg);
5589             bundle.putString("reason", reason);
5590             msg.obj = bundle;
5591             mHandler.sendMessage(msg);
5592         } else {
5593             throw new SecurityException(callerUid + " cannot kill pkg: " +
5594                     pkg);
5595         }
5596     }
5597
5598     @Override
5599     public void closeSystemDialogs(String reason) {
5600         enforceNotIsolatedCaller("closeSystemDialogs");
5601
5602         final int pid = Binder.getCallingPid();
5603         final int uid = Binder.getCallingUid();
5604         final long origId = Binder.clearCallingIdentity();
5605         try {
5606             synchronized (this) {
5607                 // Only allow this from foreground processes, so that background
5608                 // applications can't abuse it to prevent system UI from being shown.
5609                 if (uid >= Process.FIRST_APPLICATION_UID) {
5610                     ProcessRecord proc;
5611                     synchronized (mPidsSelfLocked) {
5612                         proc = mPidsSelfLocked.get(pid);
5613                     }
5614                     if (proc.curRawAdj > ProcessList.PERCEPTIBLE_APP_ADJ) {
5615                         Slog.w(TAG, "Ignoring closeSystemDialogs " + reason
5616                                 + " from background process " + proc);
5617                         return;
5618                     }
5619                 }
5620                 closeSystemDialogsLocked(reason);
5621             }
5622         } finally {
5623             Binder.restoreCallingIdentity(origId);
5624         }
5625     }
5626
5627     void closeSystemDialogsLocked(String reason) {
5628         Intent intent = new Intent(Intent.ACTION_CLOSE_SYSTEM_DIALOGS);
5629         intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY
5630                 | Intent.FLAG_RECEIVER_FOREGROUND);
5631         if (reason != null) {
5632             intent.putExtra("reason", reason);
5633         }
5634         mWindowManager.closeSystemDialogs(reason);
5635
5636         mStackSupervisor.closeSystemDialogsLocked();
5637
5638         broadcastIntentLocked(null, null, intent, null, null, 0, null, null, null,
5639                 AppOpsManager.OP_NONE, null, false, false,
5640                 -1, Process.SYSTEM_UID, UserHandle.USER_ALL);
5641     }
5642
5643     @Override
5644     public Debug.MemoryInfo[] getProcessMemoryInfo(int[] pids) {
5645         enforceNotIsolatedCaller("getProcessMemoryInfo");
5646         Debug.MemoryInfo[] infos = new Debug.MemoryInfo[pids.length];
5647         for (int i=pids.length-1; i>=0; i--) {
5648             ProcessRecord proc;
5649             int oomAdj;
5650             synchronized (this) {
5651                 synchronized (mPidsSelfLocked) {
5652                     proc = mPidsSelfLocked.get(pids[i]);
5653                     oomAdj = proc != null ? proc.setAdj : 0;
5654                 }
5655             }
5656             infos[i] = new Debug.MemoryInfo();
5657             Debug.getMemoryInfo(pids[i], infos[i]);
5658             if (proc != null) {
5659                 synchronized (this) {
5660                     if (proc.thread != null && proc.setAdj == oomAdj) {
5661                         // Record this for posterity if the process has been stable.
5662                         proc.baseProcessTracker.addPss(infos[i].getTotalPss(),
5663                                 infos[i].getTotalUss(), false, proc.pkgList);
5664                     }
5665                 }
5666             }
5667         }
5668         return infos;
5669     }
5670
5671     @Override
5672     public long[] getProcessPss(int[] pids) {
5673         enforceNotIsolatedCaller("getProcessPss");
5674         long[] pss = new long[pids.length];
5675         for (int i=pids.length-1; i>=0; i--) {
5676             ProcessRecord proc;
5677             int oomAdj;
5678             synchronized (this) {
5679                 synchronized (mPidsSelfLocked) {
5680                     proc = mPidsSelfLocked.get(pids[i]);
5681                     oomAdj = proc != null ? proc.setAdj : 0;
5682                 }
5683             }
5684             long[] tmpUss = new long[1];
5685             pss[i] = Debug.getPss(pids[i], tmpUss, null);
5686             if (proc != null) {
5687                 synchronized (this) {
5688                     if (proc.thread != null && proc.setAdj == oomAdj) {
5689                         // Record this for posterity if the process has been stable.
5690                         proc.baseProcessTracker.addPss(pss[i], tmpUss[0], false, proc.pkgList);
5691                     }
5692                 }
5693             }
5694         }
5695         return pss;
5696     }
5697
5698     @Override
5699     public void killApplicationProcess(String processName, int uid) {
5700         if (processName == null) {
5701             return;
5702         }
5703
5704         int callerUid = Binder.getCallingUid();
5705         // Only the system server can kill an application
5706         if (callerUid == Process.SYSTEM_UID) {
5707             synchronized (this) {
5708                 ProcessRecord app = getProcessRecordLocked(processName, uid, true);
5709                 if (app != null && app.thread != null) {
5710                     try {
5711                         app.thread.scheduleSuicide();
5712                     } catch (RemoteException e) {
5713                         // If the other end already died, then our work here is done.
5714                     }
5715                 } else {
5716                     Slog.w(TAG, "Process/uid not found attempting kill of "
5717                             + processName + " / " + uid);
5718                 }
5719             }
5720         } else {
5721             throw new SecurityException(callerUid + " cannot kill app process: " +
5722                     processName);
5723         }
5724     }
5725
5726     private void forceStopPackageLocked(final String packageName, int uid, String reason) {
5727         forceStopPackageLocked(packageName, UserHandle.getAppId(uid), false,
5728                 false, true, false, false, UserHandle.getUserId(uid), reason);
5729         Intent intent = new Intent(Intent.ACTION_PACKAGE_RESTARTED,
5730                 Uri.fromParts("package", packageName, null));
5731         if (!mProcessesReady) {
5732             intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY
5733                     | Intent.FLAG_RECEIVER_FOREGROUND);
5734         }
5735         intent.putExtra(Intent.EXTRA_UID, uid);
5736         intent.putExtra(Intent.EXTRA_USER_HANDLE, UserHandle.getUserId(uid));
5737         broadcastIntentLocked(null, null, intent,
5738                 null, null, 0, null, null, null, AppOpsManager.OP_NONE,
5739                 null, false, false, MY_PID, Process.SYSTEM_UID, UserHandle.getUserId(uid));
5740     }
5741
5742
5743     private final boolean killPackageProcessesLocked(String packageName, int appId,
5744             int userId, int minOomAdj, boolean callerWillRestart, boolean allowRestart,
5745             boolean doit, boolean evenPersistent, String reason) {
5746         ArrayList<ProcessRecord> procs = new ArrayList<>();
5747
5748         // Remove all processes this package may have touched: all with the
5749         // same UID (except for the system or root user), and all whose name
5750         // matches the package name.
5751         final int NP = mProcessNames.getMap().size();
5752         for (int ip=0; ip<NP; ip++) {
5753             SparseArray<ProcessRecord> apps = mProcessNames.getMap().valueAt(ip);
5754             final int NA = apps.size();
5755             for (int ia=0; ia<NA; ia++) {
5756                 ProcessRecord app = apps.valueAt(ia);
5757                 if (app.persistent && !evenPersistent) {
5758                     // we don't kill persistent processes
5759                     continue;
5760                 }
5761                 if (app.removed) {
5762                     if (doit) {
5763                         procs.add(app);
5764                     }
5765                     continue;
5766                 }
5767
5768                 // Skip process if it doesn't meet our oom adj requirement.
5769                 if (app.setAdj < minOomAdj) {
5770                     continue;
5771                 }
5772
5773                 // If no package is specified, we call all processes under the
5774                 // give user id.
5775                 if (packageName == null) {
5776                     if (userId != UserHandle.USER_ALL && app.userId != userId) {
5777                         continue;
5778                     }
5779                     if (appId >= 0 && UserHandle.getAppId(app.uid) != appId) {
5780                         continue;
5781                     }
5782                 // Package has been specified, we want to hit all processes
5783                 // that match it.  We need to qualify this by the processes
5784                 // that are running under the specified app and user ID.
5785                 } else {
5786                     final boolean isDep = app.pkgDeps != null
5787                             && app.pkgDeps.contains(packageName);
5788                     if (!isDep && UserHandle.getAppId(app.uid) != appId) {
5789                         continue;
5790                     }
5791                     if (userId != UserHandle.USER_ALL && app.userId != userId) {
5792                         continue;
5793                     }
5794                     if (!app.pkgList.containsKey(packageName) && !isDep) {
5795                         continue;
5796                     }
5797                 }
5798
5799                 // Process has passed all conditions, kill it!
5800                 if (!doit) {
5801                     return true;
5802                 }
5803                 app.removed = true;
5804                 procs.add(app);
5805             }
5806         }
5807
5808         int N = procs.size();
5809         for (int i=0; i<N; i++) {
5810             removeProcessLocked(procs.get(i), callerWillRestart, allowRestart, reason);
5811         }
5812         updateOomAdjLocked();
5813         return N > 0;
5814     }
5815
5816     private void cleanupDisabledPackageComponentsLocked(
5817             String packageName, int userId, boolean killProcess, String[] changedClasses) {
5818
5819         Set<String> disabledClasses = null;
5820         boolean packageDisabled = false;
5821         IPackageManager pm = AppGlobals.getPackageManager();
5822
5823         if (changedClasses == null) {
5824             // Nothing changed...
5825             return;
5826         }
5827
5828         // Determine enable/disable state of the package and its components.
5829         int enabled = PackageManager.COMPONENT_ENABLED_STATE_DEFAULT;
5830         for (int i = changedClasses.length - 1; i >= 0; i--) {
5831             final String changedClass = changedClasses[i];
5832
5833             if (changedClass.equals(packageName)) {
5834                 try {
5835                     // Entire package setting changed
5836                     enabled = pm.getApplicationEnabledSetting(packageName,
5837                             (userId != UserHandle.USER_ALL) ? userId : UserHandle.USER_SYSTEM);
5838                 } catch (Exception e) {
5839                     // No such package/component; probably racing with uninstall.  In any
5840                     // event it means we have nothing further to do here.
5841                     return;
5842                 }
5843                 packageDisabled = enabled != PackageManager.COMPONENT_ENABLED_STATE_ENABLED
5844                         && enabled != PackageManager.COMPONENT_ENABLED_STATE_DEFAULT;
5845                 if (packageDisabled) {
5846                     // Entire package is disabled.
5847                     // No need to continue to check component states.
5848                     disabledClasses = null;
5849                     break;
5850                 }
5851             } else {
5852                 try {
5853                     enabled = pm.getComponentEnabledSetting(
5854                             new ComponentName(packageName, changedClass),
5855                             (userId != UserHandle.USER_ALL) ? userId : UserHandle.USER_SYSTEM);
5856                 } catch (Exception e) {
5857                     // As above, probably racing with uninstall.
5858                     return;
5859                 }
5860                 if (enabled != PackageManager.COMPONENT_ENABLED_STATE_ENABLED
5861                         && enabled != PackageManager.COMPONENT_ENABLED_STATE_DEFAULT) {
5862                     if (disabledClasses == null) {
5863                         disabledClasses = new ArraySet<>(changedClasses.length);
5864                     }
5865                     disabledClasses.add(changedClass);
5866                 }
5867             }
5868         }
5869
5870         if (!packageDisabled && disabledClasses == null) {
5871             // Nothing to do here...
5872             return;
5873         }
5874
5875         // Clean-up disabled activities.
5876         if (mStackSupervisor.finishDisabledPackageActivitiesLocked(
5877                 packageName, disabledClasses, true, false, userId) && mBooted) {
5878             mStackSupervisor.resumeFocusedStackTopActivityLocked();
5879             mStackSupervisor.scheduleIdleLocked();
5880         }
5881
5882         // Clean-up disabled tasks
5883         cleanupDisabledPackageTasksLocked(packageName, disabledClasses, userId);
5884
5885         // Clean-up disabled services.
5886         mServices.bringDownDisabledPackageServicesLocked(
5887                 packageName, disabledClasses, userId, false, killProcess, true);
5888
5889         // Clean-up disabled providers.
5890         ArrayList<ContentProviderRecord> providers = new ArrayList<>();
5891         mProviderMap.collectPackageProvidersLocked(
5892                 packageName, disabledClasses, true, false, userId, providers);
5893         for (int i = providers.size() - 1; i >= 0; i--) {
5894             removeDyingProviderLocked(null, providers.get(i), true);
5895         }
5896
5897         // Clean-up disabled broadcast receivers.
5898         for (int i = mBroadcastQueues.length - 1; i >= 0; i--) {
5899             mBroadcastQueues[i].cleanupDisabledPackageReceiversLocked(
5900                     packageName, disabledClasses, userId, true);
5901         }
5902
5903     }
5904
5905     final boolean forceStopPackageLocked(String packageName, int appId,
5906             boolean callerWillRestart, boolean purgeCache, boolean doit,
5907             boolean evenPersistent, boolean uninstalling, int userId, String reason) {
5908         int i;
5909
5910         if (userId == UserHandle.USER_ALL && packageName == null) {
5911             Slog.w(TAG, "Can't force stop all processes of all users, that is insane!");
5912         }
5913
5914         if (appId < 0 && packageName != null) {
5915             try {
5916                 appId = UserHandle.getAppId(AppGlobals.getPackageManager()
5917                         .getPackageUid(packageName, MATCH_DEBUG_TRIAGED_MISSING, userId));
5918             } catch (RemoteException e) {
5919             }
5920         }
5921
5922         if (doit) {
5923             if (packageName != null) {
5924                 Slog.i(TAG, "Force stopping " + packageName + " appid=" + appId
5925                         + " user=" + userId + ": " + reason);
5926             } else {
5927                 Slog.i(TAG, "Force stopping u" + userId + ": " + reason);
5928             }
5929
5930             mAppErrors.resetProcessCrashTimeLocked(packageName == null, appId, userId);
5931         }
5932
5933         boolean didSomething = killPackageProcessesLocked(packageName, appId, userId,
5934                 ProcessList.INVALID_ADJ, callerWillRestart, true, doit, evenPersistent,
5935                 packageName == null ? ("stop user " + userId) : ("stop " + packageName));
5936
5937         if (mStackSupervisor.finishDisabledPackageActivitiesLocked(
5938                 packageName, null, doit, evenPersistent, userId)) {
5939             if (!doit) {
5940                 return true;
5941             }
5942             didSomething = true;
5943         }
5944
5945         if (mServices.bringDownDisabledPackageServicesLocked(
5946                 packageName, null, userId, evenPersistent, true, doit)) {
5947             if (!doit) {
5948                 return true;
5949             }
5950             didSomething = true;
5951         }
5952
5953         if (packageName == null) {
5954             // Remove all sticky broadcasts from this user.
5955             mStickyBroadcasts.remove(userId);
5956         }
5957
5958         ArrayList<ContentProviderRecord> providers = new ArrayList<>();
5959         if (mProviderMap.collectPackageProvidersLocked(packageName, null, doit, evenPersistent,
5960                 userId, providers)) {
5961             if (!doit) {
5962                 return true;
5963             }
5964             didSomething = true;
5965         }
5966         for (i = providers.size() - 1; i >= 0; i--) {
5967             removeDyingProviderLocked(null, providers.get(i), true);
5968         }
5969
5970         // Remove transient permissions granted from/to this package/user
5971         removeUriPermissionsForPackageLocked(packageName, userId, false);
5972
5973         if (doit) {
5974             for (i = mBroadcastQueues.length - 1; i >= 0; i--) {
5975                 didSomething |= mBroadcastQueues[i].cleanupDisabledPackageReceiversLocked(
5976                         packageName, null, userId, doit);
5977             }
5978         }
5979
5980         if (packageName == null || uninstalling) {
5981             // Remove pending intents.  For now we only do this when force
5982             // stopping users, because we have some problems when doing this
5983             // for packages -- app widgets are not currently cleaned up for
5984             // such packages, so they can be left with bad pending intents.
5985             if (mIntentSenderRecords.size() > 0) {
5986                 Iterator<WeakReference<PendingIntentRecord>> it
5987                         = mIntentSenderRecords.values().iterator();
5988                 while (it.hasNext()) {
5989                     WeakReference<PendingIntentRecord> wpir = it.next();
5990                     if (wpir == null) {
5991                         it.remove();
5992                         continue;
5993                     }
5994                     PendingIntentRecord pir = wpir.get();
5995                     if (pir == null) {
5996                         it.remove();
5997                         continue;
5998                     }
5999                     if (packageName == null) {
6000                         // Stopping user, remove all objects for the user.
6001                         if (pir.key.userId != userId) {
6002                             // Not the same user, skip it.
6003                             continue;
6004                         }
6005                     } else {
6006                         if (UserHandle.getAppId(pir.uid) != appId) {
6007                             // Different app id, skip it.
6008                             continue;
6009                         }
6010                         if (userId != UserHandle.USER_ALL && pir.key.userId != userId) {
6011                             // Different user, skip it.
6012                             continue;
6013                         }
6014                         if (!pir.key.packageName.equals(packageName)) {
6015                             // Different package, skip it.
6016                             continue;
6017                         }
6018                     }
6019                     if (!doit) {
6020                         return true;
6021                     }
6022                     didSomething = true;
6023                     it.remove();
6024                     pir.canceled = true;
6025                     if (pir.key.activity != null && pir.key.activity.pendingResults != null) {
6026                         pir.key.activity.pendingResults.remove(pir.ref);
6027                     }
6028                 }
6029             }
6030         }
6031
6032         if (doit) {
6033             if (purgeCache && packageName != null) {
6034                 AttributeCache ac = AttributeCache.instance();
6035                 if (ac != null) {
6036                     ac.removePackage(packageName);
6037                 }
6038             }
6039             if (mBooted) {
6040                 mStackSupervisor.resumeFocusedStackTopActivityLocked();
6041                 mStackSupervisor.scheduleIdleLocked();
6042             }
6043         }
6044
6045         return didSomething;
6046     }
6047
6048     private final ProcessRecord removeProcessNameLocked(final String name, final int uid) {
6049         ProcessRecord old = mProcessNames.remove(name, uid);
6050         if (old != null) {
6051             old.uidRecord.numProcs--;
6052             if (old.uidRecord.numProcs == 0) {
6053                 // No more processes using this uid, tell clients it is gone.
6054                 if (DEBUG_UID_OBSERVERS) Slog.i(TAG_UID_OBSERVERS,
6055                         "No more processes in " + old.uidRecord);
6056                 enqueueUidChangeLocked(old.uidRecord, -1, UidRecord.CHANGE_GONE);
6057                 mActiveUids.remove(uid);
6058                 mBatteryStatsService.noteUidProcessState(uid,
6059                         ActivityManager.PROCESS_STATE_NONEXISTENT);
6060             }
6061             old.uidRecord = null;
6062         }
6063         mIsolatedProcesses.remove(uid);
6064         return old;
6065     }
6066
6067     private final void addProcessNameLocked(ProcessRecord proc) {
6068         // We shouldn't already have a process under this name, but just in case we
6069         // need to clean up whatever may be there now.
6070         ProcessRecord old = removeProcessNameLocked(proc.processName, proc.uid);
6071         if (old == proc && proc.persistent) {
6072             // We are re-adding a persistent process.  Whatevs!  Just leave it there.
6073             Slog.w(TAG, "Re-adding persistent process " + proc);
6074         } else if (old != null) {
6075             Slog.wtf(TAG, "Already have existing proc " + old + " when adding " + proc);
6076         }
6077         UidRecord uidRec = mActiveUids.get(proc.uid);
6078         if (uidRec == null) {
6079             uidRec = new UidRecord(proc.uid);
6080             // This is the first appearance of the uid, report it now!
6081             if (DEBUG_UID_OBSERVERS) Slog.i(TAG_UID_OBSERVERS,
6082                     "Creating new process uid: " + uidRec);
6083             mActiveUids.put(proc.uid, uidRec);
6084             mBatteryStatsService.noteUidProcessState(uidRec.uid, uidRec.curProcState);
6085             enqueueUidChangeLocked(uidRec, -1, UidRecord.CHANGE_ACTIVE);
6086         }
6087         proc.uidRecord = uidRec;
6088         uidRec.numProcs++;
6089         mProcessNames.put(proc.processName, proc.uid, proc);
6090         if (proc.isolated) {
6091             mIsolatedProcesses.put(proc.uid, proc);
6092         }
6093     }
6094
6095     boolean removeProcessLocked(ProcessRecord app,
6096             boolean callerWillRestart, boolean allowRestart, String reason) {
6097         final String name = app.processName;
6098         final int uid = app.uid;
6099         if (DEBUG_PROCESSES) Slog.d(TAG_PROCESSES,
6100             "Force removing proc " + app.toShortString() + " (" + name + "/" + uid + ")");
6101
6102         removeProcessNameLocked(name, uid);
6103         if (mHeavyWeightProcess == app) {
6104             mHandler.sendMessage(mHandler.obtainMessage(CANCEL_HEAVY_NOTIFICATION_MSG,
6105                     mHeavyWeightProcess.userId, 0));
6106             mHeavyWeightProcess = null;
6107         }
6108         boolean needRestart = false;
6109         if (app.pid > 0 && app.pid != MY_PID) {
6110             int pid = app.pid;
6111             synchronized (mPidsSelfLocked) {
6112                 mPidsSelfLocked.remove(pid);
6113                 mHandler.removeMessages(PROC_START_TIMEOUT_MSG, app);
6114             }
6115             mBatteryStatsService.noteProcessFinish(app.processName, app.info.uid);
6116             if (app.isolated) {
6117                 mBatteryStatsService.removeIsolatedUid(app.uid, app.info.uid);
6118             }
6119             boolean willRestart = false;
6120             if (app.persistent && !app.isolated) {
6121                 if (!callerWillRestart) {
6122                     willRestart = true;
6123                 } else {
6124                     needRestart = true;
6125                 }
6126             }
6127             app.kill(reason, true);
6128             handleAppDiedLocked(app, willRestart, allowRestart);
6129             if (willRestart) {
6130                 removeLruProcessLocked(app);
6131                 addAppLocked(app.info, false, null /* ABI override */);
6132             }
6133         } else {
6134             mRemovedProcesses.add(app);
6135         }
6136
6137         return needRestart;
6138     }
6139
6140     private final void processContentProviderPublishTimedOutLocked(ProcessRecord app) {
6141         cleanupAppInLaunchingProvidersLocked(app, true);
6142         removeProcessLocked(app, false, true, "timeout publishing content providers");
6143     }
6144
6145     private final void processStartTimedOutLocked(ProcessRecord app) {
6146         final int pid = app.pid;
6147         boolean gone = false;
6148         synchronized (mPidsSelfLocked) {
6149             ProcessRecord knownApp = mPidsSelfLocked.get(pid);
6150             if (knownApp != null && knownApp.thread == null) {
6151                 mPidsSelfLocked.remove(pid);
6152                 gone = true;
6153             }
6154         }
6155
6156         if (gone) {
6157             Slog.w(TAG, "Process " + app + " failed to attach");
6158             EventLog.writeEvent(EventLogTags.AM_PROCESS_START_TIMEOUT, app.userId,
6159                     pid, app.uid, app.processName);
6160             removeProcessNameLocked(app.processName, app.uid);
6161             if (mHeavyWeightProcess == app) {
6162                 mHandler.sendMessage(mHandler.obtainMessage(CANCEL_HEAVY_NOTIFICATION_MSG,
6163                         mHeavyWeightProcess.userId, 0));
6164                 mHeavyWeightProcess = null;
6165             }
6166             mBatteryStatsService.noteProcessFinish(app.processName, app.info.uid);
6167             if (app.isolated) {
6168                 mBatteryStatsService.removeIsolatedUid(app.uid, app.info.uid);
6169             }
6170             // Take care of any launching providers waiting for this process.
6171             cleanupAppInLaunchingProvidersLocked(app, true);
6172             // Take care of any services that are waiting for the process.
6173             mServices.processStartTimedOutLocked(app);
6174             app.kill("start timeout", true);
6175             removeLruProcessLocked(app);
6176             if (mBackupTarget != null && mBackupTarget.app.pid == pid) {
6177                 Slog.w(TAG, "Unattached app died before backup, skipping");
6178                 try {
6179                     IBackupManager bm = IBackupManager.Stub.asInterface(
6180                             ServiceManager.getService(Context.BACKUP_SERVICE));
6181                     bm.agentDisconnected(app.info.packageName);
6182                 } catch (RemoteException e) {
6183                     // Can't happen; the backup manager is local
6184                 }
6185             }
6186             if (isPendingBroadcastProcessLocked(pid)) {
6187                 Slog.w(TAG, "Unattached app died before broadcast acknowledged, skipping");
6188                 skipPendingBroadcastLocked(pid);
6189             }
6190         } else {
6191             Slog.w(TAG, "Spurious process start timeout - pid not known for " + app);
6192         }
6193     }
6194
6195     private final boolean attachApplicationLocked(IApplicationThread thread,
6196             int pid) {
6197
6198         // Find the application record that is being attached...  either via
6199         // the pid if we are running in multiple processes, or just pull the
6200         // next app record if we are emulating process with anonymous threads.
6201         ProcessRecord app;
6202         if (pid != MY_PID && pid >= 0) {
6203             synchronized (mPidsSelfLocked) {
6204                 app = mPidsSelfLocked.get(pid);
6205             }
6206         } else {
6207             app = null;
6208         }
6209
6210         if (app == null) {
6211             Slog.w(TAG, "No pending application record for pid " + pid
6212                     + " (IApplicationThread " + thread + "); dropping process");
6213             EventLog.writeEvent(EventLogTags.AM_DROP_PROCESS, pid);
6214             if (pid > 0 && pid != MY_PID) {
6215                 Process.killProcessQuiet(pid);
6216                 //TODO: killProcessGroup(app.info.uid, pid);
6217             } else {
6218                 try {
6219                     thread.scheduleExit();
6220                 } catch (Exception e) {
6221                     // Ignore exceptions.
6222                 }
6223             }
6224             return false;
6225         }
6226
6227         // If this application record is still attached to a previous
6228         // process, clean it up now.
6229         if (app.thread != null) {
6230             handleAppDiedLocked(app, true, true);
6231         }
6232
6233         // Tell the process all about itself.
6234
6235         if (DEBUG_ALL) Slog.v(
6236                 TAG, "Binding process pid " + pid + " to record " + app);
6237
6238         final String processName = app.processName;
6239         try {
6240             AppDeathRecipient adr = new AppDeathRecipient(
6241                     app, pid, thread);
6242             thread.asBinder().linkToDeath(adr, 0);
6243             app.deathRecipient = adr;
6244         } catch (RemoteException e) {
6245             app.resetPackageList(mProcessStats);
6246             startProcessLocked(app, "link fail", processName);
6247             return false;
6248         }
6249
6250         EventLog.writeEvent(EventLogTags.AM_PROC_BOUND, app.userId, app.pid, app.processName);
6251
6252         app.makeActive(thread, mProcessStats);
6253         app.curAdj = app.setAdj = ProcessList.INVALID_ADJ;
6254         app.curSchedGroup = app.setSchedGroup = ProcessList.SCHED_GROUP_DEFAULT;
6255         app.forcingToForeground = null;
6256         updateProcessForegroundLocked(app, false, false);
6257         app.hasShownUi = false;
6258         app.debugging = false;
6259         app.cached = false;
6260         app.killedByAm = false;
6261
6262         mHandler.removeMessages(PROC_START_TIMEOUT_MSG, app);
6263
6264         boolean normalMode = mProcessesReady || isAllowedWhileBooting(app.info);
6265         List<ProviderInfo> providers = normalMode ? generateApplicationProvidersLocked(app) : null;
6266
6267         if (providers != null && checkAppInLaunchingProvidersLocked(app)) {
6268             Message msg = mHandler.obtainMessage(CONTENT_PROVIDER_PUBLISH_TIMEOUT_MSG);
6269             msg.obj = app;
6270             mHandler.sendMessageDelayed(msg, CONTENT_PROVIDER_PUBLISH_TIMEOUT);
6271         }
6272
6273         if (!normalMode) {
6274             Slog.i(TAG, "Launching preboot mode app: " + app);
6275         }
6276
6277         if (DEBUG_ALL) Slog.v(
6278             TAG, "New app record " + app
6279             + " thread=" + thread.asBinder() + " pid=" + pid);
6280         try {
6281             int testMode = IApplicationThread.DEBUG_OFF;
6282             if (mDebugApp != null && mDebugApp.equals(processName)) {
6283                 testMode = mWaitForDebugger
6284                     ? IApplicationThread.DEBUG_WAIT
6285                     : IApplicationThread.DEBUG_ON;
6286                 app.debugging = true;
6287                 if (mDebugTransient) {
6288                     mDebugApp = mOrigDebugApp;
6289                     mWaitForDebugger = mOrigWaitForDebugger;
6290                 }
6291             }
6292             String profileFile = app.instrumentationProfileFile;
6293             ParcelFileDescriptor profileFd = null;
6294             int samplingInterval = 0;
6295             boolean profileAutoStop = false;
6296             if (mProfileApp != null && mProfileApp.equals(processName)) {
6297                 mProfileProc = app;
6298                 profileFile = mProfileFile;
6299                 profileFd = mProfileFd;
6300                 samplingInterval = mSamplingInterval;
6301                 profileAutoStop = mAutoStopProfiler;
6302             }
6303             boolean enableTrackAllocation = false;
6304             if (mTrackAllocationApp != null && mTrackAllocationApp.equals(processName)) {
6305                 enableTrackAllocation = true;
6306                 mTrackAllocationApp = null;
6307             }
6308
6309             // If the app is being launched for restore or full backup, set it up specially
6310             boolean isRestrictedBackupMode = false;
6311             if (mBackupTarget != null && mBackupAppName.equals(processName)) {
6312                 isRestrictedBackupMode = mBackupTarget.appInfo.uid >= Process.FIRST_APPLICATION_UID
6313                         && ((mBackupTarget.backupMode == BackupRecord.RESTORE)
6314                                 || (mBackupTarget.backupMode == BackupRecord.RESTORE_FULL)
6315                                 || (mBackupTarget.backupMode == BackupRecord.BACKUP_FULL));
6316             }
6317
6318             notifyPackageUse(app.instrumentationInfo != null
6319                     ? app.instrumentationInfo.packageName
6320                     : app.info.packageName);
6321             if (app.instrumentationClass != null) {
6322                 notifyPackageUse(app.instrumentationClass.getPackageName());
6323             }
6324             if (DEBUG_CONFIGURATION) Slog.v(TAG_CONFIGURATION, "Binding proc "
6325                     + processName + " with config " + mConfiguration);
6326             ApplicationInfo appInfo = app.instrumentationInfo != null
6327                     ? app.instrumentationInfo : app.info;
6328             app.compat = compatibilityInfoForPackageLocked(appInfo);
6329             if (profileFd != null) {
6330                 profileFd = profileFd.dup();
6331             }
6332             ProfilerInfo profilerInfo = profileFile == null ? null
6333                     : new ProfilerInfo(profileFile, profileFd, samplingInterval, profileAutoStop);
6334             thread.bindApplication(processName, appInfo, providers, app.instrumentationClass,
6335                     profilerInfo, app.instrumentationArguments, app.instrumentationWatcher,
6336                     app.instrumentationUiAutomationConnection, testMode,
6337                     mBinderTransactionTrackingEnabled, enableTrackAllocation,
6338                     isRestrictedBackupMode || !normalMode, app.persistent,
6339                     new Configuration(mConfiguration), app.compat,
6340                     getCommonServicesLocked(app.isolated),
6341                     mCoreSettingsObserver.getCoreSettingsLocked());
6342             updateLruProcessLocked(app, false, null);
6343             app.lastRequestedGc = app.lastLowMemory = SystemClock.uptimeMillis();
6344         } catch (Exception e) {
6345             // todo: Yikes!  What should we do?  For now we will try to
6346             // start another process, but that could easily get us in
6347             // an infinite loop of restarting processes...
6348             Slog.wtf(TAG, "Exception thrown during bind of " + app, e);
6349
6350             app.resetPackageList(mProcessStats);
6351             app.unlinkDeathRecipient();
6352             startProcessLocked(app, "bind fail", processName);
6353             return false;
6354         }
6355
6356         // Remove this record from the list of starting applications.
6357         mPersistentStartingProcesses.remove(app);
6358         if (DEBUG_PROCESSES && mProcessesOnHold.contains(app)) Slog.v(TAG_PROCESSES,
6359                 "Attach application locked removing on hold: " + app);
6360         mProcessesOnHold.remove(app);
6361
6362         boolean badApp = false;
6363         boolean didSomething = false;
6364
6365         // See if the top visible activity is waiting to run in this process...
6366         if (normalMode) {
6367             try {
6368                 if (mStackSupervisor.attachApplicationLocked(app)) {
6369                     didSomething = true;
6370                 }
6371             } catch (Exception e) {
6372                 Slog.wtf(TAG, "Exception thrown launching activities in " + app, e);
6373                 badApp = true;
6374             }
6375         }
6376
6377         // Find any services that should be running in this process...
6378         if (!badApp) {
6379             try {
6380                 didSomething |= mServices.attachApplicationLocked(app, processName);
6381             } catch (Exception e) {
6382                 Slog.wtf(TAG, "Exception thrown starting services in " + app, e);
6383                 badApp = true;
6384             }
6385         }
6386
6387         // Check if a next-broadcast receiver is in this process...
6388         if (!badApp && isPendingBroadcastProcessLocked(pid)) {
6389             try {
6390                 didSomething |= sendPendingBroadcastsLocked(app);
6391             } catch (Exception e) {
6392                 // If the app died trying to launch the receiver we declare it 'bad'
6393                 Slog.wtf(TAG, "Exception thrown dispatching broadcasts in " + app, e);
6394                 badApp = true;
6395             }
6396         }
6397
6398         // Check whether the next backup agent is in this process...
6399         if (!badApp && mBackupTarget != null && mBackupTarget.appInfo.uid == app.uid) {
6400             if (DEBUG_BACKUP) Slog.v(TAG_BACKUP,
6401                     "New app is backup target, launching agent for " + app);
6402             notifyPackageUse(mBackupTarget.appInfo.packageName);
6403             try {
6404                 thread.scheduleCreateBackupAgent(mBackupTarget.appInfo,
6405                         compatibilityInfoForPackageLocked(mBackupTarget.appInfo),
6406                         mBackupTarget.backupMode);
6407             } catch (Exception e) {
6408                 Slog.wtf(TAG, "Exception thrown creating backup agent in " + app, e);
6409                 badApp = true;
6410             }
6411         }
6412
6413         if (badApp) {
6414             app.kill("error during init", true);
6415             handleAppDiedLocked(app, false, true);
6416             return false;
6417         }
6418
6419         if (!didSomething) {
6420             updateOomAdjLocked();
6421         }
6422
6423         return true;
6424     }
6425
6426     @Override
6427     public final void attachApplication(IApplicationThread thread) {
6428         synchronized (this) {
6429             int callingPid = Binder.getCallingPid();
6430             final long origId = Binder.clearCallingIdentity();
6431             attachApplicationLocked(thread, callingPid);
6432             Binder.restoreCallingIdentity(origId);
6433         }
6434     }
6435
6436     @Override
6437     public final void activityIdle(IBinder token, Configuration config, boolean stopProfiling) {
6438         final long origId = Binder.clearCallingIdentity();
6439         synchronized (this) {
6440             ActivityStack stack = ActivityRecord.getStackLocked(token);
6441             if (stack != null) {
6442                 ActivityRecord r =
6443                         mStackSupervisor.activityIdleInternalLocked(token, false, config);
6444                 if (stopProfiling) {
6445                     if ((mProfileProc == r.app) && (mProfileFd != null)) {
6446                         try {
6447                             mProfileFd.close();
6448                         } catch (IOException e) {
6449                         }
6450                         clearProfilerLocked();
6451                     }
6452                 }
6453             }
6454         }
6455         Binder.restoreCallingIdentity(origId);
6456     }
6457
6458     void postFinishBooting(boolean finishBooting, boolean enableScreen) {
6459         mHandler.sendMessage(mHandler.obtainMessage(FINISH_BOOTING_MSG,
6460                 finishBooting ? 1 : 0, enableScreen ? 1 : 0));
6461     }
6462
6463     void enableScreenAfterBoot() {
6464         EventLog.writeEvent(EventLogTags.BOOT_PROGRESS_ENABLE_SCREEN,
6465                 SystemClock.uptimeMillis());
6466         mWindowManager.enableScreenAfterBoot();
6467
6468         synchronized (this) {
6469             updateEventDispatchingLocked();
6470         }
6471     }
6472
6473     @Override
6474     public void showBootMessage(final CharSequence msg, final boolean always) {
6475         if (Binder.getCallingUid() != Process.myUid()) {
6476             // These days only the core system can call this, so apps can't get in
6477             // the way of what we show about running them.
6478         }
6479         mWindowManager.showBootMessage(msg, always);
6480     }
6481
6482     @Override
6483     public void keyguardWaitingForActivityDrawn() {
6484         enforceNotIsolatedCaller("keyguardWaitingForActivityDrawn");
6485         final long token = Binder.clearCallingIdentity();
6486         try {
6487             synchronized (this) {
6488                 if (DEBUG_LOCKSCREEN) logLockScreen("");
6489                 mWindowManager.keyguardWaitingForActivityDrawn();
6490                 if (mLockScreenShown == LOCK_SCREEN_SHOWN) {
6491                     mLockScreenShown = LOCK_SCREEN_LEAVING;
6492                     updateSleepIfNeededLocked();
6493                 }
6494             }
6495         } finally {
6496             Binder.restoreCallingIdentity(token);
6497         }
6498     }
6499
6500     @Override
6501     public void keyguardGoingAway(int flags) {
6502         enforceNotIsolatedCaller("keyguardGoingAway");
6503         final long token = Binder.clearCallingIdentity();
6504         try {
6505             synchronized (this) {
6506                 if (DEBUG_LOCKSCREEN) logLockScreen("");
6507                 mWindowManager.keyguardGoingAway(flags);
6508                 if (mLockScreenShown == LOCK_SCREEN_SHOWN) {
6509                     mLockScreenShown = LOCK_SCREEN_HIDDEN;
6510                     updateSleepIfNeededLocked();
6511
6512                     // Some stack visibility might change (e.g. docked stack)
6513                     mStackSupervisor.ensureActivitiesVisibleLocked(null, 0, !PRESERVE_WINDOWS);
6514                 }
6515             }
6516         } finally {
6517             Binder.restoreCallingIdentity(token);
6518         }
6519     }
6520
6521     final void finishBooting() {
6522         synchronized (this) {
6523             if (!mBootAnimationComplete) {
6524                 mCallFinishBooting = true;
6525                 return;
6526             }
6527             mCallFinishBooting = false;
6528         }
6529
6530         ArraySet<String> completedIsas = new ArraySet<String>();
6531         for (String abi : Build.SUPPORTED_ABIS) {
6532             Process.establishZygoteConnectionForAbi(abi);
6533             final String instructionSet = VMRuntime.getInstructionSet(abi);
6534             if (!completedIsas.contains(instructionSet)) {
6535                 try {
6536                     mInstaller.markBootComplete(VMRuntime.getInstructionSet(abi));
6537                 } catch (InstallerException e) {
6538                     Slog.e(TAG, "Unable to mark boot complete for abi: " + abi, e);
6539                 }
6540                 completedIsas.add(instructionSet);
6541             }
6542         }
6543
6544         IntentFilter pkgFilter = new IntentFilter();
6545         pkgFilter.addAction(Intent.ACTION_QUERY_PACKAGE_RESTART);
6546         pkgFilter.addDataScheme("package");
6547         mContext.registerReceiver(new BroadcastReceiver() {
6548             @Override
6549             public void onReceive(Context context, Intent intent) {
6550                 String[] pkgs = intent.getStringArrayExtra(Intent.EXTRA_PACKAGES);
6551                 if (pkgs != null) {
6552                     for (String pkg : pkgs) {
6553                         synchronized (ActivityManagerService.this) {
6554                             if (forceStopPackageLocked(pkg, -1, false, false, false, false, false,
6555                                     0, "query restart")) {
6556                                 setResultCode(Activity.RESULT_OK);
6557                                 return;
6558                             }
6559                         }
6560                     }
6561                 }
6562             }
6563         }, pkgFilter);
6564
6565         IntentFilter dumpheapFilter = new IntentFilter();
6566         dumpheapFilter.addAction(DumpHeapActivity.ACTION_DELETE_DUMPHEAP);
6567         mContext.registerReceiver(new BroadcastReceiver() {
6568             @Override
6569             public void onReceive(Context context, Intent intent) {
6570                 if (intent.getBooleanExtra(DumpHeapActivity.EXTRA_DELAY_DELETE, false)) {
6571                     mHandler.sendEmptyMessageDelayed(POST_DUMP_HEAP_NOTIFICATION_MSG, 5*60*1000);
6572                 } else {
6573                     mHandler.sendEmptyMessage(POST_DUMP_HEAP_NOTIFICATION_MSG);
6574                 }
6575             }
6576         }, dumpheapFilter);
6577
6578         mProcessStartLogger.registerListener(mContext);
6579
6580         // Let system services know.
6581         mSystemServiceManager.startBootPhase(SystemService.PHASE_BOOT_COMPLETED);
6582
6583         synchronized (this) {
6584             // Ensure that any processes we had put on hold are now started
6585             // up.
6586             final int NP = mProcessesOnHold.size();
6587             if (NP > 0) {
6588                 ArrayList<ProcessRecord> procs =
6589                     new ArrayList<ProcessRecord>(mProcessesOnHold);
6590                 for (int ip=0; ip<NP; ip++) {
6591                     if (DEBUG_PROCESSES) Slog.v(TAG_PROCESSES, "Starting process on hold: "
6592                             + procs.get(ip));
6593                     startProcessLocked(procs.get(ip), "on-hold", null);
6594                 }
6595             }
6596
6597             if (mFactoryTest != FactoryTest.FACTORY_TEST_LOW_LEVEL) {
6598                 // Start looking for apps that are abusing wake locks.
6599                 Message nmsg = mHandler.obtainMessage(CHECK_EXCESSIVE_WAKE_LOCKS_MSG);
6600                 mHandler.sendMessageDelayed(nmsg, POWER_CHECK_DELAY);
6601                 // Tell anyone interested that we are done booting!
6602                 SystemProperties.set("sys.boot_completed", "1");
6603
6604                 // And trigger dev.bootcomplete if we are not showing encryption progress
6605                 if (!"trigger_restart_min_framework".equals(SystemProperties.get("vold.decrypt"))
6606                     || "".equals(SystemProperties.get("vold.encrypt_progress"))) {
6607                     SystemProperties.set("dev.bootcomplete", "1");
6608                 }
6609                 mUserController.sendBootCompletedLocked(
6610                         new IIntentReceiver.Stub() {
6611                             @Override
6612                             public void performReceive(Intent intent, int resultCode,
6613                                     String data, Bundle extras, boolean ordered,
6614                                     boolean sticky, int sendingUser) {
6615                                 synchronized (ActivityManagerService.this) {
6616                                     requestPssAllProcsLocked(SystemClock.uptimeMillis(),
6617                                             true, false);
6618                                 }
6619                             }
6620                         });
6621                 scheduleStartProfilesLocked();
6622             }
6623         }
6624     }
6625
6626     @Override
6627     public void bootAnimationComplete() {
6628         final boolean callFinishBooting;
6629         synchronized (this) {
6630             callFinishBooting = mCallFinishBooting;
6631             mBootAnimationComplete = true;
6632         }
6633         if (callFinishBooting) {
6634             Trace.traceBegin(Trace.TRACE_TAG_ACTIVITY_MANAGER, "FinishBooting");
6635             finishBooting();
6636             Trace.traceEnd(Trace.TRACE_TAG_ACTIVITY_MANAGER);
6637         }
6638     }
6639
6640     final void ensureBootCompleted() {
6641         boolean booting;
6642         boolean enableScreen;
6643         synchronized (this) {
6644             booting = mBooting;
6645             mBooting = false;
6646             enableScreen = !mBooted;
6647             mBooted = true;
6648         }
6649
6650         if (booting) {
6651             Trace.traceBegin(Trace.TRACE_TAG_ACTIVITY_MANAGER, "FinishBooting");
6652             finishBooting();
6653             Trace.traceEnd(Trace.TRACE_TAG_ACTIVITY_MANAGER);
6654         }
6655
6656         if (enableScreen) {
6657             enableScreenAfterBoot();
6658         }
6659     }
6660
6661     @Override
6662     public final void activityResumed(IBinder token) {
6663         final long origId = Binder.clearCallingIdentity();
6664         synchronized(this) {
6665             ActivityStack stack = ActivityRecord.getStackLocked(token);
6666             if (stack != null) {
6667                 stack.activityResumedLocked(token);
6668             }
6669         }
6670         Binder.restoreCallingIdentity(origId);
6671     }
6672
6673     @Override
6674     public final void activityPaused(IBinder token) {
6675         final long origId = Binder.clearCallingIdentity();
6676         synchronized(this) {
6677             ActivityStack stack = ActivityRecord.getStackLocked(token);
6678             if (stack != null) {
6679                 stack.activityPausedLocked(token, false);
6680             }
6681         }
6682         Binder.restoreCallingIdentity(origId);
6683     }
6684
6685     @Override
6686     public final void activityStopped(IBinder token, Bundle icicle,
6687             PersistableBundle persistentState, CharSequence description) {
6688         if (DEBUG_ALL) Slog.v(TAG, "Activity stopped: token=" + token);
6689
6690         // Refuse possible leaked file descriptors
6691         if (icicle != null && icicle.hasFileDescriptors()) {
6692             throw new IllegalArgumentException("File descriptors passed in Bundle");
6693         }
6694
6695         final long origId = Binder.clearCallingIdentity();
6696
6697         synchronized (this) {
6698             ActivityRecord r = ActivityRecord.isInStackLocked(token);
6699             if (r != null) {
6700                 r.task.stack.activityStoppedLocked(r, icicle, persistentState, description);
6701             }
6702         }
6703
6704         trimApplications();
6705
6706         Binder.restoreCallingIdentity(origId);
6707     }
6708
6709     @Override
6710     public final void activityDestroyed(IBinder token) {
6711         if (DEBUG_SWITCH) Slog.v(TAG_SWITCH, "ACTIVITY DESTROYED: " + token);
6712         synchronized (this) {
6713             ActivityStack stack = ActivityRecord.getStackLocked(token);
6714             if (stack != null) {
6715                 stack.activityDestroyedLocked(token, "activityDestroyed");
6716             }
6717         }
6718     }
6719
6720     @Override
6721     public final void activityRelaunched(IBinder token) {
6722         final long origId = Binder.clearCallingIdentity();
6723         synchronized (this) {
6724             mStackSupervisor.activityRelaunchedLocked(token);
6725         }
6726         Binder.restoreCallingIdentity(origId);
6727     }
6728
6729     @Override
6730     public void reportSizeConfigurations(IBinder token, int[] horizontalSizeConfiguration,
6731             int[] verticalSizeConfigurations, int[] smallestSizeConfigurations) {
6732         if (DEBUG_CONFIGURATION) Slog.v(TAG, "Report configuration: " + token + " "
6733                 + horizontalSizeConfiguration + " " + verticalSizeConfigurations);
6734         synchronized (this) {
6735             ActivityRecord record = ActivityRecord.isInStackLocked(token);
6736             if (record == null) {
6737                 throw new IllegalArgumentException("reportSizeConfigurations: ActivityRecord not "
6738                         + "found for: " + token);
6739             }
6740             record.setSizeConfigurations(horizontalSizeConfiguration,
6741                     verticalSizeConfigurations, smallestSizeConfigurations);
6742         }
6743     }
6744
6745     @Override
6746     public final void backgroundResourcesReleased(IBinder token) {
6747         final long origId = Binder.clearCallingIdentity();
6748         try {
6749             synchronized (this) {
6750                 ActivityStack stack = ActivityRecord.getStackLocked(token);
6751                 if (stack != null) {
6752                     stack.backgroundResourcesReleased();
6753                 }
6754             }
6755         } finally {
6756             Binder.restoreCallingIdentity(origId);
6757         }
6758     }
6759
6760     @Override
6761     public final void notifyLaunchTaskBehindComplete(IBinder token) {
6762         mStackSupervisor.scheduleLaunchTaskBehindComplete(token);
6763     }
6764
6765     @Override
6766     public final void notifyEnterAnimationComplete(IBinder token) {
6767         mHandler.sendMessage(mHandler.obtainMessage(ENTER_ANIMATION_COMPLETE_MSG, token));
6768     }
6769
6770     @Override
6771     public String getCallingPackage(IBinder token) {
6772         synchronized (this) {
6773             ActivityRecord r = getCallingRecordLocked(token);
6774             return r != null ? r.info.packageName : null;
6775         }
6776     }
6777
6778     @Override
6779     public ComponentName getCallingActivity(IBinder token) {
6780         synchronized (this) {
6781             ActivityRecord r = getCallingRecordLocked(token);
6782             return r != null ? r.intent.getComponent() : null;
6783         }
6784     }
6785
6786     private ActivityRecord getCallingRecordLocked(IBinder token) {
6787         ActivityRecord r = ActivityRecord.isInStackLocked(token);
6788         if (r == null) {
6789             return null;
6790         }
6791         return r.resultTo;
6792     }
6793
6794     @Override
6795     public ComponentName getActivityClassForToken(IBinder token) {
6796         synchronized(this) {
6797             ActivityRecord r = ActivityRecord.isInStackLocked(token);
6798             if (r == null) {
6799                 return null;
6800             }
6801             return r.intent.getComponent();
6802         }
6803     }
6804
6805     @Override
6806     public String getPackageForToken(IBinder token) {
6807         synchronized(this) {
6808             ActivityRecord r = ActivityRecord.isInStackLocked(token);
6809             if (r == null) {
6810                 return null;
6811             }
6812             return r.packageName;
6813         }
6814     }
6815
6816     @Override
6817     public boolean isRootVoiceInteraction(IBinder token) {
6818         synchronized(this) {
6819             ActivityRecord r = ActivityRecord.isInStackLocked(token);
6820             if (r == null) {
6821                 return false;
6822             }
6823             return r.rootVoiceInteraction;
6824         }
6825     }
6826
6827     @Override
6828     public IIntentSender getIntentSender(int type,
6829             String packageName, IBinder token, String resultWho,
6830             int requestCode, Intent[] intents, String[] resolvedTypes,
6831             int flags, Bundle bOptions, int userId) {
6832         enforceNotIsolatedCaller("getIntentSender");
6833         // Refuse possible leaked file descriptors
6834         if (intents != null) {
6835             if (intents.length < 1) {
6836                 throw new IllegalArgumentException("Intents array length must be >= 1");
6837             }
6838             for (int i=0; i<intents.length; i++) {
6839                 Intent intent = intents[i];
6840                 if (intent != null) {
6841                     if (intent.hasFileDescriptors()) {
6842                         throw new IllegalArgumentException("File descriptors passed in Intent");
6843                     }
6844                     if (type == ActivityManager.INTENT_SENDER_BROADCAST &&
6845                             (intent.getFlags()&Intent.FLAG_RECEIVER_BOOT_UPGRADE) != 0) {
6846                         throw new IllegalArgumentException(
6847                                 "Can't use FLAG_RECEIVER_BOOT_UPGRADE here");
6848                     }
6849                     intents[i] = new Intent(intent);
6850                 }
6851             }
6852             if (resolvedTypes != null && resolvedTypes.length != intents.length) {
6853                 throw new IllegalArgumentException(
6854                         "Intent array length does not match resolvedTypes length");
6855             }
6856         }
6857         if (bOptions != null) {
6858             if (bOptions.hasFileDescriptors()) {
6859                 throw new IllegalArgumentException("File descriptors passed in options");
6860             }
6861         }
6862
6863         synchronized(this) {
6864             int callingUid = Binder.getCallingUid();
6865             int origUserId = userId;
6866             userId = mUserController.handleIncomingUser(Binder.getCallingPid(), callingUid, userId,
6867                     type == ActivityManager.INTENT_SENDER_BROADCAST,
6868                     ALLOW_NON_FULL, "getIntentSender", null);
6869             if (origUserId == UserHandle.USER_CURRENT) {
6870                 // We don't want to evaluate this until the pending intent is
6871                 // actually executed.  However, we do want to always do the
6872                 // security checking for it above.
6873                 userId = UserHandle.USER_CURRENT;
6874             }
6875             try {
6876                 if (callingUid != 0 && callingUid != Process.SYSTEM_UID) {
6877                     final int uid = AppGlobals.getPackageManager().getPackageUid(packageName,
6878                             MATCH_DEBUG_TRIAGED_MISSING, UserHandle.getUserId(callingUid));
6879                     if (!UserHandle.isSameApp(callingUid, uid)) {
6880                         String msg = "Permission Denial: getIntentSender() from pid="
6881                             + Binder.getCallingPid()
6882                             + ", uid=" + Binder.getCallingUid()
6883                             + ", (need uid=" + uid + ")"
6884                             + " is not allowed to send as package " + packageName;
6885                         Slog.w(TAG, msg);
6886                         throw new SecurityException(msg);
6887                     }
6888                 }
6889
6890                 return getIntentSenderLocked(type, packageName, callingUid, userId,
6891                         token, resultWho, requestCode, intents, resolvedTypes, flags, bOptions);
6892
6893             } catch (RemoteException e) {
6894                 throw new SecurityException(e);
6895             }
6896         }
6897     }
6898
6899     IIntentSender getIntentSenderLocked(int type, String packageName,
6900             int callingUid, int userId, IBinder token, String resultWho,
6901             int requestCode, Intent[] intents, String[] resolvedTypes, int flags,
6902             Bundle bOptions) {
6903         if (DEBUG_MU) Slog.v(TAG_MU, "getIntentSenderLocked(): uid=" + callingUid);
6904         ActivityRecord activity = null;
6905         if (type == ActivityManager.INTENT_SENDER_ACTIVITY_RESULT) {
6906             activity = ActivityRecord.isInStackLocked(token);
6907             if (activity == null) {
6908                 Slog.w(TAG, "Failed createPendingResult: activity " + token + " not in any stack");
6909                 return null;
6910             }
6911             if (activity.finishing) {
6912                 Slog.w(TAG, "Failed createPendingResult: activity " + activity + " is finishing");
6913                 return null;
6914             }
6915         }
6916
6917         // We're going to be splicing together extras before sending, so we're
6918         // okay poking into any contained extras.
6919         if (intents != null) {
6920             for (int i = 0; i < intents.length; i++) {
6921                 intents[i].setDefusable(true);
6922             }
6923         }
6924
6925         final boolean noCreate = (flags&PendingIntent.FLAG_NO_CREATE) != 0;
6926         final boolean cancelCurrent = (flags&PendingIntent.FLAG_CANCEL_CURRENT) != 0;
6927         final boolean updateCurrent = (flags&PendingIntent.FLAG_UPDATE_CURRENT) != 0;
6928         flags &= ~(PendingIntent.FLAG_NO_CREATE|PendingIntent.FLAG_CANCEL_CURRENT
6929                 |PendingIntent.FLAG_UPDATE_CURRENT);
6930
6931         PendingIntentRecord.Key key = new PendingIntentRecord.Key(
6932                 type, packageName, activity, resultWho,
6933                 requestCode, intents, resolvedTypes, flags, bOptions, userId);
6934         WeakReference<PendingIntentRecord> ref;
6935         ref = mIntentSenderRecords.get(key);
6936         PendingIntentRecord rec = ref != null ? ref.get() : null;
6937         if (rec != null) {
6938             if (!cancelCurrent) {
6939                 if (updateCurrent) {
6940                     if (rec.key.requestIntent != null) {
6941                         rec.key.requestIntent.replaceExtras(intents != null ?
6942                                 intents[intents.length - 1] : null);
6943                     }
6944                     if (intents != null) {
6945                         intents[intents.length-1] = rec.key.requestIntent;
6946                         rec.key.allIntents = intents;
6947                         rec.key.allResolvedTypes = resolvedTypes;
6948                     } else {
6949                         rec.key.allIntents = null;
6950                         rec.key.allResolvedTypes = null;
6951                     }
6952                 }
6953                 return rec;
6954             }
6955             rec.canceled = true;
6956             mIntentSenderRecords.remove(key);
6957         }
6958         if (noCreate) {
6959             return rec;
6960         }
6961         rec = new PendingIntentRecord(this, key, callingUid);
6962         mIntentSenderRecords.put(key, rec.ref);
6963         if (type == ActivityManager.INTENT_SENDER_ACTIVITY_RESULT) {
6964             if (activity.pendingResults == null) {
6965                 activity.pendingResults
6966                         = new HashSet<WeakReference<PendingIntentRecord>>();
6967             }
6968             activity.pendingResults.add(rec.ref);
6969         }
6970         return rec;
6971     }
6972
6973     @Override
6974     public void cancelIntentSender(IIntentSender sender) {
6975         if (!(sender instanceof PendingIntentRecord)) {
6976             return;
6977         }
6978         synchronized(this) {
6979             PendingIntentRecord rec = (PendingIntentRecord)sender;
6980             try {
6981                 final int uid = AppGlobals.getPackageManager().getPackageUid(rec.key.packageName,
6982                         MATCH_DEBUG_TRIAGED_MISSING, UserHandle.getCallingUserId());
6983                 if (!UserHandle.isSameApp(uid, Binder.getCallingUid())) {
6984                     String msg = "Permission Denial: cancelIntentSender() from pid="
6985                         + Binder.getCallingPid()
6986                         + ", uid=" + Binder.getCallingUid()
6987                         + " is not allowed to cancel packges "
6988                         + rec.key.packageName;
6989                     Slog.w(TAG, msg);
6990                     throw new SecurityException(msg);
6991                 }
6992             } catch (RemoteException e) {
6993                 throw new SecurityException(e);
6994             }
6995             cancelIntentSenderLocked(rec, true);
6996         }
6997     }
6998
6999     void cancelIntentSenderLocked(PendingIntentRecord rec, boolean cleanActivity) {
7000         rec.canceled = true;
7001         mIntentSenderRecords.remove(rec.key);
7002         if (cleanActivity && rec.key.activity != null) {
7003             rec.key.activity.pendingResults.remove(rec.ref);
7004         }
7005     }
7006
7007     @Override
7008     public String getPackageForIntentSender(IIntentSender pendingResult) {
7009         if (!(pendingResult instanceof PendingIntentRecord)) {
7010             return null;
7011         }
7012         try {
7013             PendingIntentRecord res = (PendingIntentRecord)pendingResult;
7014             return res.key.packageName;
7015         } catch (ClassCastException e) {
7016         }
7017         return null;
7018     }
7019
7020     @Override
7021     public int getUidForIntentSender(IIntentSender sender) {
7022         if (sender instanceof PendingIntentRecord) {
7023             try {
7024                 PendingIntentRecord res = (PendingIntentRecord)sender;
7025                 return res.uid;
7026             } catch (ClassCastException e) {
7027             }
7028         }
7029         return -1;
7030     }
7031
7032     @Override
7033     public boolean isIntentSenderTargetedToPackage(IIntentSender pendingResult) {
7034         if (!(pendingResult instanceof PendingIntentRecord)) {
7035             return false;
7036         }
7037         try {
7038             PendingIntentRecord res = (PendingIntentRecord)pendingResult;
7039             if (res.key.allIntents == null) {
7040                 return false;
7041             }
7042             for (int i=0; i<res.key.allIntents.length; i++) {
7043                 Intent intent = res.key.allIntents[i];
7044                 if (intent.getPackage() != null && intent.getComponent() != null) {
7045                     return false;
7046                 }
7047             }
7048             return true;
7049         } catch (ClassCastException e) {
7050         }
7051         return false;
7052     }
7053
7054     @Override
7055     public boolean isIntentSenderAnActivity(IIntentSender pendingResult) {
7056         if (!(pendingResult instanceof PendingIntentRecord)) {
7057             return false;
7058         }
7059         try {
7060             PendingIntentRecord res = (PendingIntentRecord)pendingResult;
7061             if (res.key.type == ActivityManager.INTENT_SENDER_ACTIVITY) {
7062                 return true;
7063             }
7064             return false;
7065         } catch (ClassCastException e) {
7066         }
7067         return false;
7068     }
7069
7070     @Override
7071     public Intent getIntentForIntentSender(IIntentSender pendingResult) {
7072         enforceCallingPermission(Manifest.permission.GET_INTENT_SENDER_INTENT,
7073                 "getIntentForIntentSender()");
7074         if (!(pendingResult instanceof PendingIntentRecord)) {
7075             return null;
7076         }
7077         try {
7078             PendingIntentRecord res = (PendingIntentRecord)pendingResult;
7079             return res.key.requestIntent != null ? new Intent(res.key.requestIntent) : null;
7080         } catch (ClassCastException e) {
7081         }
7082         return null;
7083     }
7084
7085     @Override
7086     public String getTagForIntentSender(IIntentSender pendingResult, String prefix) {
7087         if (!(pendingResult instanceof PendingIntentRecord)) {
7088             return null;
7089         }
7090         try {
7091             PendingIntentRecord res = (PendingIntentRecord)pendingResult;
7092             synchronized (this) {
7093                 return getTagForIntentSenderLocked(res, prefix);
7094             }
7095         } catch (ClassCastException e) {
7096         }
7097         return null;
7098     }
7099
7100     String getTagForIntentSenderLocked(PendingIntentRecord res, String prefix) {
7101         final Intent intent = res.key.requestIntent;
7102         if (intent != null) {
7103             if (res.lastTag != null && res.lastTagPrefix == prefix && (res.lastTagPrefix == null
7104                     || res.lastTagPrefix.equals(prefix))) {
7105                 return res.lastTag;
7106             }
7107             res.lastTagPrefix = prefix;
7108             final StringBuilder sb = new StringBuilder(128);
7109             if (prefix != null) {
7110                 sb.append(prefix);
7111             }
7112             if (intent.getAction() != null) {
7113                 sb.append(intent.getAction());
7114             } else if (intent.getComponent() != null) {
7115                 intent.getComponent().appendShortString(sb);
7116             } else {
7117                 sb.append("?");
7118             }
7119             return res.lastTag = sb.toString();
7120         }
7121         return null;
7122     }
7123
7124     @Override
7125     public void setProcessLimit(int max) {
7126         enforceCallingPermission(android.Manifest.permission.SET_PROCESS_LIMIT,
7127                 "setProcessLimit()");
7128         synchronized (this) {
7129             mProcessLimit = max < 0 ? ProcessList.MAX_CACHED_APPS : max;
7130             mProcessLimitOverride = max;
7131         }
7132         trimApplications();
7133     }
7134
7135     @Override
7136     public int getProcessLimit() {
7137         synchronized (this) {
7138             return mProcessLimitOverride;
7139         }
7140     }
7141
7142     void foregroundTokenDied(ForegroundToken token) {
7143         synchronized (ActivityManagerService.this) {
7144             synchronized (mPidsSelfLocked) {
7145                 ForegroundToken cur
7146                     = mForegroundProcesses.get(token.pid);
7147                 if (cur != token) {
7148                     return;
7149                 }
7150                 mForegroundProcesses.remove(token.pid);
7151                 ProcessRecord pr = mPidsSelfLocked.get(token.pid);
7152                 if (pr == null) {
7153                     return;
7154                 }
7155                 pr.forcingToForeground = null;
7156                 updateProcessForegroundLocked(pr, false, false);
7157             }
7158             updateOomAdjLocked();
7159         }
7160     }
7161
7162     @Override
7163     public void setProcessForeground(IBinder token, int pid, boolean isForeground) {
7164         enforceCallingPermission(android.Manifest.permission.SET_PROCESS_LIMIT,
7165                 "setProcessForeground()");
7166         synchronized(this) {
7167             boolean changed = false;
7168
7169             synchronized (mPidsSelfLocked) {
7170                 ProcessRecord pr = mPidsSelfLocked.get(pid);
7171                 if (pr == null && isForeground) {
7172                     Slog.w(TAG, "setProcessForeground called on unknown pid: " + pid);
7173                     return;
7174                 }
7175                 ForegroundToken oldToken = mForegroundProcesses.get(pid);
7176                 if (oldToken != null) {
7177                     oldToken.token.unlinkToDeath(oldToken, 0);
7178                     mForegroundProcesses.remove(pid);
7179                     if (pr != null) {
7180                         pr.forcingToForeground = null;
7181                     }
7182                     changed = true;
7183                 }
7184                 if (isForeground && token != null) {
7185                     ForegroundToken newToken = new ForegroundToken() {
7186                         @Override
7187                         public void binderDied() {
7188                             foregroundTokenDied(this);
7189                         }
7190                     };
7191                     newToken.pid = pid;
7192                     newToken.token = token;
7193                     try {
7194                         token.linkToDeath(newToken, 0);
7195                         mForegroundProcesses.put(pid, newToken);
7196                         pr.forcingToForeground = token;
7197                         changed = true;
7198                     } catch (RemoteException e) {
7199                         // If the process died while doing this, we will later
7200                         // do the cleanup with the process death link.
7201                     }
7202                 }
7203             }
7204
7205             if (changed) {
7206                 updateOomAdjLocked();
7207             }
7208         }
7209     }
7210
7211     @Override
7212     public boolean isAppForeground(int uid) throws RemoteException {
7213         synchronized (this) {
7214             UidRecord uidRec = mActiveUids.get(uid);
7215             if (uidRec == null || uidRec.idle) {
7216                 return false;
7217             }
7218             return uidRec.curProcState <= ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND;
7219         }
7220     }
7221
7222     @Override
7223     public boolean inMultiWindow(IBinder token) {
7224         final long origId = Binder.clearCallingIdentity();
7225         try {
7226             synchronized(this) {
7227                 final ActivityRecord r = ActivityRecord.isInStackLocked(token);
7228                 if (r == null) {
7229                     return false;
7230                 }
7231                 // An activity is consider to be in multi-window mode if its task isn't fullscreen.
7232                 return !r.task.mFullscreen;
7233             }
7234         } finally {
7235             Binder.restoreCallingIdentity(origId);
7236         }
7237     }
7238
7239     @Override
7240     public boolean inPictureInPicture(IBinder token) {
7241         final long origId = Binder.clearCallingIdentity();
7242         try {
7243             synchronized(this) {
7244                 final ActivityStack stack = ActivityRecord.getStackLocked(token);
7245                 if (stack == null) {
7246                     return false;
7247                 }
7248                 return stack.mStackId == PINNED_STACK_ID;
7249             }
7250         } finally {
7251             Binder.restoreCallingIdentity(origId);
7252         }
7253     }
7254
7255     @Override
7256     public void enterPictureInPicture(IBinder token) {
7257         final long origId = Binder.clearCallingIdentity();
7258         try {
7259             synchronized(this) {
7260                 if (!mSupportsPictureInPicture) {
7261                     throw new IllegalStateException("enterPictureInPicture: "
7262                             + "Device doesn't support picture-in-picture mode.");
7263                 }
7264
7265                 final ActivityRecord r = ActivityRecord.forTokenLocked(token);
7266
7267                 if (r == null) {
7268                     throw new IllegalStateException("enterPictureInPicture: "
7269                             + "Can't find activity for token=" + token);
7270                 }
7271
7272                 if (!r.supportsPictureInPicture()) {
7273                     throw new IllegalArgumentException("enterPictureInPicture: "
7274                             + "Picture-In-Picture not supported for r=" + r);
7275                 }
7276
7277                 // Use the default launch bounds for pinned stack if it doesn't exist yet.
7278                 final Rect bounds = (mStackSupervisor.getStack(PINNED_STACK_ID) == null)
7279                         ? mDefaultPinnedStackBounds : null;
7280
7281                 mStackSupervisor.moveActivityToPinnedStackLocked(
7282                         r, "enterPictureInPicture", bounds);
7283             }
7284         } finally {
7285             Binder.restoreCallingIdentity(origId);
7286         }
7287     }
7288
7289     // =========================================================
7290     // PROCESS INFO
7291     // =========================================================
7292
7293     static class ProcessInfoService extends IProcessInfoService.Stub {
7294         final ActivityManagerService mActivityManagerService;
7295         ProcessInfoService(ActivityManagerService activityManagerService) {
7296             mActivityManagerService = activityManagerService;
7297         }
7298
7299         @Override
7300         public void getProcessStatesFromPids(/*in*/ int[] pids, /*out*/ int[] states) {
7301             mActivityManagerService.getProcessStatesAndOomScoresForPIDs(
7302                     /*in*/ pids, /*out*/ states, null);
7303         }
7304
7305         @Override
7306         public void getProcessStatesAndOomScoresFromPids(
7307                 /*in*/ int[] pids, /*out*/ int[] states, /*out*/ int[] scores) {
7308             mActivityManagerService.getProcessStatesAndOomScoresForPIDs(
7309                     /*in*/ pids, /*out*/ states, /*out*/ scores);
7310         }
7311     }
7312
7313     /**
7314      * For each PID in the given input array, write the current process state
7315      * for that process into the states array, or -1 to indicate that no
7316      * process with the given PID exists. If scores array is provided, write
7317      * the oom score for the process into the scores array, with INVALID_ADJ
7318      * indicating the PID doesn't exist.
7319      */
7320     public void getProcessStatesAndOomScoresForPIDs(
7321             /*in*/ int[] pids, /*out*/ int[] states, /*out*/ int[] scores) {
7322         if (scores != null) {
7323             enforceCallingPermission(android.Manifest.permission.GET_PROCESS_STATE_AND_OOM_SCORE,
7324                     "getProcessStatesAndOomScoresForPIDs()");
7325         }
7326
7327         if (pids == null) {
7328             throw new NullPointerException("pids");
7329         } else if (states == null) {
7330             throw new NullPointerException("states");
7331         } else if (pids.length != states.length) {
7332             throw new IllegalArgumentException("pids and states arrays have different lengths!");
7333         } else if (scores != null && pids.length != scores.length) {
7334             throw new IllegalArgumentException("pids and scores arrays have different lengths!");
7335         }
7336
7337         synchronized (mPidsSelfLocked) {
7338             for (int i = 0; i < pids.length; i++) {
7339                 ProcessRecord pr = mPidsSelfLocked.get(pids[i]);
7340                 states[i] = (pr == null) ? ActivityManager.PROCESS_STATE_NONEXISTENT :
7341                         pr.curProcState;
7342                 if (scores != null) {
7343                     scores[i] = (pr == null) ? ProcessList.INVALID_ADJ : pr.curAdj;
7344                 }
7345             }
7346         }
7347     }
7348
7349     // =========================================================
7350     // PERMISSIONS
7351     // =========================================================
7352
7353     static class PermissionController extends IPermissionController.Stub {
7354         ActivityManagerService mActivityManagerService;
7355         PermissionController(ActivityManagerService activityManagerService) {
7356             mActivityManagerService = activityManagerService;
7357         }
7358
7359         @Override
7360         public boolean checkPermission(String permission, int pid, int uid) {
7361             return mActivityManagerService.checkPermission(permission, pid,
7362                     uid) == PackageManager.PERMISSION_GRANTED;
7363         }
7364
7365         @Override
7366         public String[] getPackagesForUid(int uid) {
7367             return mActivityManagerService.mContext.getPackageManager()
7368                     .getPackagesForUid(uid);
7369         }
7370
7371         @Override
7372         public boolean isRuntimePermission(String permission) {
7373             try {
7374                 PermissionInfo info = mActivityManagerService.mContext.getPackageManager()
7375                         .getPermissionInfo(permission, 0);
7376                 return info.protectionLevel == PermissionInfo.PROTECTION_DANGEROUS;
7377             } catch (NameNotFoundException nnfe) {
7378                 Slog.e(TAG, "No such permission: "+ permission, nnfe);
7379             }
7380             return false;
7381         }
7382     }
7383
7384     class IntentFirewallInterface implements IntentFirewall.AMSInterface {
7385         @Override
7386         public int checkComponentPermission(String permission, int pid, int uid,
7387                 int owningUid, boolean exported) {
7388             return ActivityManagerService.this.checkComponentPermission(permission, pid, uid,
7389                     owningUid, exported);
7390         }
7391
7392         @Override
7393         public Object getAMSLock() {
7394             return ActivityManagerService.this;
7395         }
7396     }
7397
7398     /**
7399      * This can be called with or without the global lock held.
7400      */
7401     int checkComponentPermission(String permission, int pid, int uid,
7402             int owningUid, boolean exported) {
7403         if (pid == MY_PID) {
7404             return PackageManager.PERMISSION_GRANTED;
7405         }
7406         return ActivityManager.checkComponentPermission(permission, uid,
7407                 owningUid, exported);
7408     }
7409
7410     /**
7411      * As the only public entry point for permissions checking, this method
7412      * can enforce the semantic that requesting a check on a null global
7413      * permission is automatically denied.  (Internally a null permission
7414      * string is used when calling {@link #checkComponentPermission} in cases
7415      * when only uid-based security is needed.)
7416      *
7417      * This can be called with or without the global lock held.
7418      */
7419     @Override
7420     public int checkPermission(String permission, int pid, int uid) {
7421         if (permission == null) {
7422             return PackageManager.PERMISSION_DENIED;
7423         }
7424         return checkComponentPermission(permission, pid, uid, -1, true);
7425     }
7426
7427     @Override
7428     public int checkPermissionWithToken(String permission, int pid, int uid, IBinder callerToken) {
7429         if (permission == null) {
7430             return PackageManager.PERMISSION_DENIED;
7431         }
7432
7433         // We might be performing an operation on behalf of an indirect binder
7434         // invocation, e.g. via {@link #openContentUri}.  Check and adjust the
7435         // client identity accordingly before proceeding.
7436         Identity tlsIdentity = sCallerIdentity.get();
7437         if (tlsIdentity != null && tlsIdentity.token == callerToken) {
7438             Slog.d(TAG, "checkComponentPermission() adjusting {pid,uid} to {"
7439                     + tlsIdentity.pid + "," + tlsIdentity.uid + "}");
7440             uid = tlsIdentity.uid;
7441             pid = tlsIdentity.pid;
7442         }
7443
7444         return checkComponentPermission(permission, pid, uid, -1, true);
7445     }
7446
7447     /**
7448      * Binder IPC calls go through the public entry point.
7449      * This can be called with or without the global lock held.
7450      */
7451     int checkCallingPermission(String permission) {
7452         return checkPermission(permission,
7453                 Binder.getCallingPid(),
7454                 UserHandle.getAppId(Binder.getCallingUid()));
7455     }
7456
7457     /**
7458      * This can be called with or without the global lock held.
7459      */
7460     void enforceCallingPermission(String permission, String func) {
7461         if (checkCallingPermission(permission)
7462                 == PackageManager.PERMISSION_GRANTED) {
7463             return;
7464         }
7465
7466         String msg = "Permission Denial: " + func + " from pid="
7467                 + Binder.getCallingPid()
7468                 + ", uid=" + Binder.getCallingUid()
7469                 + " requires " + permission;
7470         Slog.w(TAG, msg);
7471         throw new SecurityException(msg);
7472     }
7473
7474     /**
7475      * Determine if UID is holding permissions required to access {@link Uri} in
7476      * the given {@link ProviderInfo}. Final permission checking is always done
7477      * in {@link ContentProvider}.
7478      */
7479     private final boolean checkHoldingPermissionsLocked(
7480             IPackageManager pm, ProviderInfo pi, GrantUri grantUri, int uid, final int modeFlags) {
7481         if (DEBUG_URI_PERMISSION) Slog.v(TAG_URI_PERMISSION,
7482                 "checkHoldingPermissionsLocked: uri=" + grantUri + " uid=" + uid);
7483         if (UserHandle.getUserId(uid) != grantUri.sourceUserId) {
7484             if (ActivityManager.checkComponentPermission(INTERACT_ACROSS_USERS, uid, -1, true)
7485                     != PERMISSION_GRANTED) {
7486                 return false;
7487             }
7488         }
7489         return checkHoldingPermissionsInternalLocked(pm, pi, grantUri, uid, modeFlags, true);
7490     }
7491
7492     private final boolean checkHoldingPermissionsInternalLocked(IPackageManager pm, ProviderInfo pi,
7493             GrantUri grantUri, int uid, final int modeFlags, boolean considerUidPermissions) {
7494         if (pi.applicationInfo.uid == uid) {
7495             return true;
7496         } else if (!pi.exported) {
7497             return false;
7498         }
7499
7500         boolean readMet = (modeFlags & Intent.FLAG_GRANT_READ_URI_PERMISSION) == 0;
7501         boolean writeMet = (modeFlags & Intent.FLAG_GRANT_WRITE_URI_PERMISSION) == 0;
7502         try {
7503             // check if target holds top-level <provider> permissions
7504             if (!readMet && pi.readPermission != null && considerUidPermissions
7505                     && (pm.checkUidPermission(pi.readPermission, uid) == PERMISSION_GRANTED)) {
7506                 readMet = true;
7507             }
7508             if (!writeMet && pi.writePermission != null && considerUidPermissions
7509                     && (pm.checkUidPermission(pi.writePermission, uid) == PERMISSION_GRANTED)) {
7510                 writeMet = true;
7511             }
7512
7513             // track if unprotected read/write is allowed; any denied
7514             // <path-permission> below removes this ability
7515             boolean allowDefaultRead = pi.readPermission == null;
7516             boolean allowDefaultWrite = pi.writePermission == null;
7517
7518             // check if target holds any <path-permission> that match uri
7519             final PathPermission[] pps = pi.pathPermissions;
7520             if (pps != null) {
7521                 final String path = grantUri.uri.getPath();
7522                 int i = pps.length;
7523                 while (i > 0 && (!readMet || !writeMet)) {
7524                     i--;
7525                     PathPermission pp = pps[i];
7526                     if (pp.match(path)) {
7527                         if (!readMet) {
7528                             final String pprperm = pp.getReadPermission();
7529                             if (DEBUG_URI_PERMISSION) Slog.v(TAG_URI_PERMISSION,
7530                                     "Checking read perm for " + pprperm + " for " + pp.getPath()
7531                                     + ": match=" + pp.match(path)
7532                                     + " check=" + pm.checkUidPermission(pprperm, uid));
7533                             if (pprperm != null) {
7534                                 if (considerUidPermissions && pm.checkUidPermission(pprperm, uid)
7535                                         == PERMISSION_GRANTED) {
7536                                     readMet = true;
7537                                 } else {
7538                                     allowDefaultRead = false;
7539                                 }
7540                             }
7541                         }
7542                         if (!writeMet) {
7543                             final String ppwperm = pp.getWritePermission();
7544                             if (DEBUG_URI_PERMISSION) Slog.v(TAG_URI_PERMISSION,
7545                                     "Checking write perm " + ppwperm + " for " + pp.getPath()
7546                                     + ": match=" + pp.match(path)
7547                                     + " check=" + pm.checkUidPermission(ppwperm, uid));
7548                             if (ppwperm != null) {
7549                                 if (considerUidPermissions && pm.checkUidPermission(ppwperm, uid)
7550                                         == PERMISSION_GRANTED) {
7551                                     writeMet = true;
7552                                 } else {
7553                                     allowDefaultWrite = false;
7554                                 }
7555                             }
7556                         }
7557                     }
7558                 }
7559             }
7560
7561             // grant unprotected <provider> read/write, if not blocked by
7562             // <path-permission> above
7563             if (allowDefaultRead) readMet = true;
7564             if (allowDefaultWrite) writeMet = true;
7565
7566         } catch (RemoteException e) {
7567             return false;
7568         }
7569
7570         return readMet && writeMet;
7571     }
7572
7573     public int getAppStartMode(int uid, String packageName) {
7574         synchronized (this) {
7575             return checkAllowBackgroundLocked(uid, packageName, -1);
7576         }
7577     }
7578
7579     int checkAllowBackgroundLocked(int uid, String packageName, int callingPid) {
7580         UidRecord uidRec = mActiveUids.get(uid);
7581         if (!mLenientBackgroundCheck) {
7582             if (uidRec == null
7583                     || uidRec.curProcState >= ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND) {
7584                 if (mAppOpsService.noteOperation(AppOpsManager.OP_RUN_IN_BACKGROUND, uid,
7585                         packageName) != AppOpsManager.MODE_ALLOWED) {
7586                     return ActivityManager.APP_START_MODE_DELAYED;
7587                 }
7588             }
7589
7590         } else if (uidRec == null || uidRec.idle) {
7591             if (callingPid >= 0) {
7592                 ProcessRecord proc;
7593                 synchronized (mPidsSelfLocked) {
7594                     proc = mPidsSelfLocked.get(callingPid);
7595                 }
7596                 if (proc != null && proc.curProcState < ActivityManager.PROCESS_STATE_RECEIVER) {
7597                     // Whoever is instigating this is in the foreground, so we will allow it
7598                     // to go through.
7599                     return ActivityManager.APP_START_MODE_NORMAL;
7600                 }
7601             }
7602             if (mAppOpsService.noteOperation(AppOpsManager.OP_RUN_IN_BACKGROUND, uid, packageName)
7603                     != AppOpsManager.MODE_ALLOWED) {
7604                 return ActivityManager.APP_START_MODE_DELAYED;
7605             }
7606         }
7607         return ActivityManager.APP_START_MODE_NORMAL;
7608     }
7609
7610     private ProviderInfo getProviderInfoLocked(String authority, int userHandle) {
7611         ProviderInfo pi = null;
7612         ContentProviderRecord cpr = mProviderMap.getProviderByName(authority, userHandle);
7613         if (cpr != null) {
7614             pi = cpr.info;
7615         } else {
7616             try {
7617                 pi = AppGlobals.getPackageManager().resolveContentProvider(
7618                         authority, PackageManager.GET_URI_PERMISSION_PATTERNS, userHandle);
7619             } catch (RemoteException ex) {
7620             }
7621         }
7622         return pi;
7623     }
7624
7625     private UriPermission findUriPermissionLocked(int targetUid, GrantUri grantUri) {
7626         final ArrayMap<GrantUri, UriPermission> targetUris = mGrantedUriPermissions.get(targetUid);
7627         if (targetUris != null) {
7628             return targetUris.get(grantUri);
7629         }
7630         return null;
7631     }
7632
7633     private UriPermission findOrCreateUriPermissionLocked(String sourcePkg,
7634             String targetPkg, int targetUid, GrantUri grantUri) {
7635         ArrayMap<GrantUri, UriPermission> targetUris = mGrantedUriPermissions.get(targetUid);
7636         if (targetUris == null) {
7637             targetUris = Maps.newArrayMap();
7638             mGrantedUriPermissions.put(targetUid, targetUris);
7639         }
7640
7641         UriPermission perm = targetUris.get(grantUri);
7642         if (perm == null) {
7643             perm = new UriPermission(sourcePkg, targetPkg, targetUid, grantUri);
7644             targetUris.put(grantUri, perm);
7645         }
7646
7647         return perm;
7648     }
7649
7650     private final boolean checkUriPermissionLocked(GrantUri grantUri, int uid,
7651             final int modeFlags) {
7652         final boolean persistable = (modeFlags & Intent.FLAG_GRANT_PERSISTABLE_URI_PERMISSION) != 0;
7653         final int minStrength = persistable ? UriPermission.STRENGTH_PERSISTABLE
7654                 : UriPermission.STRENGTH_OWNED;
7655
7656         // Root gets to do everything.
7657         if (uid == 0) {
7658             return true;
7659         }
7660
7661         final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.get(uid);
7662         if (perms == null) return false;
7663
7664         // First look for exact match
7665         final UriPermission exactPerm = perms.get(grantUri);
7666         if (exactPerm != null && exactPerm.getStrength(modeFlags) >= minStrength) {
7667             return true;
7668         }
7669
7670         // No exact match, look for prefixes
7671         final int N = perms.size();
7672         for (int i = 0; i < N; i++) {
7673             final UriPermission perm = perms.valueAt(i);
7674             if (perm.uri.prefix && grantUri.uri.isPathPrefixMatch(perm.uri.uri)
7675                     && perm.getStrength(modeFlags) >= minStrength) {
7676                 return true;
7677             }
7678         }
7679
7680         return false;
7681     }
7682
7683     /**
7684      * @param uri This uri must NOT contain an embedded userId.
7685      * @param userId The userId in which the uri is to be resolved.
7686      */
7687     @Override
7688     public int checkUriPermission(Uri uri, int pid, int uid,
7689             final int modeFlags, int userId, IBinder callerToken) {
7690         enforceNotIsolatedCaller("checkUriPermission");
7691
7692         // Another redirected-binder-call permissions check as in
7693         // {@link checkPermissionWithToken}.
7694         Identity tlsIdentity = sCallerIdentity.get();
7695         if (tlsIdentity != null && tlsIdentity.token == callerToken) {
7696             uid = tlsIdentity.uid;
7697             pid = tlsIdentity.pid;
7698         }
7699
7700         // Our own process gets to do everything.
7701         if (pid == MY_PID) {
7702             return PackageManager.PERMISSION_GRANTED;
7703         }
7704         synchronized (this) {
7705             return checkUriPermissionLocked(new GrantUri(userId, uri, false), uid, modeFlags)
7706                     ? PackageManager.PERMISSION_GRANTED
7707                     : PackageManager.PERMISSION_DENIED;
7708         }
7709     }
7710
7711     /**
7712      * Check if the targetPkg can be granted permission to access uri by
7713      * the callingUid using the given modeFlags.  Throws a security exception
7714      * if callingUid is not allowed to do this.  Returns the uid of the target
7715      * if the URI permission grant should be performed; returns -1 if it is not
7716      * needed (for example targetPkg already has permission to access the URI).
7717      * If you already know the uid of the target, you can supply it in
7718      * lastTargetUid else set that to -1.
7719      */
7720     int checkGrantUriPermissionLocked(int callingUid, String targetPkg, GrantUri grantUri,
7721             final int modeFlags, int lastTargetUid) {
7722         if (!Intent.isAccessUriMode(modeFlags)) {
7723             return -1;
7724         }
7725
7726         if (targetPkg != null) {
7727             if (DEBUG_URI_PERMISSION) Slog.v(TAG_URI_PERMISSION,
7728                     "Checking grant " + targetPkg + " permission to " + grantUri);
7729         }
7730
7731         final IPackageManager pm = AppGlobals.getPackageManager();
7732
7733         // If this is not a content: uri, we can't do anything with it.
7734         if (!ContentResolver.SCHEME_CONTENT.equals(grantUri.uri.getScheme())) {
7735             if (DEBUG_URI_PERMISSION) Slog.v(TAG_URI_PERMISSION,
7736                     "Can't grant URI permission for non-content URI: " + grantUri);
7737             return -1;
7738         }
7739
7740         final String authority = grantUri.uri.getAuthority();
7741         final ProviderInfo pi = getProviderInfoLocked(authority, grantUri.sourceUserId);
7742         if (pi == null) {
7743             Slog.w(TAG, "No content provider found for permission check: " +
7744                     grantUri.uri.toSafeString());
7745             return -1;
7746         }
7747
7748         int targetUid = lastTargetUid;
7749         if (targetUid < 0 && targetPkg != null) {
7750             try {
7751                 targetUid = pm.getPackageUid(targetPkg, MATCH_DEBUG_TRIAGED_MISSING,
7752                         UserHandle.getUserId(callingUid));
7753                 if (targetUid < 0) {
7754                     if (DEBUG_URI_PERMISSION) Slog.v(TAG_URI_PERMISSION,
7755                             "Can't grant URI permission no uid for: " + targetPkg);
7756                     return -1;
7757                 }
7758             } catch (RemoteException ex) {
7759                 return -1;
7760             }
7761         }
7762
7763         if (targetUid >= 0) {
7764             // First...  does the target actually need this permission?
7765             if (checkHoldingPermissionsLocked(pm, pi, grantUri, targetUid, modeFlags)) {
7766                 // No need to grant the target this permission.
7767                 if (DEBUG_URI_PERMISSION) Slog.v(TAG_URI_PERMISSION,
7768                         "Target " + targetPkg + " already has full permission to " + grantUri);
7769                 return -1;
7770             }
7771         } else {
7772             // First...  there is no target package, so can anyone access it?
7773             boolean allowed = pi.exported;
7774             if ((modeFlags&Intent.FLAG_GRANT_READ_URI_PERMISSION) != 0) {
7775                 if (pi.readPermission != null) {
7776                     allowed = false;
7777                 }
7778             }
7779             if ((modeFlags&Intent.FLAG_GRANT_WRITE_URI_PERMISSION) != 0) {
7780                 if (pi.writePermission != null) {
7781                     allowed = false;
7782                 }
7783             }
7784             if (allowed) {
7785                 return -1;
7786             }
7787         }
7788
7789         /* There is a special cross user grant if:
7790          * - The target is on another user.
7791          * - Apps on the current user can access the uri without any uid permissions.
7792          * In this case, we grant a uri permission, even if the ContentProvider does not normally
7793          * grant uri permissions.
7794          */
7795         boolean specialCrossUserGrant = UserHandle.getUserId(targetUid) != grantUri.sourceUserId
7796                 && checkHoldingPermissionsInternalLocked(pm, pi, grantUri, callingUid,
7797                 modeFlags, false /*without considering the uid permissions*/);
7798
7799         // Second...  is the provider allowing granting of URI permissions?
7800         if (!specialCrossUserGrant) {
7801             if (!pi.grantUriPermissions) {
7802                 throw new SecurityException("Provider " + pi.packageName
7803                         + "/" + pi.name
7804                         + " does not allow granting of Uri permissions (uri "
7805                         + grantUri + ")");
7806             }
7807             if (pi.uriPermissionPatterns != null) {
7808                 final int N = pi.uriPermissionPatterns.length;
7809                 boolean allowed = false;
7810                 for (int i=0; i<N; i++) {
7811                     if (pi.uriPermissionPatterns[i] != null
7812                             && pi.uriPermissionPatterns[i].match(grantUri.uri.getPath())) {
7813                         allowed = true;
7814                         break;
7815                     }
7816                 }
7817                 if (!allowed) {
7818                     throw new SecurityException("Provider " + pi.packageName
7819                             + "/" + pi.name
7820                             + " does not allow granting of permission to path of Uri "
7821                             + grantUri);
7822                 }
7823             }
7824         }
7825
7826         // Third...  does the caller itself have permission to access
7827         // this uri?
7828         if (UserHandle.getAppId(callingUid) != Process.SYSTEM_UID) {
7829             if (!checkHoldingPermissionsLocked(pm, pi, grantUri, callingUid, modeFlags)) {
7830                 // Require they hold a strong enough Uri permission
7831                 if (!checkUriPermissionLocked(grantUri, callingUid, modeFlags)) {
7832                     throw new SecurityException("Uid " + callingUid
7833                             + " does not have permission to uri " + grantUri);
7834                 }
7835             }
7836         }
7837         return targetUid;
7838     }
7839
7840     /**
7841      * @param uri This uri must NOT contain an embedded userId.
7842      * @param userId The userId in which the uri is to be resolved.
7843      */
7844     @Override
7845     public int checkGrantUriPermission(int callingUid, String targetPkg, Uri uri,
7846             final int modeFlags, int userId) {
7847         enforceNotIsolatedCaller("checkGrantUriPermission");
7848         synchronized(this) {
7849             return checkGrantUriPermissionLocked(callingUid, targetPkg,
7850                     new GrantUri(userId, uri, false), modeFlags, -1);
7851         }
7852     }
7853
7854     void grantUriPermissionUncheckedLocked(int targetUid, String targetPkg, GrantUri grantUri,
7855             final int modeFlags, UriPermissionOwner owner) {
7856         if (!Intent.isAccessUriMode(modeFlags)) {
7857             return;
7858         }
7859
7860         // So here we are: the caller has the assumed permission
7861         // to the uri, and the target doesn't.  Let's now give this to
7862         // the target.
7863
7864         if (DEBUG_URI_PERMISSION) Slog.v(TAG_URI_PERMISSION,
7865                 "Granting " + targetPkg + "/" + targetUid + " permission to " + grantUri);
7866
7867         final String authority = grantUri.uri.getAuthority();
7868         final ProviderInfo pi = getProviderInfoLocked(authority, grantUri.sourceUserId);
7869         if (pi == null) {
7870             Slog.w(TAG, "No content provider found for grant: " + grantUri.toSafeString());
7871             return;
7872         }
7873
7874         if ((modeFlags & Intent.FLAG_GRANT_PREFIX_URI_PERMISSION) != 0) {
7875             grantUri.prefix = true;
7876         }
7877         final UriPermission perm = findOrCreateUriPermissionLocked(
7878                 pi.packageName, targetPkg, targetUid, grantUri);
7879         perm.grantModes(modeFlags, owner);
7880     }
7881
7882     void grantUriPermissionLocked(int callingUid, String targetPkg, GrantUri grantUri,
7883             final int modeFlags, UriPermissionOwner owner, int targetUserId) {
7884         if (targetPkg == null) {
7885             throw new NullPointerException("targetPkg");
7886         }
7887         int targetUid;
7888         final IPackageManager pm = AppGlobals.getPackageManager();
7889         try {
7890             targetUid = pm.getPackageUid(targetPkg, MATCH_DEBUG_TRIAGED_MISSING, targetUserId);
7891         } catch (RemoteException ex) {
7892             return;
7893         }
7894
7895         targetUid = checkGrantUriPermissionLocked(callingUid, targetPkg, grantUri, modeFlags,
7896                 targetUid);
7897         if (targetUid < 0) {
7898             return;
7899         }
7900
7901         grantUriPermissionUncheckedLocked(targetUid, targetPkg, grantUri, modeFlags,
7902                 owner);
7903     }
7904
7905     static class NeededUriGrants extends ArrayList<GrantUri> {
7906         final String targetPkg;
7907         final int targetUid;
7908         final int flags;
7909
7910         NeededUriGrants(String targetPkg, int targetUid, int flags) {
7911             this.targetPkg = targetPkg;
7912             this.targetUid = targetUid;
7913             this.flags = flags;
7914         }
7915     }
7916
7917     /**
7918      * Like checkGrantUriPermissionLocked, but takes an Intent.
7919      */
7920     NeededUriGrants checkGrantUriPermissionFromIntentLocked(int callingUid,
7921             String targetPkg, Intent intent, int mode, NeededUriGrants needed, int targetUserId) {
7922         if (DEBUG_URI_PERMISSION) Slog.v(TAG_URI_PERMISSION,
7923                 "Checking URI perm to data=" + (intent != null ? intent.getData() : null)
7924                 + " clip=" + (intent != null ? intent.getClipData() : null)
7925                 + " from " + intent + "; flags=0x"
7926                 + Integer.toHexString(intent != null ? intent.getFlags() : 0));
7927
7928         if (targetPkg == null) {
7929             throw new NullPointerException("targetPkg");
7930         }
7931
7932         if (intent == null) {
7933             return null;
7934         }
7935         Uri data = intent.getData();
7936         ClipData clip = intent.getClipData();
7937         if (data == null && clip == null) {
7938             return null;
7939         }
7940         // Default userId for uris in the intent (if they don't specify it themselves)
7941         int contentUserHint = intent.getContentUserHint();
7942         if (contentUserHint == UserHandle.USER_CURRENT) {
7943             contentUserHint = UserHandle.getUserId(callingUid);
7944         }
7945         final IPackageManager pm = AppGlobals.getPackageManager();
7946         int targetUid;
7947         if (needed != null) {
7948             targetUid = needed.targetUid;
7949         } else {
7950             try {
7951                 targetUid = pm.getPackageUid(targetPkg, MATCH_DEBUG_TRIAGED_MISSING,
7952                         targetUserId);
7953             } catch (RemoteException ex) {
7954                 return null;
7955             }
7956             if (targetUid < 0) {
7957                 if (DEBUG_URI_PERMISSION) Slog.v(TAG_URI_PERMISSION,
7958                         "Can't grant URI permission no uid for: " + targetPkg
7959                         + " on user " + targetUserId);
7960                 return null;
7961             }
7962         }
7963         if (data != null) {
7964             GrantUri grantUri = GrantUri.resolve(contentUserHint, data);
7965             targetUid = checkGrantUriPermissionLocked(callingUid, targetPkg, grantUri, mode,
7966                     targetUid);
7967             if (targetUid > 0) {
7968                 if (needed == null) {
7969                     needed = new NeededUriGrants(targetPkg, targetUid, mode);
7970                 }
7971                 needed.add(grantUri);
7972             }
7973         }
7974         if (clip != null) {
7975             for (int i=0; i<clip.getItemCount(); i++) {
7976                 Uri uri = clip.getItemAt(i).getUri();
7977                 if (uri != null) {
7978                     GrantUri grantUri = GrantUri.resolve(contentUserHint, uri);
7979                     targetUid = checkGrantUriPermissionLocked(callingUid, targetPkg, grantUri, mode,
7980                             targetUid);
7981                     if (targetUid > 0) {
7982                         if (needed == null) {
7983                             needed = new NeededUriGrants(targetPkg, targetUid, mode);
7984                         }
7985                         needed.add(grantUri);
7986                     }
7987                 } else {
7988                     Intent clipIntent = clip.getItemAt(i).getIntent();
7989                     if (clipIntent != null) {
7990                         NeededUriGrants newNeeded = checkGrantUriPermissionFromIntentLocked(
7991                                 callingUid, targetPkg, clipIntent, mode, needed, targetUserId);
7992                         if (newNeeded != null) {
7993                             needed = newNeeded;
7994                         }
7995                     }
7996                 }
7997             }
7998         }
7999
8000         return needed;
8001     }
8002
8003     /**
8004      * Like grantUriPermissionUncheckedLocked, but takes an Intent.
8005      */
8006     void grantUriPermissionUncheckedFromIntentLocked(NeededUriGrants needed,
8007             UriPermissionOwner owner) {
8008         if (needed != null) {
8009             for (int i=0; i<needed.size(); i++) {
8010                 GrantUri grantUri = needed.get(i);
8011                 grantUriPermissionUncheckedLocked(needed.targetUid, needed.targetPkg,
8012                         grantUri, needed.flags, owner);
8013             }
8014         }
8015     }
8016
8017     void grantUriPermissionFromIntentLocked(int callingUid,
8018             String targetPkg, Intent intent, UriPermissionOwner owner, int targetUserId) {
8019         NeededUriGrants needed = checkGrantUriPermissionFromIntentLocked(callingUid, targetPkg,
8020                 intent, intent != null ? intent.getFlags() : 0, null, targetUserId);
8021         if (needed == null) {
8022             return;
8023         }
8024
8025         grantUriPermissionUncheckedFromIntentLocked(needed, owner);
8026     }
8027
8028     /**
8029      * @param uri This uri must NOT contain an embedded userId.
8030      * @param userId The userId in which the uri is to be resolved.
8031      */
8032     @Override
8033     public void grantUriPermission(IApplicationThread caller, String targetPkg, Uri uri,
8034             final int modeFlags, int userId) {
8035         enforceNotIsolatedCaller("grantUriPermission");
8036         GrantUri grantUri = new GrantUri(userId, uri, false);
8037         synchronized(this) {
8038             final ProcessRecord r = getRecordForAppLocked(caller);
8039             if (r == null) {
8040                 throw new SecurityException("Unable to find app for caller "
8041                         + caller
8042                         + " when granting permission to uri " + grantUri);
8043             }
8044             if (targetPkg == null) {
8045                 throw new IllegalArgumentException("null target");
8046             }
8047             if (grantUri == null) {
8048                 throw new IllegalArgumentException("null uri");
8049             }
8050
8051             Preconditions.checkFlagsArgument(modeFlags, Intent.FLAG_GRANT_READ_URI_PERMISSION
8052                     | Intent.FLAG_GRANT_WRITE_URI_PERMISSION
8053                     | Intent.FLAG_GRANT_PERSISTABLE_URI_PERMISSION
8054                     | Intent.FLAG_GRANT_PREFIX_URI_PERMISSION);
8055
8056             grantUriPermissionLocked(r.uid, targetPkg, grantUri, modeFlags, null,
8057                     UserHandle.getUserId(r.uid));
8058         }
8059     }
8060
8061     void removeUriPermissionIfNeededLocked(UriPermission perm) {
8062         if (perm.modeFlags == 0) {
8063             final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.get(
8064                     perm.targetUid);
8065             if (perms != null) {
8066                 if (DEBUG_URI_PERMISSION) Slog.v(TAG_URI_PERMISSION,
8067                         "Removing " + perm.targetUid + " permission to " + perm.uri);
8068
8069                 perms.remove(perm.uri);
8070                 if (perms.isEmpty()) {
8071                     mGrantedUriPermissions.remove(perm.targetUid);
8072                 }
8073             }
8074         }
8075     }
8076
8077     private void revokeUriPermissionLocked(int callingUid, GrantUri grantUri, final int modeFlags) {
8078         if (DEBUG_URI_PERMISSION) Slog.v(TAG_URI_PERMISSION,
8079                 "Revoking all granted permissions to " + grantUri);
8080
8081         final IPackageManager pm = AppGlobals.getPackageManager();
8082         final String authority = grantUri.uri.getAuthority();
8083         final ProviderInfo pi = getProviderInfoLocked(authority, grantUri.sourceUserId);
8084         if (pi == null) {
8085             Slog.w(TAG, "No content provider found for permission revoke: "
8086                     + grantUri.toSafeString());
8087             return;
8088         }
8089
8090         // Does the caller have this permission on the URI?
8091         if (!checkHoldingPermissionsLocked(pm, pi, grantUri, callingUid, modeFlags)) {
8092             // If they don't have direct access to the URI, then revoke any
8093             // ownerless URI permissions that have been granted to them.
8094             final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.get(callingUid);
8095             if (perms != null) {
8096                 boolean persistChanged = false;
8097                 for (Iterator<UriPermission> it = perms.values().iterator(); it.hasNext();) {
8098                     final UriPermission perm = it.next();
8099                     if (perm.uri.sourceUserId == grantUri.sourceUserId
8100                             && perm.uri.uri.isPathPrefixMatch(grantUri.uri)) {
8101                         if (DEBUG_URI_PERMISSION) Slog.v(TAG_URI_PERMISSION,
8102                                 "Revoking non-owned " + perm.targetUid
8103                                 + " permission to " + perm.uri);
8104                         persistChanged |= perm.revokeModes(
8105                                 modeFlags | Intent.FLAG_GRANT_PERSISTABLE_URI_PERMISSION, false);
8106                         if (perm.modeFlags == 0) {
8107                             it.remove();
8108                         }
8109                     }
8110                 }
8111                 if (perms.isEmpty()) {
8112                     mGrantedUriPermissions.remove(callingUid);
8113                 }
8114                 if (persistChanged) {
8115                     schedulePersistUriGrants();
8116                 }
8117             }
8118             return;
8119         }
8120
8121         boolean persistChanged = false;
8122
8123         // Go through all of the permissions and remove any that match.
8124         int N = mGrantedUriPermissions.size();
8125         for (int i = 0; i < N; i++) {
8126             final int targetUid = mGrantedUriPermissions.keyAt(i);
8127             final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.valueAt(i);
8128
8129             for (Iterator<UriPermission> it = perms.values().iterator(); it.hasNext();) {
8130                 final UriPermission perm = it.next();
8131                 if (perm.uri.sourceUserId == grantUri.sourceUserId
8132                         && perm.uri.uri.isPathPrefixMatch(grantUri.uri)) {
8133                     if (DEBUG_URI_PERMISSION) Slog.v(TAG_URI_PERMISSION,
8134                                 "Revoking " + perm.targetUid + " permission to " + perm.uri);
8135                     persistChanged |= perm.revokeModes(
8136                             modeFlags | Intent.FLAG_GRANT_PERSISTABLE_URI_PERMISSION, true);
8137                     if (perm.modeFlags == 0) {
8138                         it.remove();
8139                     }
8140                 }
8141             }
8142
8143             if (perms.isEmpty()) {
8144                 mGrantedUriPermissions.remove(targetUid);
8145                 N--;
8146                 i--;
8147             }
8148         }
8149
8150         if (persistChanged) {
8151             schedulePersistUriGrants();
8152         }
8153     }
8154
8155     /**
8156      * @param uri This uri must NOT contain an embedded userId.
8157      * @param userId The userId in which the uri is to be resolved.
8158      */
8159     @Override
8160     public void revokeUriPermission(IApplicationThread caller, Uri uri, final int modeFlags,
8161             int userId) {
8162         enforceNotIsolatedCaller("revokeUriPermission");
8163         synchronized(this) {
8164             final ProcessRecord r = getRecordForAppLocked(caller);
8165             if (r == null) {
8166                 throw new SecurityException("Unable to find app for caller "
8167                         + caller
8168                         + " when revoking permission to uri " + uri);
8169             }
8170             if (uri == null) {
8171                 Slog.w(TAG, "revokeUriPermission: null uri");
8172                 return;
8173             }
8174
8175             if (!Intent.isAccessUriMode(modeFlags)) {
8176                 return;
8177             }
8178
8179             final String authority = uri.getAuthority();
8180             final ProviderInfo pi = getProviderInfoLocked(authority, userId);
8181             if (pi == null) {
8182                 Slog.w(TAG, "No content provider found for permission revoke: "
8183                         + uri.toSafeString());
8184                 return;
8185             }
8186
8187             revokeUriPermissionLocked(r.uid, new GrantUri(userId, uri, false), modeFlags);
8188         }
8189     }
8190
8191     /**
8192      * Remove any {@link UriPermission} granted <em>from</em> or <em>to</em> the
8193      * given package.
8194      *
8195      * @param packageName Package name to match, or {@code null} to apply to all
8196      *            packages.
8197      * @param userHandle User to match, or {@link UserHandle#USER_ALL} to apply
8198      *            to all users.
8199      * @param persistable If persistable grants should be removed.
8200      */
8201     private void removeUriPermissionsForPackageLocked(
8202             String packageName, int userHandle, boolean persistable) {
8203         if (userHandle == UserHandle.USER_ALL && packageName == null) {
8204             throw new IllegalArgumentException("Must narrow by either package or user");
8205         }
8206
8207         boolean persistChanged = false;
8208
8209         int N = mGrantedUriPermissions.size();
8210         for (int i = 0; i < N; i++) {
8211             final int targetUid = mGrantedUriPermissions.keyAt(i);
8212             final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.valueAt(i);
8213
8214             // Only inspect grants matching user
8215             if (userHandle == UserHandle.USER_ALL
8216                     || userHandle == UserHandle.getUserId(targetUid)) {
8217                 for (Iterator<UriPermission> it = perms.values().iterator(); it.hasNext();) {
8218                     final UriPermission perm = it.next();
8219
8220                     // Only inspect grants matching package
8221                     if (packageName == null || perm.sourcePkg.equals(packageName)
8222                             || perm.targetPkg.equals(packageName)) {
8223                         persistChanged |= perm.revokeModes(persistable
8224                                 ? ~0 : ~Intent.FLAG_GRANT_PERSISTABLE_URI_PERMISSION, true);
8225
8226                         // Only remove when no modes remain; any persisted grants
8227                         // will keep this alive.
8228                         if (perm.modeFlags == 0) {
8229                             it.remove();
8230                         }
8231                     }
8232                 }
8233
8234                 if (perms.isEmpty()) {
8235                     mGrantedUriPermissions.remove(targetUid);
8236                     N--;
8237                     i--;
8238                 }
8239             }
8240         }
8241
8242         if (persistChanged) {
8243             schedulePersistUriGrants();
8244         }
8245     }
8246
8247     @Override
8248     public IBinder newUriPermissionOwner(String name) {
8249         enforceNotIsolatedCaller("newUriPermissionOwner");
8250         synchronized(this) {
8251             UriPermissionOwner owner = new UriPermissionOwner(this, name);
8252             return owner.getExternalTokenLocked();
8253         }
8254     }
8255
8256     @Override
8257     public IBinder getUriPermissionOwnerForActivity(IBinder activityToken) {
8258         enforceNotIsolatedCaller("getUriPermissionOwnerForActivity");
8259         synchronized(this) {
8260             ActivityRecord r = ActivityRecord.isInStackLocked(activityToken);
8261             if (r == null) {
8262                 throw new IllegalArgumentException("Activity does not exist; token="
8263                         + activityToken);
8264             }
8265             return r.getUriPermissionsLocked().getExternalTokenLocked();
8266         }
8267     }
8268     /**
8269      * @param uri This uri must NOT contain an embedded userId.
8270      * @param sourceUserId The userId in which the uri is to be resolved.
8271      * @param targetUserId The userId of the app that receives the grant.
8272      */
8273     @Override
8274     public void grantUriPermissionFromOwner(IBinder token, int fromUid, String targetPkg, Uri uri,
8275             final int modeFlags, int sourceUserId, int targetUserId) {
8276         targetUserId = mUserController.handleIncomingUser(Binder.getCallingPid(),
8277                 Binder.getCallingUid(), targetUserId, false, ALLOW_FULL_ONLY,
8278                 "grantUriPermissionFromOwner", null);
8279         synchronized(this) {
8280             UriPermissionOwner owner = UriPermissionOwner.fromExternalToken(token);
8281             if (owner == null) {
8282                 throw new IllegalArgumentException("Unknown owner: " + token);
8283             }
8284             if (fromUid != Binder.getCallingUid()) {
8285                 if (Binder.getCallingUid() != Process.myUid()) {
8286                     // Only system code can grant URI permissions on behalf
8287                     // of other users.
8288                     throw new SecurityException("nice try");
8289                 }
8290             }
8291             if (targetPkg == null) {
8292                 throw new IllegalArgumentException("null target");
8293             }
8294             if (uri == null) {
8295                 throw new IllegalArgumentException("null uri");
8296             }
8297
8298             grantUriPermissionLocked(fromUid, targetPkg, new GrantUri(sourceUserId, uri, false),
8299                     modeFlags, owner, targetUserId);
8300         }
8301     }
8302
8303     /**
8304      * @param uri This uri must NOT contain an embedded userId.
8305      * @param userId The userId in which the uri is to be resolved.
8306      */
8307     @Override
8308     public void revokeUriPermissionFromOwner(IBinder token, Uri uri, int mode, int userId) {
8309         synchronized(this) {
8310             UriPermissionOwner owner = UriPermissionOwner.fromExternalToken(token);
8311             if (owner == null) {
8312                 throw new IllegalArgumentException("Unknown owner: " + token);
8313             }
8314
8315             if (uri == null) {
8316                 owner.removeUriPermissionsLocked(mode);
8317             } else {
8318                 owner.removeUriPermissionLocked(new GrantUri(userId, uri, false), mode);
8319             }
8320         }
8321     }
8322
8323     private void schedulePersistUriGrants() {
8324         if (!mHandler.hasMessages(PERSIST_URI_GRANTS_MSG)) {
8325             mHandler.sendMessageDelayed(mHandler.obtainMessage(PERSIST_URI_GRANTS_MSG),
8326                     10 * DateUtils.SECOND_IN_MILLIS);
8327         }
8328     }
8329
8330     private void writeGrantedUriPermissions() {
8331         if (DEBUG_URI_PERMISSION) Slog.v(TAG_URI_PERMISSION, "writeGrantedUriPermissions()");
8332
8333         // Snapshot permissions so we can persist without lock
8334         ArrayList<UriPermission.Snapshot> persist = Lists.newArrayList();
8335         synchronized (this) {
8336             final int size = mGrantedUriPermissions.size();
8337             for (int i = 0; i < size; i++) {
8338                 final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.valueAt(i);
8339                 for (UriPermission perm : perms.values()) {
8340                     if (perm.persistedModeFlags != 0) {
8341                         persist.add(perm.snapshot());
8342                     }
8343                 }
8344             }
8345         }
8346
8347         FileOutputStream fos = null;
8348         try {
8349             fos = mGrantFile.startWrite();
8350
8351             XmlSerializer out = new FastXmlSerializer();
8352             out.setOutput(fos, StandardCharsets.UTF_8.name());
8353             out.startDocument(null, true);
8354             out.startTag(null, TAG_URI_GRANTS);
8355             for (UriPermission.Snapshot perm : persist) {
8356                 out.startTag(null, TAG_URI_GRANT);
8357                 writeIntAttribute(out, ATTR_SOURCE_USER_ID, perm.uri.sourceUserId);
8358                 writeIntAttribute(out, ATTR_TARGET_USER_ID, perm.targetUserId);
8359                 out.attribute(null, ATTR_SOURCE_PKG, perm.sourcePkg);
8360                 out.attribute(null, ATTR_TARGET_PKG, perm.targetPkg);
8361                 out.attribute(null, ATTR_URI, String.valueOf(perm.uri.uri));
8362                 writeBooleanAttribute(out, ATTR_PREFIX, perm.uri.prefix);
8363                 writeIntAttribute(out, ATTR_MODE_FLAGS, perm.persistedModeFlags);
8364                 writeLongAttribute(out, ATTR_CREATED_TIME, perm.persistedCreateTime);
8365                 out.endTag(null, TAG_URI_GRANT);
8366             }
8367             out.endTag(null, TAG_URI_GRANTS);
8368             out.endDocument();
8369
8370             mGrantFile.finishWrite(fos);
8371         } catch (IOException e) {
8372             if (fos != null) {
8373                 mGrantFile.failWrite(fos);
8374             }
8375         }
8376     }
8377
8378     private void readGrantedUriPermissionsLocked() {
8379         if (DEBUG_URI_PERMISSION) Slog.v(TAG_URI_PERMISSION, "readGrantedUriPermissions()");
8380
8381         final long now = System.currentTimeMillis();
8382
8383         FileInputStream fis = null;
8384         try {
8385             fis = mGrantFile.openRead();
8386             final XmlPullParser in = Xml.newPullParser();
8387             in.setInput(fis, StandardCharsets.UTF_8.name());
8388
8389             int type;
8390             while ((type = in.next()) != END_DOCUMENT) {
8391                 final String tag = in.getName();
8392                 if (type == START_TAG) {
8393                     if (TAG_URI_GRANT.equals(tag)) {
8394                         final int sourceUserId;
8395                         final int targetUserId;
8396                         final int userHandle = readIntAttribute(in,
8397                                 ATTR_USER_HANDLE, UserHandle.USER_NULL);
8398                         if (userHandle != UserHandle.USER_NULL) {
8399                             // For backwards compatibility.
8400                             sourceUserId = userHandle;
8401                             targetUserId = userHandle;
8402                         } else {
8403                             sourceUserId = readIntAttribute(in, ATTR_SOURCE_USER_ID);
8404                             targetUserId = readIntAttribute(in, ATTR_TARGET_USER_ID);
8405                         }
8406                         final String sourcePkg = in.getAttributeValue(null, ATTR_SOURCE_PKG);
8407                         final String targetPkg = in.getAttributeValue(null, ATTR_TARGET_PKG);
8408                         final Uri uri = Uri.parse(in.getAttributeValue(null, ATTR_URI));
8409                         final boolean prefix = readBooleanAttribute(in, ATTR_PREFIX);
8410                         final int modeFlags = readIntAttribute(in, ATTR_MODE_FLAGS);
8411                         final long createdTime = readLongAttribute(in, ATTR_CREATED_TIME, now);
8412
8413                         // Sanity check that provider still belongs to source package
8414                         final ProviderInfo pi = getProviderInfoLocked(
8415                                 uri.getAuthority(), sourceUserId);
8416                         if (pi != null && sourcePkg.equals(pi.packageName)) {
8417                             int targetUid = -1;
8418                             try {
8419                                 targetUid = AppGlobals.getPackageManager().getPackageUid(
8420                                         targetPkg, MATCH_UNINSTALLED_PACKAGES, targetUserId);
8421                             } catch (RemoteException e) {
8422                             }
8423                             if (targetUid != -1) {
8424                                 final UriPermission perm = findOrCreateUriPermissionLocked(
8425                                         sourcePkg, targetPkg, targetUid,
8426                                         new GrantUri(sourceUserId, uri, prefix));
8427                                 perm.initPersistedModes(modeFlags, createdTime);
8428                             }
8429                         } else {
8430                             Slog.w(TAG, "Persisted grant for " + uri + " had source " + sourcePkg
8431                                     + " but instead found " + pi);
8432                         }
8433                     }
8434                 }
8435             }
8436         } catch (FileNotFoundException e) {
8437             // Missing grants is okay
8438         } catch (IOException e) {
8439             Slog.wtf(TAG, "Failed reading Uri grants", e);
8440         } catch (XmlPullParserException e) {
8441             Slog.wtf(TAG, "Failed reading Uri grants", e);
8442         } finally {
8443             IoUtils.closeQuietly(fis);
8444         }
8445     }
8446
8447     /**
8448      * @param uri This uri must NOT contain an embedded userId.
8449      * @param userId The userId in which the uri is to be resolved.
8450      */
8451     @Override
8452     public void takePersistableUriPermission(Uri uri, final int modeFlags, int userId) {
8453         enforceNotIsolatedCaller("takePersistableUriPermission");
8454
8455         Preconditions.checkFlagsArgument(modeFlags,
8456                 Intent.FLAG_GRANT_READ_URI_PERMISSION | Intent.FLAG_GRANT_WRITE_URI_PERMISSION);
8457
8458         synchronized (this) {
8459             final int callingUid = Binder.getCallingUid();
8460             boolean persistChanged = false;
8461             GrantUri grantUri = new GrantUri(userId, uri, false);
8462
8463             UriPermission exactPerm = findUriPermissionLocked(callingUid,
8464                     new GrantUri(userId, uri, false));
8465             UriPermission prefixPerm = findUriPermissionLocked(callingUid,
8466                     new GrantUri(userId, uri, true));
8467
8468             final boolean exactValid = (exactPerm != null)
8469                     && ((modeFlags & exactPerm.persistableModeFlags) == modeFlags);
8470             final boolean prefixValid = (prefixPerm != null)
8471                     && ((modeFlags & prefixPerm.persistableModeFlags) == modeFlags);
8472
8473             if (!(exactValid || prefixValid)) {
8474                 throw new SecurityException("No persistable permission grants found for UID "
8475                         + callingUid + " and Uri " + grantUri.toSafeString());
8476             }
8477
8478             if (exactValid) {
8479                 persistChanged |= exactPerm.takePersistableModes(modeFlags);
8480             }
8481             if (prefixValid) {
8482                 persistChanged |= prefixPerm.takePersistableModes(modeFlags);
8483             }
8484
8485             persistChanged |= maybePrunePersistedUriGrantsLocked(callingUid);
8486
8487             if (persistChanged) {
8488                 schedulePersistUriGrants();
8489             }
8490         }
8491     }
8492
8493     /**
8494      * @param uri This uri must NOT contain an embedded userId.
8495      * @param userId The userId in which the uri is to be resolved.
8496      */
8497     @Override
8498     public void releasePersistableUriPermission(Uri uri, final int modeFlags, int userId) {
8499         enforceNotIsolatedCaller("releasePersistableUriPermission");
8500
8501         Preconditions.checkFlagsArgument(modeFlags,
8502                 Intent.FLAG_GRANT_READ_URI_PERMISSION | Intent.FLAG_GRANT_WRITE_URI_PERMISSION);
8503
8504         synchronized (this) {
8505             final int callingUid = Binder.getCallingUid();
8506             boolean persistChanged = false;
8507
8508             UriPermission exactPerm = findUriPermissionLocked(callingUid,
8509                     new GrantUri(userId, uri, false));
8510             UriPermission prefixPerm = findUriPermissionLocked(callingUid,
8511                     new GrantUri(userId, uri, true));
8512             if (exactPerm == null && prefixPerm == null) {
8513                 throw new SecurityException("No permission grants found for UID " + callingUid
8514                         + " and Uri " + uri.toSafeString());
8515             }
8516
8517             if (exactPerm != null) {
8518                 persistChanged |= exactPerm.releasePersistableModes(modeFlags);
8519                 removeUriPermissionIfNeededLocked(exactPerm);
8520             }
8521             if (prefixPerm != null) {
8522                 persistChanged |= prefixPerm.releasePersistableModes(modeFlags);
8523                 removeUriPermissionIfNeededLocked(prefixPerm);
8524             }
8525
8526             if (persistChanged) {
8527                 schedulePersistUriGrants();
8528             }
8529         }
8530     }
8531
8532     /**
8533      * Prune any older {@link UriPermission} for the given UID until outstanding
8534      * persisted grants are below {@link #MAX_PERSISTED_URI_GRANTS}.
8535      *
8536      * @return if any mutations occured that require persisting.
8537      */
8538     private boolean maybePrunePersistedUriGrantsLocked(int uid) {
8539         final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.get(uid);
8540         if (perms == null) return false;
8541         if (perms.size() < MAX_PERSISTED_URI_GRANTS) return false;
8542
8543         final ArrayList<UriPermission> persisted = Lists.newArrayList();
8544         for (UriPermission perm : perms.values()) {
8545             if (perm.persistedModeFlags != 0) {
8546                 persisted.add(perm);
8547             }
8548         }
8549
8550         final int trimCount = persisted.size() - MAX_PERSISTED_URI_GRANTS;
8551         if (trimCount <= 0) return false;
8552
8553         Collections.sort(persisted, new UriPermission.PersistedTimeComparator());
8554         for (int i = 0; i < trimCount; i++) {
8555             final UriPermission perm = persisted.get(i);
8556
8557             if (DEBUG_URI_PERMISSION) Slog.v(TAG_URI_PERMISSION,
8558                     "Trimming grant created at " + perm.persistedCreateTime);
8559
8560             perm.releasePersistableModes(~0);
8561             removeUriPermissionIfNeededLocked(perm);
8562         }
8563
8564         return true;
8565     }
8566
8567     @Override
8568     public ParceledListSlice<android.content.UriPermission> getPersistedUriPermissions(
8569             String packageName, boolean incoming) {
8570         enforceNotIsolatedCaller("getPersistedUriPermissions");
8571         Preconditions.checkNotNull(packageName, "packageName");
8572
8573         final int callingUid = Binder.getCallingUid();
8574         final IPackageManager pm = AppGlobals.getPackageManager();
8575         try {
8576             final int packageUid = pm.getPackageUid(packageName, MATCH_DEBUG_TRIAGED_MISSING,
8577                     UserHandle.getUserId(callingUid));
8578             if (packageUid != callingUid) {
8579                 throw new SecurityException(
8580                         "Package " + packageName + " does not belong to calling UID " + callingUid);
8581             }
8582         } catch (RemoteException e) {
8583             throw new SecurityException("Failed to verify package name ownership");
8584         }
8585
8586         final ArrayList<android.content.UriPermission> result = Lists.newArrayList();
8587         synchronized (this) {
8588             if (incoming) {
8589                 final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.get(
8590                         callingUid);
8591                 if (perms == null) {
8592                     Slog.w(TAG, "No permission grants found for " + packageName);
8593                 } else {
8594                     for (UriPermission perm : perms.values()) {
8595                         if (packageName.equals(perm.targetPkg) && perm.persistedModeFlags != 0) {
8596                             result.add(perm.buildPersistedPublicApiObject());
8597                         }
8598                     }
8599                 }
8600             } else {
8601                 final int size = mGrantedUriPermissions.size();
8602                 for (int i = 0; i < size; i++) {
8603                     final ArrayMap<GrantUri, UriPermission> perms =
8604                             mGrantedUriPermissions.valueAt(i);
8605                     for (UriPermission perm : perms.values()) {
8606                         if (packageName.equals(perm.sourcePkg) && perm.persistedModeFlags != 0) {
8607                             result.add(perm.buildPersistedPublicApiObject());
8608                         }
8609                     }
8610                 }
8611             }
8612         }
8613         return new ParceledListSlice<android.content.UriPermission>(result);
8614     }
8615
8616     @Override
8617     public ParceledListSlice<android.content.UriPermission> getGrantedUriPermissions(
8618             String packageName, int userId) {
8619         enforceCallingPermission(android.Manifest.permission.GET_APP_GRANTED_URI_PERMISSIONS,
8620                 "getGrantedUriPermissions");
8621
8622         final ArrayList<android.content.UriPermission> result = Lists.newArrayList();
8623         synchronized (this) {
8624             final int size = mGrantedUriPermissions.size();
8625             for (int i = 0; i < size; i++) {
8626                 final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.valueAt(i);
8627                 for (UriPermission perm : perms.values()) {
8628                     if (packageName.equals(perm.targetPkg) && perm.targetUserId == userId
8629                             && perm.persistedModeFlags != 0) {
8630                         result.add(perm.buildPersistedPublicApiObject());
8631                     }
8632                 }
8633             }
8634         }
8635         return new ParceledListSlice<android.content.UriPermission>(result);
8636     }
8637
8638     @Override
8639     public void clearGrantedUriPermissions(String packageName, int userId) {
8640         enforceCallingPermission(android.Manifest.permission.CLEAR_APP_GRANTED_URI_PERMISSIONS,
8641                 "clearGrantedUriPermissions");
8642         removeUriPermissionsForPackageLocked(packageName, userId, true);
8643     }
8644
8645     @Override
8646     public void showWaitingForDebugger(IApplicationThread who, boolean waiting) {
8647         synchronized (this) {
8648             ProcessRecord app =
8649                 who != null ? getRecordForAppLocked(who) : null;
8650             if (app == null) return;
8651
8652             Message msg = Message.obtain();
8653             msg.what = WAIT_FOR_DEBUGGER_UI_MSG;
8654             msg.obj = app;
8655             msg.arg1 = waiting ? 1 : 0;
8656             mUiHandler.sendMessage(msg);
8657         }
8658     }
8659
8660     @Override
8661     public void getMemoryInfo(ActivityManager.MemoryInfo outInfo) {
8662         final long homeAppMem = mProcessList.getMemLevel(ProcessList.HOME_APP_ADJ);
8663         final long cachedAppMem = mProcessList.getMemLevel(ProcessList.CACHED_APP_MIN_ADJ);
8664         outInfo.availMem = Process.getFreeMemory();
8665         outInfo.totalMem = Process.getTotalMemory();
8666         outInfo.threshold = homeAppMem;
8667         outInfo.lowMemory = outInfo.availMem < (homeAppMem + ((cachedAppMem-homeAppMem)/2));
8668         outInfo.hiddenAppThreshold = cachedAppMem;
8669         outInfo.secondaryServerThreshold = mProcessList.getMemLevel(
8670                 ProcessList.SERVICE_ADJ);
8671         outInfo.visibleAppThreshold = mProcessList.getMemLevel(
8672                 ProcessList.VISIBLE_APP_ADJ);
8673         outInfo.foregroundAppThreshold = mProcessList.getMemLevel(
8674                 ProcessList.FOREGROUND_APP_ADJ);
8675     }
8676
8677     // =========================================================
8678     // TASK MANAGEMENT
8679     // =========================================================
8680
8681     @Override
8682     public List<IAppTask> getAppTasks(String callingPackage) {
8683         int callingUid = Binder.getCallingUid();
8684         long ident = Binder.clearCallingIdentity();
8685
8686         synchronized(this) {
8687             ArrayList<IAppTask> list = new ArrayList<IAppTask>();
8688             try {
8689                 if (DEBUG_ALL) Slog.v(TAG, "getAppTasks");
8690
8691                 final int N = mRecentTasks.size();
8692                 for (int i = 0; i < N; i++) {
8693                     TaskRecord tr = mRecentTasks.get(i);
8694                     // Skip tasks that do not match the caller.  We don't need to verify
8695                     // callingPackage, because we are also limiting to callingUid and know
8696                     // that will limit to the correct security sandbox.
8697                     if (tr.effectiveUid != callingUid) {
8698                         continue;
8699                     }
8700                     Intent intent = tr.getBaseIntent();
8701                     if (intent == null ||
8702                             !callingPackage.equals(intent.getComponent().getPackageName())) {
8703                         continue;
8704                     }
8705                     ActivityManager.RecentTaskInfo taskInfo =
8706                             createRecentTaskInfoFromTaskRecord(tr);
8707                     AppTaskImpl taskImpl = new AppTaskImpl(taskInfo.persistentId, callingUid);
8708                     list.add(taskImpl);
8709                 }
8710             } finally {
8711                 Binder.restoreCallingIdentity(ident);
8712             }
8713             return list;
8714         }
8715     }
8716
8717     @Override
8718     public List<RunningTaskInfo> getTasks(int maxNum, int flags) {
8719         final int callingUid = Binder.getCallingUid();
8720         ArrayList<RunningTaskInfo> list = new ArrayList<RunningTaskInfo>();
8721
8722         synchronized(this) {
8723             if (DEBUG_ALL) Slog.v(
8724                 TAG, "getTasks: max=" + maxNum + ", flags=" + flags);
8725
8726             final boolean allowed = isGetTasksAllowed("getTasks", Binder.getCallingPid(),
8727                     callingUid);
8728
8729             // TODO: Improve with MRU list from all ActivityStacks.
8730             mStackSupervisor.getTasksLocked(maxNum, list, callingUid, allowed);
8731         }
8732
8733         return list;
8734     }
8735
8736     /**
8737      * Creates a new RecentTaskInfo from a TaskRecord.
8738      */
8739     private ActivityManager.RecentTaskInfo createRecentTaskInfoFromTaskRecord(TaskRecord tr) {
8740         // Update the task description to reflect any changes in the task stack
8741         tr.updateTaskDescription();
8742
8743         // Compose the recent task info
8744         ActivityManager.RecentTaskInfo rti = new ActivityManager.RecentTaskInfo();
8745         rti.id = tr.getTopActivity() == null ? INVALID_TASK_ID : tr.taskId;
8746         rti.persistentId = tr.taskId;
8747         rti.baseIntent = new Intent(tr.getBaseIntent());
8748         rti.origActivity = tr.origActivity;
8749         rti.realActivity = tr.realActivity;
8750         rti.description = tr.lastDescription;
8751         rti.stackId = tr.stack != null ? tr.stack.mStackId : -1;
8752         rti.userId = tr.userId;
8753         rti.taskDescription = new ActivityManager.TaskDescription(tr.lastTaskDescription);
8754         rti.firstActiveTime = tr.firstActiveTime;
8755         rti.lastActiveTime = tr.lastActiveTime;
8756         rti.affiliatedTaskId = tr.mAffiliatedTaskId;
8757         rti.affiliatedTaskColor = tr.mAffiliatedTaskColor;
8758         rti.numActivities = 0;
8759         if (tr.mBounds != null) {
8760             rti.bounds = new Rect(tr.mBounds);
8761         }
8762         rti.isDockable = tr.canGoInDockedStack();
8763
8764         ActivityRecord base = null;
8765         ActivityRecord top = null;
8766         ActivityRecord tmp;
8767
8768         for (int i = tr.mActivities.size() - 1; i >= 0; --i) {
8769             tmp = tr.mActivities.get(i);
8770             if (tmp.finishing) {
8771                 continue;
8772             }
8773             base = tmp;
8774             if (top == null || (top.state == ActivityState.INITIALIZING)) {
8775                 top = base;
8776             }
8777             rti.numActivities++;
8778         }
8779
8780         rti.baseActivity = (base != null) ? base.intent.getComponent() : null;
8781         rti.topActivity = (top != null) ? top.intent.getComponent() : null;
8782
8783         return rti;
8784     }
8785
8786     private boolean isGetTasksAllowed(String caller, int callingPid, int callingUid) {
8787         boolean allowed = checkPermission(android.Manifest.permission.REAL_GET_TASKS,
8788                 callingPid, callingUid) == PackageManager.PERMISSION_GRANTED;
8789         if (!allowed) {
8790             if (checkPermission(android.Manifest.permission.GET_TASKS,
8791                     callingPid, callingUid) == PackageManager.PERMISSION_GRANTED) {
8792                 // Temporary compatibility: some existing apps on the system image may
8793                 // still be requesting the old permission and not switched to the new
8794                 // one; if so, we'll still allow them full access.  This means we need
8795                 // to see if they are holding the old permission and are a system app.
8796                 try {
8797                     if (AppGlobals.getPackageManager().isUidPrivileged(callingUid)) {
8798                         allowed = true;
8799                         if (DEBUG_TASKS) Slog.w(TAG, caller + ": caller " + callingUid
8800                                 + " is using old GET_TASKS but privileged; allowing");
8801                     }
8802                 } catch (RemoteException e) {
8803                 }
8804             }
8805         }
8806         if (!allowed) {
8807             if (DEBUG_TASKS) Slog.w(TAG, caller + ": caller " + callingUid
8808                     + " does not hold REAL_GET_TASKS; limiting output");
8809         }
8810         return allowed;
8811     }
8812
8813     @Override
8814     public List<ActivityManager.RecentTaskInfo> getRecentTasks(int maxNum, int flags, int userId) {
8815         final int callingUid = Binder.getCallingUid();
8816         userId = mUserController.handleIncomingUser(Binder.getCallingPid(), callingUid, userId,
8817                 false, ALLOW_FULL_ONLY, "getRecentTasks", null);
8818
8819         final boolean includeProfiles = (flags & ActivityManager.RECENT_INCLUDE_PROFILES) != 0;
8820         final boolean withExcluded = (flags&ActivityManager.RECENT_WITH_EXCLUDED) != 0;
8821         synchronized (this) {
8822             final boolean allowed = isGetTasksAllowed("getRecentTasks", Binder.getCallingPid(),
8823                     callingUid);
8824             final boolean detailed = checkCallingPermission(
8825                     android.Manifest.permission.GET_DETAILED_TASKS)
8826                     == PackageManager.PERMISSION_GRANTED;
8827
8828             if (!isUserRunning(userId, ActivityManager.FLAG_AND_UNLOCKED)) {
8829                 Slog.i(TAG, "user " + userId + " is still locked. Cannot load recents");
8830                 return Collections.emptyList();
8831             }
8832             mRecentTasks.loadUserRecentsLocked(userId);
8833
8834             final int recentsCount = mRecentTasks.size();
8835             ArrayList<ActivityManager.RecentTaskInfo> res =
8836                     new ArrayList<>(maxNum < recentsCount ? maxNum : recentsCount);
8837
8838             final Set<Integer> includedUsers;
8839             if (includeProfiles) {
8840                 includedUsers = mUserController.getProfileIds(userId);
8841             } else {
8842                 includedUsers = new HashSet<>();
8843             }
8844             includedUsers.add(Integer.valueOf(userId));
8845
8846             for (int i = 0; i < recentsCount && maxNum > 0; i++) {
8847                 TaskRecord tr = mRecentTasks.get(i);
8848                 // Only add calling user or related users recent tasks
8849                 if (!includedUsers.contains(Integer.valueOf(tr.userId))) {
8850                     if (DEBUG_RECENTS) Slog.d(TAG_RECENTS, "Skipping, not user: " + tr);
8851                     continue;
8852                 }
8853
8854                 if (tr.realActivitySuspended) {
8855                     if (DEBUG_RECENTS) Slog.d(TAG_RECENTS, "Skipping, activity suspended: " + tr);
8856                     continue;
8857                 }
8858
8859                 // Return the entry if desired by the caller.  We always return
8860                 // the first entry, because callers always expect this to be the
8861                 // foreground app.  We may filter others if the caller has
8862                 // not supplied RECENT_WITH_EXCLUDED and there is some reason
8863                 // we should exclude the entry.
8864
8865                 if (i == 0
8866                         || withExcluded
8867                         || (tr.intent == null)
8868                         || ((tr.intent.getFlags() & Intent.FLAG_ACTIVITY_EXCLUDE_FROM_RECENTS)
8869                                 == 0)) {
8870                     if (!allowed) {
8871                         // If the caller doesn't have the GET_TASKS permission, then only
8872                         // allow them to see a small subset of tasks -- their own and home.
8873                         if (!tr.isHomeTask() && tr.effectiveUid != callingUid) {
8874                             if (DEBUG_RECENTS) Slog.d(TAG_RECENTS, "Skipping, not allowed: " + tr);
8875                             continue;
8876                         }
8877                     }
8878                     if ((flags & ActivityManager.RECENT_IGNORE_HOME_STACK_TASKS) != 0) {
8879                         if (tr.stack != null && tr.stack.isHomeStack()) {
8880                             if (DEBUG_RECENTS) Slog.d(TAG_RECENTS,
8881                                     "Skipping, home stack task: " + tr);
8882                             continue;
8883                         }
8884                     }
8885                     if ((flags & ActivityManager.RECENT_INGORE_DOCKED_STACK_TASKS) != 0) {
8886                         if (tr.stack != null && tr.stack.isDockedStack()) {
8887                             if (DEBUG_RECENTS) Slog.d(TAG_RECENTS,
8888                                     "Skipping, docked stack task: " + tr);
8889                             continue;
8890                         }
8891                     }
8892                     if ((flags & ActivityManager.RECENT_INGORE_PINNED_STACK_TASKS) != 0) {
8893                         if (tr.stack != null && tr.stack.isPinnedStack()) {
8894                             if (DEBUG_RECENTS) Slog.d(TAG_RECENTS,
8895                                     "Skipping, pinned stack task: " + tr);
8896                             continue;
8897                         }
8898                     }
8899                     if (tr.autoRemoveRecents && tr.getTopActivity() == null) {
8900                         // Don't include auto remove tasks that are finished or finishing.
8901                         if (DEBUG_RECENTS) Slog.d(TAG_RECENTS,
8902                                 "Skipping, auto-remove without activity: " + tr);
8903                         continue;
8904                     }
8905                     if ((flags&ActivityManager.RECENT_IGNORE_UNAVAILABLE) != 0
8906                             && !tr.isAvailable) {
8907                         if (DEBUG_RECENTS) Slog.d(TAG_RECENTS,
8908                                 "Skipping, unavail real act: " + tr);
8909                         continue;
8910                     }
8911
8912                     if (!tr.mUserSetupComplete) {
8913                         // Don't include task launched while user is not done setting-up.
8914                         if (DEBUG_RECENTS) Slog.d(TAG_RECENTS,
8915                                 "Skipping, user setup not complete: " + tr);
8916                         continue;
8917                     }
8918
8919                     ActivityManager.RecentTaskInfo rti = createRecentTaskInfoFromTaskRecord(tr);
8920                     if (!detailed) {
8921                         rti.baseIntent.replaceExtras((Bundle)null);
8922                     }
8923
8924                     res.add(rti);
8925                     maxNum--;
8926                 }
8927             }
8928             return res;
8929         }
8930     }
8931
8932     @Override
8933     public ActivityManager.TaskThumbnail getTaskThumbnail(int id) {
8934         synchronized (this) {
8935             enforceCallingPermission(android.Manifest.permission.READ_FRAME_BUFFER,
8936                     "getTaskThumbnail()");
8937             final TaskRecord tr = mStackSupervisor.anyTaskForIdLocked(
8938                     id, !RESTORE_FROM_RECENTS, INVALID_STACK_ID);
8939             if (tr != null) {
8940                 return tr.getTaskThumbnailLocked();
8941             }
8942         }
8943         return null;
8944     }
8945
8946     @Override
8947     public int addAppTask(IBinder activityToken, Intent intent,
8948             ActivityManager.TaskDescription description, Bitmap thumbnail) throws RemoteException {
8949         final int callingUid = Binder.getCallingUid();
8950         final long callingIdent = Binder.clearCallingIdentity();
8951
8952         try {
8953             synchronized (this) {
8954                 ActivityRecord r = ActivityRecord.isInStackLocked(activityToken);
8955                 if (r == null) {
8956                     throw new IllegalArgumentException("Activity does not exist; token="
8957                             + activityToken);
8958                 }
8959                 ComponentName comp = intent.getComponent();
8960                 if (comp == null) {
8961                     throw new IllegalArgumentException("Intent " + intent
8962                             + " must specify explicit component");
8963                 }
8964                 if (thumbnail.getWidth() != mThumbnailWidth
8965                         || thumbnail.getHeight() != mThumbnailHeight) {
8966                     throw new IllegalArgumentException("Bad thumbnail size: got "
8967                             + thumbnail.getWidth() + "x" + thumbnail.getHeight() + ", require "
8968                             + mThumbnailWidth + "x" + mThumbnailHeight);
8969                 }
8970                 if (intent.getSelector() != null) {
8971                     intent.setSelector(null);
8972                 }
8973                 if (intent.getSourceBounds() != null) {
8974                     intent.setSourceBounds(null);
8975                 }
8976                 if ((intent.getFlags()&Intent.FLAG_ACTIVITY_NEW_DOCUMENT) != 0) {
8977                     if ((intent.getFlags()&Intent.FLAG_ACTIVITY_RETAIN_IN_RECENTS) == 0) {
8978                         // The caller has added this as an auto-remove task...  that makes no
8979                         // sense, so turn off auto-remove.
8980                         intent.addFlags(Intent.FLAG_ACTIVITY_RETAIN_IN_RECENTS);
8981                     }
8982                 } else if ((intent.getFlags()&Intent.FLAG_ACTIVITY_NEW_TASK) != 0) {
8983                     // Must be a new task.
8984                     intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
8985                 }
8986                 if (!comp.equals(mLastAddedTaskComponent) || callingUid != mLastAddedTaskUid) {
8987                     mLastAddedTaskActivity = null;
8988                 }
8989                 ActivityInfo ainfo = mLastAddedTaskActivity;
8990                 if (ainfo == null) {
8991                     ainfo = mLastAddedTaskActivity = AppGlobals.getPackageManager().getActivityInfo(
8992                             comp, 0, UserHandle.getUserId(callingUid));
8993                     if (ainfo.applicationInfo.uid != callingUid) {
8994                         throw new SecurityException(
8995                                 "Can't add task for another application: target uid="
8996                                 + ainfo.applicationInfo.uid + ", calling uid=" + callingUid);
8997                     }
8998                 }
8999
9000                 // Use the full screen as the context for the task thumbnail
9001                 final Point displaySize = new Point();
9002                 final TaskThumbnailInfo thumbnailInfo = new TaskThumbnailInfo();
9003                 r.task.stack.getDisplaySize(displaySize);
9004                 thumbnailInfo.taskWidth = displaySize.x;
9005                 thumbnailInfo.taskHeight = displaySize.y;
9006                 thumbnailInfo.screenOrientation = mConfiguration.orientation;
9007
9008                 TaskRecord task = new TaskRecord(this,
9009                         mStackSupervisor.getNextTaskIdForUserLocked(r.userId),
9010                         ainfo, intent, description, thumbnailInfo);
9011
9012                 int trimIdx = mRecentTasks.trimForTaskLocked(task, false);
9013                 if (trimIdx >= 0) {
9014                     // If this would have caused a trim, then we'll abort because that
9015                     // means it would be added at the end of the list but then just removed.
9016                     return INVALID_TASK_ID;
9017                 }
9018
9019                 final int N = mRecentTasks.size();
9020                 if (N >= (ActivityManager.getMaxRecentTasksStatic()-1)) {
9021                     final TaskRecord tr = mRecentTasks.remove(N - 1);
9022                     tr.removedFromRecents();
9023                 }
9024
9025                 task.inRecents = true;
9026                 mRecentTasks.add(task);
9027                 r.task.stack.addTask(task, false, "addAppTask");
9028
9029                 task.setLastThumbnailLocked(thumbnail);
9030                 task.freeLastThumbnail();
9031
9032                 return task.taskId;
9033             }
9034         } finally {
9035             Binder.restoreCallingIdentity(callingIdent);
9036         }
9037     }
9038
9039     @Override
9040     public Point getAppTaskThumbnailSize() {
9041         synchronized (this) {
9042             return new Point(mThumbnailWidth,  mThumbnailHeight);
9043         }
9044     }
9045
9046     @Override
9047     public void setTaskDescription(IBinder token, ActivityManager.TaskDescription td) {
9048         synchronized (this) {
9049             ActivityRecord r = ActivityRecord.isInStackLocked(token);
9050             if (r != null) {
9051                 r.setTaskDescription(td);
9052                 r.task.updateTaskDescription();
9053             }
9054         }
9055     }
9056
9057     @Override
9058     public void setTaskResizeable(int taskId, int resizeableMode) {
9059         synchronized (this) {
9060             final TaskRecord task = mStackSupervisor.anyTaskForIdLocked(
9061                     taskId, !RESTORE_FROM_RECENTS, INVALID_STACK_ID);
9062             if (task == null) {
9063                 Slog.w(TAG, "setTaskResizeable: taskId=" + taskId + " not found");
9064                 return;
9065             }
9066             if (task.mResizeMode != resizeableMode) {
9067                 task.mResizeMode = resizeableMode;
9068                 mWindowManager.setTaskResizeable(taskId, resizeableMode);
9069                 mStackSupervisor.ensureActivitiesVisibleLocked(null, 0, !PRESERVE_WINDOWS);
9070                 mStackSupervisor.resumeFocusedStackTopActivityLocked();
9071             }
9072         }
9073     }
9074
9075     @Override
9076     public void resizeTask(int taskId, Rect bounds, int resizeMode) {
9077         enforceCallingPermission(MANAGE_ACTIVITY_STACKS, "resizeTask()");
9078         long ident = Binder.clearCallingIdentity();
9079         try {
9080             synchronized (this) {
9081                 TaskRecord task = mStackSupervisor.anyTaskForIdLocked(taskId);
9082                 if (task == null) {
9083                     Slog.w(TAG, "resizeTask: taskId=" + taskId + " not found");
9084                     return;
9085                 }
9086                 int stackId = task.stack.mStackId;
9087                 // We allow the task to scroll instead of resizing if this is a non-resizeable task
9088                 // in crop windows resize mode or if the task size is affected by the docked stack
9089                 // changing size. No need to update configuration.
9090                 if (bounds != null && task.inCropWindowsResizeMode()
9091                         && mStackSupervisor.isStackDockedInEffect(stackId)) {
9092                     mWindowManager.scrollTask(task.taskId, bounds);
9093                     return;
9094                 }
9095
9096                 // Place the task in the right stack if it isn't there already based on
9097                 // the requested bounds.
9098                 // The stack transition logic is:
9099                 // - a null bounds on a freeform task moves that task to fullscreen
9100                 // - a non-null bounds on a non-freeform (fullscreen OR docked) task moves
9101                 //   that task to freeform
9102                 // - otherwise the task is not moved
9103                 if (!StackId.isTaskResizeAllowed(stackId)) {
9104                     throw new IllegalArgumentException("resizeTask not allowed on task=" + task);
9105                 }
9106                 if (bounds == null && stackId == FREEFORM_WORKSPACE_STACK_ID) {
9107                     stackId = FULLSCREEN_WORKSPACE_STACK_ID;
9108                 } else if (bounds != null && stackId != FREEFORM_WORKSPACE_STACK_ID ) {
9109                     stackId = FREEFORM_WORKSPACE_STACK_ID;
9110                 }
9111                 boolean preserveWindow = (resizeMode & RESIZE_MODE_PRESERVE_WINDOW) != 0;
9112                 if (stackId != task.stack.mStackId) {
9113                     mStackSupervisor.moveTaskToStackUncheckedLocked(
9114                             task, stackId, ON_TOP, !FORCE_FOCUS, "resizeTask");
9115                     preserveWindow = false;
9116                 }
9117
9118                 mStackSupervisor.resizeTaskLocked(task, bounds, resizeMode, preserveWindow,
9119                         false /* deferResume */);
9120             }
9121         } finally {
9122             Binder.restoreCallingIdentity(ident);
9123         }
9124     }
9125
9126     @Override
9127     public Rect getTaskBounds(int taskId) {
9128         enforceCallingPermission(MANAGE_ACTIVITY_STACKS, "getTaskBounds()");
9129         long ident = Binder.clearCallingIdentity();
9130         Rect rect = new Rect();
9131         try {
9132             synchronized (this) {
9133                 final TaskRecord task = mStackSupervisor.anyTaskForIdLocked(
9134                         taskId, !RESTORE_FROM_RECENTS, INVALID_STACK_ID);
9135                 if (task == null) {
9136                     Slog.w(TAG, "getTaskBounds: taskId=" + taskId + " not found");
9137                     return rect;
9138                 }
9139                 if (task.stack != null) {
9140                     // Return the bounds from window manager since it will be adjusted for various
9141                     // things like the presense of a docked stack for tasks that aren't resizeable.
9142                     mWindowManager.getTaskBounds(task.taskId, rect);
9143                 } else {
9144                     // Task isn't in window manager yet since it isn't associated with a stack.
9145                     // Return the persist value from activity manager
9146                     if (task.mBounds != null) {
9147                         rect.set(task.mBounds);
9148                     } else if (task.mLastNonFullscreenBounds != null) {
9149                         rect.set(task.mLastNonFullscreenBounds);
9150                     }
9151                 }
9152             }
9153         } finally {
9154             Binder.restoreCallingIdentity(ident);
9155         }
9156         return rect;
9157     }
9158
9159     @Override
9160     public Bitmap getTaskDescriptionIcon(String filePath, int userId) {
9161         if (userId != UserHandle.getCallingUserId()) {
9162             enforceCallingPermission(android.Manifest.permission.INTERACT_ACROSS_USERS_FULL,
9163                     "getTaskDescriptionIcon");
9164         }
9165         final File passedIconFile = new File(filePath);
9166         final File legitIconFile = new File(TaskPersister.getUserImagesDir(userId),
9167                 passedIconFile.getName());
9168         if (!legitIconFile.getPath().equals(filePath)
9169                 || !filePath.contains(ActivityRecord.ACTIVITY_ICON_SUFFIX)) {
9170             throw new IllegalArgumentException("Bad file path: " + filePath
9171                     + " passed for userId " + userId);
9172         }
9173         return mRecentTasks.getTaskDescriptionIcon(filePath);
9174     }
9175
9176     @Override
9177     public void startInPlaceAnimationOnFrontMostApplication(ActivityOptions opts)
9178             throws RemoteException {
9179         if (opts.getAnimationType() != ActivityOptions.ANIM_CUSTOM_IN_PLACE ||
9180                 opts.getCustomInPlaceResId() == 0) {
9181             throw new IllegalArgumentException("Expected in-place ActivityOption " +
9182                     "with valid animation");
9183         }
9184         mWindowManager.prepareAppTransition(TRANSIT_TASK_IN_PLACE, false);
9185         mWindowManager.overridePendingAppTransitionInPlace(opts.getPackageName(),
9186                 opts.getCustomInPlaceResId());
9187         mWindowManager.executeAppTransition();
9188     }
9189
9190     private void cleanUpRemovedTaskLocked(TaskRecord tr, boolean killProcess,
9191             boolean removeFromRecents) {
9192         if (removeFromRecents) {
9193             mRecentTasks.remove(tr);
9194             tr.removedFromRecents();
9195         }
9196         ComponentName component = tr.getBaseIntent().getComponent();
9197         if (component == null) {
9198             Slog.w(TAG, "No component for base intent of task: " + tr);
9199             return;
9200         }
9201
9202         // Find any running services associated with this app and stop if needed.
9203         mServices.cleanUpRemovedTaskLocked(tr, component, new Intent(tr.getBaseIntent()));
9204
9205         if (!killProcess) {
9206             return;
9207         }
9208
9209         // Determine if the process(es) for this task should be killed.
9210         final String pkg = component.getPackageName();
9211         ArrayList<ProcessRecord> procsToKill = new ArrayList<>();
9212         ArrayMap<String, SparseArray<ProcessRecord>> pmap = mProcessNames.getMap();
9213         for (int i = 0; i < pmap.size(); i++) {
9214
9215             SparseArray<ProcessRecord> uids = pmap.valueAt(i);
9216             for (int j = 0; j < uids.size(); j++) {
9217                 ProcessRecord proc = uids.valueAt(j);
9218                 if (proc.userId != tr.userId) {
9219                     // Don't kill process for a different user.
9220                     continue;
9221                 }
9222                 if (proc == mHomeProcess) {
9223                     // Don't kill the home process along with tasks from the same package.
9224                     continue;
9225                 }
9226                 if (!proc.pkgList.containsKey(pkg)) {
9227                     // Don't kill process that is not associated with this task.
9228                     continue;
9229                 }
9230
9231                 for (int k = 0; k < proc.activities.size(); k++) {
9232                     TaskRecord otherTask = proc.activities.get(k).task;
9233                     if (tr.taskId != otherTask.taskId && otherTask.inRecents) {
9234                         // Don't kill process(es) that has an activity in a different task that is
9235                         // also in recents.
9236                         return;
9237                     }
9238                 }
9239
9240                 if (proc.foregroundServices) {
9241                     // Don't kill process(es) with foreground service.
9242                     return;
9243                 }
9244
9245                 // Add process to kill list.
9246                 procsToKill.add(proc);
9247             }
9248         }
9249
9250         // Kill the running processes.
9251         for (int i = 0; i < procsToKill.size(); i++) {
9252             ProcessRecord pr = procsToKill.get(i);
9253             if (pr.setSchedGroup == ProcessList.SCHED_GROUP_BACKGROUND
9254                     && pr.curReceiver == null) {
9255                 pr.kill("remove task", true);
9256             } else {
9257                 // We delay killing processes that are not in the background or running a receiver.
9258                 pr.waitingToKill = "remove task";
9259             }
9260         }
9261     }
9262
9263     private void removeTasksByPackageNameLocked(String packageName, int userId) {
9264         // Remove all tasks with activities in the specified package from the list of recent tasks
9265         for (int i = mRecentTasks.size() - 1; i >= 0; i--) {
9266             TaskRecord tr = mRecentTasks.get(i);
9267             if (tr.userId != userId) continue;
9268
9269             ComponentName cn = tr.intent.getComponent();
9270             if (cn != null && cn.getPackageName().equals(packageName)) {
9271                 // If the package name matches, remove the task.
9272                 removeTaskByIdLocked(tr.taskId, true, REMOVE_FROM_RECENTS);
9273             }
9274         }
9275     }
9276
9277     private void cleanupDisabledPackageTasksLocked(String packageName, Set<String> filterByClasses,
9278             int userId) {
9279
9280         for (int i = mRecentTasks.size() - 1; i >= 0; i--) {
9281             TaskRecord tr = mRecentTasks.get(i);
9282             if (userId != UserHandle.USER_ALL && tr.userId != userId) {
9283                 continue;
9284             }
9285
9286             ComponentName cn = tr.intent.getComponent();
9287             final boolean sameComponent = cn != null && cn.getPackageName().equals(packageName)
9288                     && (filterByClasses == null || filterByClasses.contains(cn.getClassName()));
9289             if (sameComponent) {
9290                 removeTaskByIdLocked(tr.taskId, false, REMOVE_FROM_RECENTS);
9291             }
9292         }
9293     }
9294
9295     /**
9296      * Removes the task with the specified task id.
9297      *
9298      * @param taskId Identifier of the task to be removed.
9299      * @param killProcess Kill any process associated with the task if possible.
9300      * @param removeFromRecents Whether to also remove the task from recents.
9301      * @return Returns true if the given task was found and removed.
9302      */
9303     private boolean removeTaskByIdLocked(int taskId, boolean killProcess,
9304             boolean removeFromRecents) {
9305         final TaskRecord tr = mStackSupervisor.anyTaskForIdLocked(
9306                 taskId, !RESTORE_FROM_RECENTS, INVALID_STACK_ID);
9307         if (tr != null) {
9308             tr.removeTaskActivitiesLocked();
9309             cleanUpRemovedTaskLocked(tr, killProcess, removeFromRecents);
9310             if (tr.isPersistable) {
9311                 notifyTaskPersisterLocked(null, true);
9312             }
9313             return true;
9314         }
9315         Slog.w(TAG, "Request to remove task ignored for non-existent task " + taskId);
9316         return false;
9317     }
9318
9319     @Override
9320     public void removeStack(int stackId) {
9321         enforceCallingPermission(Manifest.permission.MANAGE_ACTIVITY_STACKS, "removeStack()");
9322         if (stackId == HOME_STACK_ID) {
9323             throw new IllegalArgumentException("Removing home stack is not allowed.");
9324         }
9325
9326         synchronized (this) {
9327             final long ident = Binder.clearCallingIdentity();
9328             try {
9329                 final ActivityStack stack = mStackSupervisor.getStack(stackId);
9330                 if (stack == null) {
9331                     return;
9332                 }
9333                 final ArrayList<TaskRecord> tasks = stack.getAllTasks();
9334                 for (int i = tasks.size() - 1; i >= 0; i--) {
9335                     removeTaskByIdLocked(
9336                             tasks.get(i).taskId, true /* killProcess */, REMOVE_FROM_RECENTS);
9337                 }
9338             } finally {
9339                 Binder.restoreCallingIdentity(ident);
9340             }
9341         }
9342     }
9343
9344     @Override
9345     public boolean removeTask(int taskId) {
9346         enforceCallingPermission(android.Manifest.permission.REMOVE_TASKS, "removeTask()");
9347         synchronized (this) {
9348             final long ident = Binder.clearCallingIdentity();
9349             try {
9350                 return removeTaskByIdLocked(taskId, true, REMOVE_FROM_RECENTS);
9351             } finally {
9352                 Binder.restoreCallingIdentity(ident);
9353             }
9354         }
9355     }
9356
9357     /**
9358      * TODO: Add mController hook
9359      */
9360     @Override
9361     public void moveTaskToFront(int taskId, int flags, Bundle bOptions) {
9362         enforceCallingPermission(android.Manifest.permission.REORDER_TASKS, "moveTaskToFront()");
9363
9364         if (DEBUG_STACK) Slog.d(TAG_STACK, "moveTaskToFront: moving taskId=" + taskId);
9365         synchronized(this) {
9366             moveTaskToFrontLocked(taskId, flags, bOptions);
9367         }
9368     }
9369
9370     void moveTaskToFrontLocked(int taskId, int flags, Bundle bOptions) {
9371         ActivityOptions options = ActivityOptions.fromBundle(bOptions);
9372
9373         if (!checkAppSwitchAllowedLocked(Binder.getCallingPid(),
9374                 Binder.getCallingUid(), -1, -1, "Task to front")) {
9375             ActivityOptions.abort(options);
9376             return;
9377         }
9378         final long origId = Binder.clearCallingIdentity();
9379         try {
9380             final TaskRecord task = mStackSupervisor.anyTaskForIdLocked(taskId);
9381             if (task == null) {
9382                 Slog.d(TAG, "Could not find task for id: "+ taskId);
9383                 return;
9384             }
9385             if (mStackSupervisor.isLockTaskModeViolation(task)) {
9386                 mStackSupervisor.showLockTaskToast();
9387                 Slog.e(TAG, "moveTaskToFront: Attempt to violate Lock Task Mode");
9388                 return;
9389             }
9390             final ActivityRecord prev = mStackSupervisor.topRunningActivityLocked();
9391             if (prev != null && prev.isRecentsActivity()) {
9392                 task.setTaskToReturnTo(ActivityRecord.RECENTS_ACTIVITY_TYPE);
9393             }
9394             mStackSupervisor.findTaskToMoveToFrontLocked(task, flags, options, "moveTaskToFront");
9395         } finally {
9396             Binder.restoreCallingIdentity(origId);
9397         }
9398         ActivityOptions.abort(options);
9399     }
9400
9401     /**
9402      * Moves an activity, and all of the other activities within the same task, to the bottom
9403      * of the history stack.  The activity's order within the task is unchanged.
9404      *
9405      * @param token A reference to the activity we wish to move
9406      * @param nonRoot If false then this only works if the activity is the root
9407      *                of a task; if true it will work for any activity in a task.
9408      * @return Returns true if the move completed, false if not.
9409      */
9410     @Override
9411     public boolean moveActivityTaskToBack(IBinder token, boolean nonRoot) {
9412         enforceNotIsolatedCaller("moveActivityTaskToBack");
9413         synchronized(this) {
9414             final long origId = Binder.clearCallingIdentity();
9415             try {
9416                 int taskId = ActivityRecord.getTaskForActivityLocked(token, !nonRoot);
9417                 final TaskRecord task = mStackSupervisor.anyTaskForIdLocked(taskId);
9418                 if (task != null) {
9419                     if (mStackSupervisor.isLockedTask(task)) {
9420                         mStackSupervisor.showLockTaskToast();
9421                         return false;
9422                     }
9423                     return ActivityRecord.getStackLocked(token).moveTaskToBackLocked(taskId);
9424                 }
9425             } finally {
9426                 Binder.restoreCallingIdentity(origId);
9427             }
9428         }
9429         return false;
9430     }
9431
9432     @Override
9433     public void moveTaskBackwards(int task) {
9434         enforceCallingPermission(android.Manifest.permission.REORDER_TASKS,
9435                 "moveTaskBackwards()");
9436
9437         synchronized(this) {
9438             if (!checkAppSwitchAllowedLocked(Binder.getCallingPid(),
9439                     Binder.getCallingUid(), -1, -1, "Task backwards")) {
9440                 return;
9441             }
9442             final long origId = Binder.clearCallingIdentity();
9443             moveTaskBackwardsLocked(task);
9444             Binder.restoreCallingIdentity(origId);
9445         }
9446     }
9447
9448     private final void moveTaskBackwardsLocked(int task) {
9449         Slog.e(TAG, "moveTaskBackwards not yet implemented!");
9450     }
9451
9452     @Override
9453     public IActivityContainer createVirtualActivityContainer(IBinder parentActivityToken,
9454             IActivityContainerCallback callback) throws RemoteException {
9455         enforceCallingPermission(MANAGE_ACTIVITY_STACKS, "createActivityContainer()");
9456         synchronized (this) {
9457             if (parentActivityToken == null) {
9458                 throw new IllegalArgumentException("parent token must not be null");
9459             }
9460             ActivityRecord r = ActivityRecord.forTokenLocked(parentActivityToken);
9461             if (r == null) {
9462                 return null;
9463             }
9464             if (callback == null) {
9465                 throw new IllegalArgumentException("callback must not be null");
9466             }
9467             return mStackSupervisor.createVirtualActivityContainer(r, callback);
9468         }
9469     }
9470
9471     @Override
9472     public void deleteActivityContainer(IActivityContainer container) throws RemoteException {
9473         enforceCallingPermission(MANAGE_ACTIVITY_STACKS, "deleteActivityContainer()");
9474         synchronized (this) {
9475             mStackSupervisor.deleteActivityContainer(container);
9476         }
9477     }
9478
9479     @Override
9480     public IActivityContainer createStackOnDisplay(int displayId) throws RemoteException {
9481         enforceCallingPermission(MANAGE_ACTIVITY_STACKS, "createStackOnDisplay()");
9482         synchronized (this) {
9483             final int stackId = mStackSupervisor.getNextStackId();
9484             final ActivityStack stack =
9485                     mStackSupervisor.createStackOnDisplay(stackId, displayId, true /*onTop*/);
9486             if (stack == null) {
9487                 return null;
9488             }
9489             return stack.mActivityContainer;
9490         }
9491     }
9492
9493     @Override
9494     public int getActivityDisplayId(IBinder activityToken) throws RemoteException {
9495         synchronized (this) {
9496             ActivityStack stack = ActivityRecord.getStackLocked(activityToken);
9497             if (stack != null && stack.mActivityContainer.isAttachedLocked()) {
9498                 return stack.mActivityContainer.getDisplayId();
9499             }
9500             return Display.DEFAULT_DISPLAY;
9501         }
9502     }
9503
9504     @Override
9505     public int getActivityStackId(IBinder token) throws RemoteException {
9506         synchronized (this) {
9507             ActivityStack stack = ActivityRecord.getStackLocked(token);
9508             if (stack == null) {
9509                 return INVALID_STACK_ID;
9510             }
9511             return stack.mStackId;
9512         }
9513     }
9514
9515     @Override
9516     public void exitFreeformMode(IBinder token) throws RemoteException {
9517         synchronized (this) {
9518             long ident = Binder.clearCallingIdentity();
9519             try {
9520                 final ActivityRecord r = ActivityRecord.forTokenLocked(token);
9521                 if (r == null) {
9522                     throw new IllegalArgumentException(
9523                             "exitFreeformMode: No activity record matching token=" + token);
9524                 }
9525                 final ActivityStack stack = r.getStackLocked(token);
9526                 if (stack == null || stack.mStackId != FREEFORM_WORKSPACE_STACK_ID) {
9527                     throw new IllegalStateException(
9528                             "exitFreeformMode: You can only go fullscreen from freeform.");
9529                 }
9530                 if (DEBUG_STACK) Slog.d(TAG_STACK, "exitFreeformMode: " + r);
9531                 mStackSupervisor.moveTaskToStackLocked(r.task.taskId, FULLSCREEN_WORKSPACE_STACK_ID,
9532                         ON_TOP, !FORCE_FOCUS, "exitFreeformMode", ANIMATE);
9533             } finally {
9534                 Binder.restoreCallingIdentity(ident);
9535             }
9536         }
9537     }
9538
9539     @Override
9540     public void moveTaskToStack(int taskId, int stackId, boolean toTop) {
9541         enforceCallingPermission(MANAGE_ACTIVITY_STACKS, "moveTaskToStack()");
9542         if (stackId == HOME_STACK_ID) {
9543             throw new IllegalArgumentException(
9544                     "moveTaskToStack: Attempt to move task " + taskId + " to home stack");
9545         }
9546         synchronized (this) {
9547             long ident = Binder.clearCallingIdentity();
9548             try {
9549                 if (DEBUG_STACK) Slog.d(TAG_STACK, "moveTaskToStack: moving task=" + taskId
9550                         + " to stackId=" + stackId + " toTop=" + toTop);
9551                 if (stackId == DOCKED_STACK_ID) {
9552                     mWindowManager.setDockedStackCreateState(DOCKED_STACK_CREATE_MODE_TOP_OR_LEFT,
9553                             null /* initialBounds */);
9554                 }
9555                 mStackSupervisor.moveTaskToStackLocked(taskId, stackId, toTop, !FORCE_FOCUS,
9556                         "moveTaskToStack", ANIMATE);
9557             } finally {
9558                 Binder.restoreCallingIdentity(ident);
9559             }
9560         }
9561     }
9562
9563     @Override
9564     public void swapDockedAndFullscreenStack() throws RemoteException {
9565         enforceCallingPermission(MANAGE_ACTIVITY_STACKS, "swapDockedAndFullscreenStack()");
9566         synchronized (this) {
9567             long ident = Binder.clearCallingIdentity();
9568             try {
9569                 final ActivityStack fullscreenStack = mStackSupervisor.getStack(
9570                         FULLSCREEN_WORKSPACE_STACK_ID);
9571                 final TaskRecord topTask = fullscreenStack != null ? fullscreenStack.topTask()
9572                         : null;
9573                 final ActivityStack dockedStack = mStackSupervisor.getStack(DOCKED_STACK_ID);
9574                 final ArrayList<TaskRecord> tasks = dockedStack != null ? dockedStack.getAllTasks()
9575                         : null;
9576                 if (topTask == null || tasks == null || tasks.size() == 0) {
9577                     Slog.w(TAG,
9578                             "Unable to swap tasks, either docked or fullscreen stack is empty.");
9579                     return;
9580                 }
9581
9582                 // TODO: App transition
9583                 mWindowManager.prepareAppTransition(TRANSIT_ACTIVITY_RELAUNCH, false);
9584
9585                 // Defer the resume so resume/pausing while moving stacks is dangerous.
9586                 mStackSupervisor.moveTaskToStackLocked(topTask.taskId, DOCKED_STACK_ID,
9587                         false /* toTop */, !FORCE_FOCUS, "swapDockedAndFullscreenStack",
9588                         ANIMATE, true /* deferResume */);
9589                 final int size = tasks.size();
9590                 for (int i = 0; i < size; i++) {
9591                     final int id = tasks.get(i).taskId;
9592                     if (id == topTask.taskId) {
9593                         continue;
9594                     }
9595                     mStackSupervisor.moveTaskToStackLocked(id,
9596                             FULLSCREEN_WORKSPACE_STACK_ID, true /* toTop */, !FORCE_FOCUS,
9597                             "swapDockedAndFullscreenStack", ANIMATE, true /* deferResume */);
9598                 }
9599
9600                 // Because we deferred the resume, to avoid conflicts with stack switches while
9601                 // resuming, we need to do it after all the tasks are moved.
9602                 mStackSupervisor.ensureActivitiesVisibleLocked(null, 0, !PRESERVE_WINDOWS);
9603                 mStackSupervisor.resumeFocusedStackTopActivityLocked();
9604
9605                 mWindowManager.executeAppTransition();
9606             } finally {
9607                 Binder.restoreCallingIdentity(ident);
9608             }
9609         }
9610     }
9611
9612     /**
9613      * Moves the input task to the docked stack.
9614      *
9615      * @param taskId Id of task to move.
9616      * @param createMode The mode the docked stack should be created in if it doesn't exist
9617      *                   already. See
9618      *                   {@link android.app.ActivityManager#DOCKED_STACK_CREATE_MODE_TOP_OR_LEFT}
9619      *                   and
9620      *                   {@link android.app.ActivityManager#DOCKED_STACK_CREATE_MODE_BOTTOM_OR_RIGHT}
9621      * @param toTop If the task and stack should be moved to the top.
9622      * @param animate Whether we should play an animation for the moving the task
9623      * @param initialBounds If the docked stack gets created, it will use these bounds for the
9624      *                      docked stack. Pass {@code null} to use default bounds.
9625      */
9626     @Override
9627     public boolean moveTaskToDockedStack(int taskId, int createMode, boolean toTop, boolean animate,
9628             Rect initialBounds) {
9629         enforceCallingPermission(MANAGE_ACTIVITY_STACKS, "moveTaskToDockedStack()");
9630         synchronized (this) {
9631             long ident = Binder.clearCallingIdentity();
9632             try {
9633                 if (DEBUG_STACK) Slog.d(TAG_STACK, "moveTaskToDockedStack: moving task=" + taskId
9634                         + " to createMode=" + createMode + " toTop=" + toTop);
9635                 mWindowManager.setDockedStackCreateState(createMode, initialBounds);
9636                 return mStackSupervisor.moveTaskToStackLocked(
9637                         taskId, DOCKED_STACK_ID, toTop, !FORCE_FOCUS,
9638                         "moveTaskToDockedStack", animate);
9639             } finally {
9640                 Binder.restoreCallingIdentity(ident);
9641             }
9642         }
9643     }
9644
9645     /**
9646      * Moves the top activity in the input stackId to the pinned stack.
9647      *
9648      * @param stackId Id of stack to move the top activity to pinned stack.
9649      * @param bounds Bounds to use for pinned stack.
9650      *
9651      * @return True if the top activity of the input stack was successfully moved to the pinned
9652      *          stack.
9653      */
9654     @Override
9655     public boolean moveTopActivityToPinnedStack(int stackId, Rect bounds) {
9656         enforceCallingPermission(MANAGE_ACTIVITY_STACKS, "moveTopActivityToPinnedStack()");
9657         synchronized (this) {
9658             if (!mSupportsPictureInPicture) {
9659                 throw new IllegalStateException("moveTopActivityToPinnedStack:"
9660                         + "Device doesn't support picture-in-pciture mode");
9661             }
9662
9663             long ident = Binder.clearCallingIdentity();
9664             try {
9665                 return mStackSupervisor.moveTopStackActivityToPinnedStackLocked(stackId, bounds);
9666             } finally {
9667                 Binder.restoreCallingIdentity(ident);
9668             }
9669         }
9670     }
9671
9672     @Override
9673     public void resizeStack(int stackId, Rect bounds, boolean allowResizeInDockedMode,
9674             boolean preserveWindows, boolean animate) {
9675         enforceCallingPermission(MANAGE_ACTIVITY_STACKS, "resizeStack()");
9676         long ident = Binder.clearCallingIdentity();
9677         try {
9678             synchronized (this) {
9679                 if (animate) {
9680                     if (stackId == PINNED_STACK_ID) {
9681                         mWindowManager.animateResizePinnedStack(bounds);
9682                     } else {
9683                         throw new IllegalArgumentException("Stack: " + stackId
9684                                 + " doesn't support animated resize.");
9685                     }
9686                 } else {
9687                     mStackSupervisor.resizeStackLocked(stackId, bounds, null /* tempTaskBounds */,
9688                             null /* tempTaskInsetBounds */, preserveWindows,
9689                             allowResizeInDockedMode);
9690                 }
9691             }
9692         } finally {
9693             Binder.restoreCallingIdentity(ident);
9694         }
9695     }
9696
9697     @Override
9698     public void resizeDockedStack(Rect dockedBounds, Rect tempDockedTaskBounds,
9699             Rect tempDockedTaskInsetBounds,
9700             Rect tempOtherTaskBounds, Rect tempOtherTaskInsetBounds) {
9701         enforceCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS,
9702                 "resizeDockedStack()");
9703         long ident = Binder.clearCallingIdentity();
9704         try {
9705             synchronized (this) {
9706                 mStackSupervisor.resizeDockedStackLocked(dockedBounds, tempDockedTaskBounds,
9707                         tempDockedTaskInsetBounds, tempOtherTaskBounds, tempOtherTaskInsetBounds,
9708                         PRESERVE_WINDOWS);
9709             }
9710         } finally {
9711             Binder.restoreCallingIdentity(ident);
9712         }
9713     }
9714
9715     @Override
9716     public void resizePinnedStack(Rect pinnedBounds, Rect tempPinnedTaskBounds) {
9717         enforceCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS,
9718                 "resizePinnedStack()");
9719         final long ident = Binder.clearCallingIdentity();
9720         try {
9721             synchronized (this) {
9722                 mStackSupervisor.resizePinnedStackLocked(pinnedBounds, tempPinnedTaskBounds);
9723             }
9724         } finally {
9725             Binder.restoreCallingIdentity(ident);
9726         }
9727     }
9728
9729     @Override
9730     public void positionTaskInStack(int taskId, int stackId, int position) {
9731         enforceCallingPermission(MANAGE_ACTIVITY_STACKS, "positionTaskInStack()");
9732         if (stackId == HOME_STACK_ID) {
9733             throw new IllegalArgumentException(
9734                     "positionTaskInStack: Attempt to change the position of task "
9735                     + taskId + " in/to home stack");
9736         }
9737         synchronized (this) {
9738             long ident = Binder.clearCallingIdentity();
9739             try {
9740                 if (DEBUG_STACK) Slog.d(TAG_STACK,
9741                         "positionTaskInStack: positioning task=" + taskId
9742                         + " in stackId=" + stackId + " at position=" + position);
9743                 mStackSupervisor.positionTaskInStackLocked(taskId, stackId, position);
9744             } finally {
9745                 Binder.restoreCallingIdentity(ident);
9746             }
9747         }
9748     }
9749
9750     @Override
9751     public List<StackInfo> getAllStackInfos() {
9752         enforceCallingPermission(MANAGE_ACTIVITY_STACKS, "getAllStackInfos()");
9753         long ident = Binder.clearCallingIdentity();
9754         try {
9755             synchronized (this) {
9756                 return mStackSupervisor.getAllStackInfosLocked();
9757             }
9758         } finally {
9759             Binder.restoreCallingIdentity(ident);
9760         }
9761     }
9762
9763     @Override
9764     public StackInfo getStackInfo(int stackId) {
9765         enforceCallingPermission(MANAGE_ACTIVITY_STACKS, "getStackInfo()");
9766         long ident = Binder.clearCallingIdentity();
9767         try {
9768             synchronized (this) {
9769                 return mStackSupervisor.getStackInfoLocked(stackId);
9770             }
9771         } finally {
9772             Binder.restoreCallingIdentity(ident);
9773         }
9774     }
9775
9776     @Override
9777     public boolean isInHomeStack(int taskId) {
9778         enforceCallingPermission(MANAGE_ACTIVITY_STACKS, "getStackInfo()");
9779         long ident = Binder.clearCallingIdentity();
9780         try {
9781             synchronized (this) {
9782                 final TaskRecord tr = mStackSupervisor.anyTaskForIdLocked(
9783                         taskId, !RESTORE_FROM_RECENTS, INVALID_STACK_ID);
9784                 return tr != null && tr.stack != null && tr.stack.isHomeStack();
9785             }
9786         } finally {
9787             Binder.restoreCallingIdentity(ident);
9788         }
9789     }
9790
9791     @Override
9792     public int getTaskForActivity(IBinder token, boolean onlyRoot) {
9793         synchronized(this) {
9794             return ActivityRecord.getTaskForActivityLocked(token, onlyRoot);
9795         }
9796     }
9797
9798     @Override
9799     public void updateDeviceOwner(String packageName) {
9800         final int callingUid = Binder.getCallingUid();
9801         if (callingUid != 0 && callingUid != Process.SYSTEM_UID) {
9802             throw new SecurityException("updateDeviceOwner called from non-system process");
9803         }
9804         synchronized (this) {
9805             mDeviceOwnerName = packageName;
9806         }
9807     }
9808
9809     @Override
9810     public void updateLockTaskPackages(int userId, String[] packages) {
9811         final int callingUid = Binder.getCallingUid();
9812         if (callingUid != 0 && callingUid != Process.SYSTEM_UID) {
9813             throw new SecurityException("updateLockTaskPackage called from non-system process");
9814         }
9815         synchronized (this) {
9816             if (DEBUG_LOCKTASK) Slog.w(TAG_LOCKTASK, "Whitelisting " + userId + ":" +
9817                     Arrays.toString(packages));
9818             mLockTaskPackages.put(userId, packages);
9819             mStackSupervisor.onLockTaskPackagesUpdatedLocked();
9820         }
9821     }
9822
9823
9824     void startLockTaskModeLocked(TaskRecord task) {
9825         if (DEBUG_LOCKTASK) Slog.w(TAG_LOCKTASK, "startLockTaskModeLocked: " + task);
9826         if (task.mLockTaskAuth == LOCK_TASK_AUTH_DONT_LOCK) {
9827             return;
9828         }
9829
9830         // isSystemInitiated is used to distinguish between locked and pinned mode, as pinned mode
9831         // is initiated by system after the pinning request was shown and locked mode is initiated
9832         // by an authorized app directly
9833         final int callingUid = Binder.getCallingUid();
9834         boolean isSystemInitiated = callingUid == Process.SYSTEM_UID;
9835         long ident = Binder.clearCallingIdentity();
9836         try {
9837             final ActivityStack stack = mStackSupervisor.getFocusedStack();
9838             if (!isSystemInitiated) {
9839                 task.mLockTaskUid = callingUid;
9840                 if (task.mLockTaskAuth == LOCK_TASK_AUTH_PINNABLE) {
9841                     // startLockTask() called by app and task mode is lockTaskModeDefault.
9842                     if (DEBUG_LOCKTASK) Slog.w(TAG_LOCKTASK, "Mode default, asking user");
9843                     StatusBarManagerInternal statusBarManager =
9844                             LocalServices.getService(StatusBarManagerInternal.class);
9845                     if (statusBarManager != null) {
9846                         statusBarManager.showScreenPinningRequest();
9847                     }
9848                     return;
9849                 }
9850
9851                 if (stack == null || task != stack.topTask()) {
9852                     throw new IllegalArgumentException("Invalid task, not in foreground");
9853                 }
9854             }
9855             if (DEBUG_LOCKTASK) Slog.w(TAG_LOCKTASK, isSystemInitiated ? "Locking pinned" :
9856                     "Locking fully");
9857             mStackSupervisor.setLockTaskModeLocked(task, isSystemInitiated ?
9858                     ActivityManager.LOCK_TASK_MODE_PINNED :
9859                     ActivityManager.LOCK_TASK_MODE_LOCKED,
9860                     "startLockTask", true);
9861         } finally {
9862             Binder.restoreCallingIdentity(ident);
9863         }
9864     }
9865
9866     @Override
9867     public void startLockTaskMode(int taskId) {
9868         synchronized (this) {
9869             final TaskRecord task = mStackSupervisor.anyTaskForIdLocked(taskId);
9870             if (task != null) {
9871                 startLockTaskModeLocked(task);
9872             }
9873         }
9874     }
9875
9876     @Override
9877     public void startLockTaskMode(IBinder token) {
9878         synchronized (this) {
9879             final ActivityRecord r = ActivityRecord.forTokenLocked(token);
9880             if (r == null) {
9881                 return;
9882             }
9883             final TaskRecord task = r.task;
9884             if (task != null) {
9885                 startLockTaskModeLocked(task);
9886             }
9887         }
9888     }
9889
9890     @Override
9891     public void startLockTaskModeOnCurrent() throws RemoteException {
9892         enforceCallingPermission(MANAGE_ACTIVITY_STACKS, "startLockTaskModeOnCurrent");
9893         long ident = Binder.clearCallingIdentity();
9894         try {
9895             synchronized (this) {
9896                 ActivityRecord r = mStackSupervisor.topRunningActivityLocked();
9897                 if (r != null) {
9898                     startLockTaskModeLocked(r.task);
9899                 }
9900             }
9901         } finally {
9902             Binder.restoreCallingIdentity(ident);
9903         }
9904     }
9905
9906     @Override
9907     public void stopLockTaskMode() {
9908         final TaskRecord lockTask = mStackSupervisor.getLockedTaskLocked();
9909         if (lockTask == null) {
9910             // Our work here is done.
9911             return;
9912         }
9913
9914         final int callingUid = Binder.getCallingUid();
9915         final int lockTaskUid = lockTask.mLockTaskUid;
9916         // Ensure the same caller for startLockTaskMode and stopLockTaskMode.
9917         // It is possible lockTaskMode was started by the system process because
9918         // android:lockTaskMode is set to a locking value in the application manifest instead of
9919         // the app calling startLockTaskMode. In this case {@link TaskRecord.mLockTaskUid} will
9920         // be 0, so we compare the callingUid to the {@link TaskRecord.effectiveUid} instead.
9921         if (getLockTaskModeState() == ActivityManager.LOCK_TASK_MODE_LOCKED &&
9922                 callingUid != lockTaskUid
9923                 && (lockTaskUid != 0
9924                     || (lockTaskUid == 0 && callingUid != lockTask.effectiveUid))) {
9925             throw new SecurityException("Invalid uid, expected " + lockTaskUid
9926                     + " callingUid=" + callingUid + " effectiveUid=" + lockTask.effectiveUid);
9927         }
9928
9929         long ident = Binder.clearCallingIdentity();
9930         try {
9931             Log.d(TAG, "stopLockTaskMode");
9932             // Stop lock task
9933             synchronized (this) {
9934                 mStackSupervisor.setLockTaskModeLocked(null, ActivityManager.LOCK_TASK_MODE_NONE,
9935                         "stopLockTask", true);
9936             }
9937         } finally {
9938             Binder.restoreCallingIdentity(ident);
9939         }
9940     }
9941
9942     @Override
9943     public void stopLockTaskModeOnCurrent() throws RemoteException {
9944         enforceCallingPermission(MANAGE_ACTIVITY_STACKS, "stopLockTaskModeOnCurrent");
9945         long ident = Binder.clearCallingIdentity();
9946         try {
9947             stopLockTaskMode();
9948         } finally {
9949             Binder.restoreCallingIdentity(ident);
9950         }
9951     }
9952
9953     @Override
9954     public boolean isInLockTaskMode() {
9955         return getLockTaskModeState() != ActivityManager.LOCK_TASK_MODE_NONE;
9956     }
9957
9958     @Override
9959     public int getLockTaskModeState() {
9960         synchronized (this) {
9961             return mStackSupervisor.getLockTaskModeState();
9962         }
9963     }
9964
9965     @Override
9966     public void showLockTaskEscapeMessage(IBinder token) {
9967         synchronized (this) {
9968             final ActivityRecord r = ActivityRecord.forTokenLocked(token);
9969             if (r == null) {
9970                 return;
9971             }
9972             mStackSupervisor.showLockTaskEscapeMessageLocked(r.task);
9973         }
9974     }
9975
9976     // =========================================================
9977     // CONTENT PROVIDERS
9978     // =========================================================
9979
9980     private final List<ProviderInfo> generateApplicationProvidersLocked(ProcessRecord app) {
9981         List<ProviderInfo> providers = null;
9982         try {
9983             providers = AppGlobals.getPackageManager()
9984                     .queryContentProviders(app.processName, app.uid,
9985                             STOCK_PM_FLAGS | PackageManager.GET_URI_PERMISSION_PATTERNS
9986                                     | MATCH_DEBUG_TRIAGED_MISSING)
9987                     .getList();
9988         } catch (RemoteException ex) {
9989         }
9990         if (DEBUG_MU) Slog.v(TAG_MU,
9991                 "generateApplicationProvidersLocked, app.info.uid = " + app.uid);
9992         int userId = app.userId;
9993         if (providers != null) {
9994             int N = providers.size();
9995             app.pubProviders.ensureCapacity(N + app.pubProviders.size());
9996             for (int i=0; i<N; i++) {
9997                 ProviderInfo cpi =
9998                     (ProviderInfo)providers.get(i);
9999                 boolean singleton = isSingleton(cpi.processName, cpi.applicationInfo,
10000                         cpi.name, cpi.flags);
10001                 if (singleton && UserHandle.getUserId(app.uid) != UserHandle.USER_SYSTEM) {
10002                     // This is a singleton provider, but a user besides the
10003                     // default user is asking to initialize a process it runs
10004                     // in...  well, no, it doesn't actually run in this process,
10005                     // it runs in the process of the default user.  Get rid of it.
10006                     providers.remove(i);
10007                     N--;
10008                     i--;
10009                     continue;
10010                 }
10011
10012                 ComponentName comp = new ComponentName(cpi.packageName, cpi.name);
10013                 ContentProviderRecord cpr = mProviderMap.getProviderByClass(comp, userId);
10014                 if (cpr == null) {
10015                     cpr = new ContentProviderRecord(this, cpi, app.info, comp, singleton);
10016                     mProviderMap.putProviderByClass(comp, cpr);
10017                 }
10018                 if (DEBUG_MU) Slog.v(TAG_MU,
10019                         "generateApplicationProvidersLocked, cpi.uid = " + cpr.uid);
10020                 app.pubProviders.put(cpi.name, cpr);
10021                 if (!cpi.multiprocess || !"android".equals(cpi.packageName)) {
10022                     // Don't add this if it is a platform component that is marked
10023                     // to run in multiple processes, because this is actually
10024                     // part of the framework so doesn't make sense to track as a
10025                     // separate apk in the process.
10026                     app.addPackage(cpi.applicationInfo.packageName, cpi.applicationInfo.versionCode,
10027                             mProcessStats);
10028                 }
10029                 notifyPackageUse(cpi.applicationInfo.packageName);
10030             }
10031         }
10032         return providers;
10033     }
10034
10035     /**
10036      * Check if {@link ProcessRecord} has a possible chance at accessing the
10037      * given {@link ProviderInfo}. Final permission checking is always done
10038      * in {@link ContentProvider}.
10039      */
10040     private final String checkContentProviderPermissionLocked(
10041             ProviderInfo cpi, ProcessRecord r, int userId, boolean checkUser) {
10042         final int callingPid = (r != null) ? r.pid : Binder.getCallingPid();
10043         final int callingUid = (r != null) ? r.uid : Binder.getCallingUid();
10044         boolean checkedGrants = false;
10045         if (checkUser) {
10046             // Looking for cross-user grants before enforcing the typical cross-users permissions
10047             int tmpTargetUserId = mUserController.unsafeConvertIncomingUserLocked(userId);
10048             if (tmpTargetUserId != UserHandle.getUserId(callingUid)) {
10049                 if (checkAuthorityGrants(callingUid, cpi, tmpTargetUserId, checkUser)) {
10050                     return null;
10051                 }
10052                 checkedGrants = true;
10053             }
10054             userId = mUserController.handleIncomingUser(callingPid, callingUid, userId, false,
10055                     ALLOW_NON_FULL, "checkContentProviderPermissionLocked " + cpi.authority, null);
10056             if (userId != tmpTargetUserId) {
10057                 // When we actually went to determine the final targer user ID, this ended
10058                 // up different than our initial check for the authority.  This is because
10059                 // they had asked for USER_CURRENT_OR_SELF and we ended up switching to
10060                 // SELF.  So we need to re-check the grants again.
10061                 checkedGrants = false;
10062             }
10063         }
10064         if (checkComponentPermission(cpi.readPermission, callingPid, callingUid,
10065                 cpi.applicationInfo.uid, cpi.exported)
10066                 == PackageManager.PERMISSION_GRANTED) {
10067             return null;
10068         }
10069         if (checkComponentPermission(cpi.writePermission, callingPid, callingUid,
10070                 cpi.applicationInfo.uid, cpi.exported)
10071                 == PackageManager.PERMISSION_GRANTED) {
10072             return null;
10073         }
10074
10075         PathPermission[] pps = cpi.pathPermissions;
10076         if (pps != null) {
10077             int i = pps.length;
10078             while (i > 0) {
10079                 i--;
10080                 PathPermission pp = pps[i];
10081                 String pprperm = pp.getReadPermission();
10082                 if (pprperm != null && checkComponentPermission(pprperm, callingPid, callingUid,
10083                         cpi.applicationInfo.uid, cpi.exported)
10084                         == PackageManager.PERMISSION_GRANTED) {
10085                     return null;
10086                 }
10087                 String ppwperm = pp.getWritePermission();
10088                 if (ppwperm != null && checkComponentPermission(ppwperm, callingPid, callingUid,
10089                         cpi.applicationInfo.uid, cpi.exported)
10090                         == PackageManager.PERMISSION_GRANTED) {
10091                     return null;
10092                 }
10093             }
10094         }
10095         if (!checkedGrants && checkAuthorityGrants(callingUid, cpi, userId, checkUser)) {
10096             return null;
10097         }
10098
10099         String msg;
10100         if (!cpi.exported) {
10101             msg = "Permission Denial: opening provider " + cpi.name
10102                     + " from " + (r != null ? r : "(null)") + " (pid=" + callingPid
10103                     + ", uid=" + callingUid + ") that is not exported from uid "
10104                     + cpi.applicationInfo.uid;
10105         } else {
10106             msg = "Permission Denial: opening provider " + cpi.name
10107                     + " from " + (r != null ? r : "(null)") + " (pid=" + callingPid
10108                     + ", uid=" + callingUid + ") requires "
10109                     + cpi.readPermission + " or " + cpi.writePermission;
10110         }
10111         Slog.w(TAG, msg);
10112         return msg;
10113     }
10114
10115     /**
10116      * Returns if the ContentProvider has granted a uri to callingUid
10117      */
10118     boolean checkAuthorityGrants(int callingUid, ProviderInfo cpi, int userId, boolean checkUser) {
10119         final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.get(callingUid);
10120         if (perms != null) {
10121             for (int i=perms.size()-1; i>=0; i--) {
10122                 GrantUri grantUri = perms.keyAt(i);
10123                 if (grantUri.sourceUserId == userId || !checkUser) {
10124                     if (matchesProvider(grantUri.uri, cpi)) {
10125                         return true;
10126                     }
10127                 }
10128             }
10129         }
10130         return false;
10131     }
10132
10133     /**
10134      * Returns true if the uri authority is one of the authorities specified in the provider.
10135      */
10136     boolean matchesProvider(Uri uri, ProviderInfo cpi) {
10137         String uriAuth = uri.getAuthority();
10138         String cpiAuth = cpi.authority;
10139         if (cpiAuth.indexOf(';') == -1) {
10140             return cpiAuth.equals(uriAuth);
10141         }
10142         String[] cpiAuths = cpiAuth.split(";");
10143         int length = cpiAuths.length;
10144         for (int i = 0; i < length; i++) {
10145             if (cpiAuths[i].equals(uriAuth)) return true;
10146         }
10147         return false;
10148     }
10149
10150     ContentProviderConnection incProviderCountLocked(ProcessRecord r,
10151             final ContentProviderRecord cpr, IBinder externalProcessToken, boolean stable) {
10152         if (r != null) {
10153             for (int i=0; i<r.conProviders.size(); i++) {
10154                 ContentProviderConnection conn = r.conProviders.get(i);
10155                 if (conn.provider == cpr) {
10156                     if (DEBUG_PROVIDER) Slog.v(TAG_PROVIDER,
10157                             "Adding provider requested by "
10158                             + r.processName + " from process "
10159                             + cpr.info.processName + ": " + cpr.name.flattenToShortString()
10160                             + " scnt=" + conn.stableCount + " uscnt=" + conn.unstableCount);
10161                     if (stable) {
10162                         conn.stableCount++;
10163                         conn.numStableIncs++;
10164                     } else {
10165                         conn.unstableCount++;
10166                         conn.numUnstableIncs++;
10167                     }
10168                     return conn;
10169                 }
10170             }
10171             ContentProviderConnection conn = new ContentProviderConnection(cpr, r);
10172             if (stable) {
10173                 conn.stableCount = 1;
10174                 conn.numStableIncs = 1;
10175             } else {
10176                 conn.unstableCount = 1;
10177                 conn.numUnstableIncs = 1;
10178             }
10179             cpr.connections.add(conn);
10180             r.conProviders.add(conn);
10181             startAssociationLocked(r.uid, r.processName, cpr.uid, cpr.name, cpr.info.processName);
10182             return conn;
10183         }
10184         cpr.addExternalProcessHandleLocked(externalProcessToken);
10185         return null;
10186     }
10187
10188     boolean decProviderCountLocked(ContentProviderConnection conn,
10189             ContentProviderRecord cpr, IBinder externalProcessToken, boolean stable) {
10190         if (conn != null) {
10191             cpr = conn.provider;
10192             if (DEBUG_PROVIDER) Slog.v(TAG_PROVIDER,
10193                     "Removing provider requested by "
10194                     + conn.client.processName + " from process "
10195                     + cpr.info.processName + ": " + cpr.name.flattenToShortString()
10196                     + " scnt=" + conn.stableCount + " uscnt=" + conn.unstableCount);
10197             if (stable) {
10198                 conn.stableCount--;
10199             } else {
10200                 conn.unstableCount--;
10201             }
10202             if (conn.stableCount == 0 && conn.unstableCount == 0) {
10203                 cpr.connections.remove(conn);
10204                 conn.client.conProviders.remove(conn);
10205                 if (conn.client.setProcState < ActivityManager.PROCESS_STATE_LAST_ACTIVITY) {
10206                     // The client is more important than last activity -- note the time this
10207                     // is happening, so we keep the old provider process around a bit as last
10208                     // activity to avoid thrashing it.
10209                     if (cpr.proc != null) {
10210                         cpr.proc.lastProviderTime = SystemClock.uptimeMillis();
10211                     }
10212                 }
10213                 stopAssociationLocked(conn.client.uid, conn.client.processName, cpr.uid, cpr.name);
10214                 return true;
10215             }
10216             return false;
10217         }
10218         cpr.removeExternalProcessHandleLocked(externalProcessToken);
10219         return false;
10220     }
10221
10222     private void checkTime(long startTime, String where) {
10223         long now = SystemClock.elapsedRealtime();
10224         if ((now-startTime) > 1000) {
10225             // If we are taking more than a second, log about it.
10226             Slog.w(TAG, "Slow operation: " + (now-startTime) + "ms so far, now at " + where);
10227         }
10228     }
10229
10230     private ContentProviderHolder getContentProviderImpl(IApplicationThread caller,
10231             String name, IBinder token, boolean stable, int userId) {
10232         ContentProviderRecord cpr;
10233         ContentProviderConnection conn = null;
10234         ProviderInfo cpi = null;
10235
10236         synchronized(this) {
10237             long startTime = SystemClock.elapsedRealtime();
10238
10239             ProcessRecord r = null;
10240             if (caller != null) {
10241                 r = getRecordForAppLocked(caller);
10242                 if (r == null) {
10243                     throw new SecurityException(
10244                             "Unable to find app for caller " + caller
10245                           + " (pid=" + Binder.getCallingPid()
10246                           + ") when getting content provider " + name);
10247                 }
10248             }
10249
10250             boolean checkCrossUser = true;
10251
10252             checkTime(startTime, "getContentProviderImpl: getProviderByName");
10253
10254             // First check if this content provider has been published...
10255             cpr = mProviderMap.getProviderByName(name, userId);
10256             // If that didn't work, check if it exists for user 0 and then
10257             // verify that it's a singleton provider before using it.
10258             if (cpr == null && userId != UserHandle.USER_SYSTEM) {
10259                 cpr = mProviderMap.getProviderByName(name, UserHandle.USER_SYSTEM);
10260                 if (cpr != null) {
10261                     cpi = cpr.info;
10262                     if (isSingleton(cpi.processName, cpi.applicationInfo,
10263                             cpi.name, cpi.flags)
10264                             && isValidSingletonCall(r.uid, cpi.applicationInfo.uid)) {
10265                         userId = UserHandle.USER_SYSTEM;
10266                         checkCrossUser = false;
10267                     } else {
10268                         cpr = null;
10269                         cpi = null;
10270                     }
10271                 }
10272             }
10273
10274             boolean providerRunning = cpr != null;
10275             if (providerRunning) {
10276                 cpi = cpr.info;
10277                 String msg;
10278                 checkTime(startTime, "getContentProviderImpl: before checkContentProviderPermission");
10279                 if ((msg = checkContentProviderPermissionLocked(cpi, r, userId, checkCrossUser))
10280                         != null) {
10281                     throw new SecurityException(msg);
10282                 }
10283                 checkTime(startTime, "getContentProviderImpl: after checkContentProviderPermission");
10284
10285                 if (r != null && cpr.canRunHere(r)) {
10286                     // This provider has been published or is in the process
10287                     // of being published...  but it is also allowed to run
10288                     // in the caller's process, so don't make a connection
10289                     // and just let the caller instantiate its own instance.
10290                     ContentProviderHolder holder = cpr.newHolder(null);
10291                     // don't give caller the provider object, it needs
10292                     // to make its own.
10293                     holder.provider = null;
10294                     return holder;
10295                 }
10296
10297                 final long origId = Binder.clearCallingIdentity();
10298
10299                 checkTime(startTime, "getContentProviderImpl: incProviderCountLocked");
10300
10301                 // In this case the provider instance already exists, so we can
10302                 // return it right away.
10303                 conn = incProviderCountLocked(r, cpr, token, stable);
10304                 if (conn != null && (conn.stableCount+conn.unstableCount) == 1) {
10305                     if (cpr.proc != null && r.setAdj <= ProcessList.PERCEPTIBLE_APP_ADJ) {
10306                         // If this is a perceptible app accessing the provider,
10307                         // make sure to count it as being accessed and thus
10308                         // back up on the LRU list.  This is good because
10309                         // content providers are often expensive to start.
10310                         checkTime(startTime, "getContentProviderImpl: before updateLruProcess");
10311                         updateLruProcessLocked(cpr.proc, false, null);
10312                         checkTime(startTime, "getContentProviderImpl: after updateLruProcess");
10313                     }
10314                 }
10315
10316                 if (cpr.proc != null) {
10317                     checkTime(startTime, "getContentProviderImpl: before updateOomAdj");
10318                     boolean success = updateOomAdjLocked(cpr.proc);
10319                     maybeUpdateProviderUsageStatsLocked(r, cpr.info.packageName, name);
10320                     checkTime(startTime, "getContentProviderImpl: after updateOomAdj");
10321                     if (DEBUG_PROVIDER) Slog.i(TAG_PROVIDER, "Adjust success: " + success);
10322                     // NOTE: there is still a race here where a signal could be
10323                     // pending on the process even though we managed to update its
10324                     // adj level.  Not sure what to do about this, but at least
10325                     // the race is now smaller.
10326                     if (!success) {
10327                         // Uh oh...  it looks like the provider's process
10328                         // has been killed on us.  We need to wait for a new
10329                         // process to be started, and make sure its death
10330                         // doesn't kill our process.
10331                         Slog.i(TAG, "Existing provider " + cpr.name.flattenToShortString()
10332                                 + " is crashing; detaching " + r);
10333                         boolean lastRef = decProviderCountLocked(conn, cpr, token, stable);
10334                         checkTime(startTime, "getContentProviderImpl: before appDied");
10335                         appDiedLocked(cpr.proc);
10336                         checkTime(startTime, "getContentProviderImpl: after appDied");
10337                         if (!lastRef) {
10338                             // This wasn't the last ref our process had on
10339                             // the provider...  we have now been killed, bail.
10340                             return null;
10341                         }
10342                         providerRunning = false;
10343                         conn = null;
10344                     }
10345                 }
10346
10347                 Binder.restoreCallingIdentity(origId);
10348             }
10349
10350             if (!providerRunning) {
10351                 try {
10352                     checkTime(startTime, "getContentProviderImpl: before resolveContentProvider");
10353                     cpi = AppGlobals.getPackageManager().
10354                         resolveContentProvider(name,
10355                             STOCK_PM_FLAGS | PackageManager.GET_URI_PERMISSION_PATTERNS, userId);
10356                     checkTime(startTime, "getContentProviderImpl: after resolveContentProvider");
10357                 } catch (RemoteException ex) {
10358                 }
10359                 if (cpi == null) {
10360                     return null;
10361                 }
10362                 // If the provider is a singleton AND
10363                 // (it's a call within the same user || the provider is a
10364                 // privileged app)
10365                 // Then allow connecting to the singleton provider
10366                 boolean singleton = isSingleton(cpi.processName, cpi.applicationInfo,
10367                         cpi.name, cpi.flags)
10368                         && isValidSingletonCall(r.uid, cpi.applicationInfo.uid);
10369                 if (singleton) {
10370                     userId = UserHandle.USER_SYSTEM;
10371                 }
10372                 cpi.applicationInfo = getAppInfoForUser(cpi.applicationInfo, userId);
10373                 checkTime(startTime, "getContentProviderImpl: got app info for user");
10374
10375                 String msg;
10376                 checkTime(startTime, "getContentProviderImpl: before checkContentProviderPermission");
10377                 if ((msg = checkContentProviderPermissionLocked(cpi, r, userId, !singleton))
10378                         != null) {
10379                     throw new SecurityException(msg);
10380                 }
10381                 checkTime(startTime, "getContentProviderImpl: after checkContentProviderPermission");
10382
10383                 if (!mProcessesReady && !mDidUpdate && !mWaitingUpdate
10384                         && !cpi.processName.equals("system")) {
10385                     // If this content provider does not run in the system
10386                     // process, and the system is not yet ready to run other
10387                     // processes, then fail fast instead of hanging.
10388                     throw new IllegalArgumentException(
10389                             "Attempt to launch content provider before system ready");
10390                 }
10391
10392                 // Make sure that the user who owns this provider is running.  If not,
10393                 // we don't want to allow it to run.
10394                 if (!mUserController.isUserRunningLocked(userId, 0)) {
10395                     Slog.w(TAG, "Unable to launch app "
10396                             + cpi.applicationInfo.packageName + "/"
10397                             + cpi.applicationInfo.uid + " for provider "
10398                             + name + ": user " + userId + " is stopped");
10399                     return null;
10400                 }
10401
10402                 ComponentName comp = new ComponentName(cpi.packageName, cpi.name);
10403                 checkTime(startTime, "getContentProviderImpl: before getProviderByClass");
10404                 cpr = mProviderMap.getProviderByClass(comp, userId);
10405                 checkTime(startTime, "getContentProviderImpl: after getProviderByClass");
10406                 final boolean firstClass = cpr == null;
10407                 if (firstClass) {
10408                     final long ident = Binder.clearCallingIdentity();
10409
10410                     // If permissions need a review before any of the app components can run,
10411                     // we return no provider and launch a review activity if the calling app
10412                     // is in the foreground.
10413                     if (Build.PERMISSIONS_REVIEW_REQUIRED) {
10414                         if (!requestTargetProviderPermissionsReviewIfNeededLocked(cpi, r, userId)) {
10415                             return null;
10416                         }
10417                     }
10418
10419                     try {
10420                         checkTime(startTime, "getContentProviderImpl: before getApplicationInfo");
10421                         ApplicationInfo ai =
10422                             AppGlobals.getPackageManager().
10423                                 getApplicationInfo(
10424                                         cpi.applicationInfo.packageName,
10425                                         STOCK_PM_FLAGS, userId);
10426                         checkTime(startTime, "getContentProviderImpl: after getApplicationInfo");
10427                         if (ai == null) {
10428                             Slog.w(TAG, "No package info for content provider "
10429                                     + cpi.name);
10430                             return null;
10431                         }
10432                         ai = getAppInfoForUser(ai, userId);
10433                         cpr = new ContentProviderRecord(this, cpi, ai, comp, singleton);
10434                     } catch (RemoteException ex) {
10435                         // pm is in same process, this will never happen.
10436                     } finally {
10437                         Binder.restoreCallingIdentity(ident);
10438                     }
10439                 }
10440
10441                 checkTime(startTime, "getContentProviderImpl: now have ContentProviderRecord");
10442
10443                 if (r != null && cpr.canRunHere(r)) {
10444                     // If this is a multiprocess provider, then just return its
10445                     // info and allow the caller to instantiate it.  Only do
10446                     // this if the provider is the same user as the caller's
10447                     // process, or can run as root (so can be in any process).
10448                     return cpr.newHolder(null);
10449                 }
10450
10451                 if (DEBUG_PROVIDER) Slog.w(TAG_PROVIDER, "LAUNCHING REMOTE PROVIDER (myuid "
10452                             + (r != null ? r.uid : null) + " pruid " + cpr.appInfo.uid + "): "
10453                             + cpr.info.name + " callers=" + Debug.getCallers(6));
10454
10455                 // This is single process, and our app is now connecting to it.
10456                 // See if we are already in the process of launching this
10457                 // provider.
10458                 final int N = mLaunchingProviders.size();
10459                 int i;
10460                 for (i = 0; i < N; i++) {
10461                     if (mLaunchingProviders.get(i) == cpr) {
10462                         break;
10463                     }
10464                 }
10465
10466                 // If the provider is not already being launched, then get it
10467                 // started.
10468                 if (i >= N) {
10469                     final long origId = Binder.clearCallingIdentity();
10470
10471                     try {
10472                         // Content provider is now in use, its package can't be stopped.
10473                         try {
10474                             checkTime(startTime, "getContentProviderImpl: before set stopped state");
10475                             AppGlobals.getPackageManager().setPackageStoppedState(
10476                                     cpr.appInfo.packageName, false, userId);
10477                             checkTime(startTime, "getContentProviderImpl: after set stopped state");
10478                         } catch (RemoteException e) {
10479                         } catch (IllegalArgumentException e) {
10480                             Slog.w(TAG, "Failed trying to unstop package "
10481                                     + cpr.appInfo.packageName + ": " + e);
10482                         }
10483
10484                         // Use existing process if already started
10485                         checkTime(startTime, "getContentProviderImpl: looking for process record");
10486                         ProcessRecord proc = getProcessRecordLocked(
10487                                 cpi.processName, cpr.appInfo.uid, false);
10488                         if (proc != null && proc.thread != null) {
10489                             if (DEBUG_PROVIDER) Slog.d(TAG_PROVIDER,
10490                                     "Installing in existing process " + proc);
10491                             if (!proc.pubProviders.containsKey(cpi.name)) {
10492                                 checkTime(startTime, "getContentProviderImpl: scheduling install");
10493                                 proc.pubProviders.put(cpi.name, cpr);
10494                                 try {
10495                                     proc.thread.scheduleInstallProvider(cpi);
10496                                 } catch (RemoteException e) {
10497                                 }
10498                             }
10499                         } else {
10500                             checkTime(startTime, "getContentProviderImpl: before start process");
10501                             proc = startProcessLocked(cpi.processName,
10502                                     cpr.appInfo, false, 0, "content provider",
10503                                     new ComponentName(cpi.applicationInfo.packageName,
10504                                             cpi.name), false, false, false);
10505                             checkTime(startTime, "getContentProviderImpl: after start process");
10506                             if (proc == null) {
10507                                 Slog.w(TAG, "Unable to launch app "
10508                                         + cpi.applicationInfo.packageName + "/"
10509                                         + cpi.applicationInfo.uid + " for provider "
10510                                         + name + ": process is bad");
10511                                 return null;
10512                             }
10513                         }
10514                         cpr.launchingApp = proc;
10515                         mLaunchingProviders.add(cpr);
10516                     } finally {
10517                         Binder.restoreCallingIdentity(origId);
10518                     }
10519                 }
10520
10521                 checkTime(startTime, "getContentProviderImpl: updating data structures");
10522
10523                 // Make sure the provider is published (the same provider class
10524                 // may be published under multiple names).
10525                 if (firstClass) {
10526                     mProviderMap.putProviderByClass(comp, cpr);
10527                 }
10528
10529                 mProviderMap.putProviderByName(name, cpr);
10530                 conn = incProviderCountLocked(r, cpr, token, stable);
10531                 if (conn != null) {
10532                     conn.waiting = true;
10533                 }
10534             }
10535             checkTime(startTime, "getContentProviderImpl: done!");
10536         }
10537
10538         // Wait for the provider to be published...
10539         synchronized (cpr) {
10540             while (cpr.provider == null) {
10541                 if (cpr.launchingApp == null) {
10542                     Slog.w(TAG, "Unable to launch app "
10543                             + cpi.applicationInfo.packageName + "/"
10544                             + cpi.applicationInfo.uid + " for provider "
10545                             + name + ": launching app became null");
10546                     EventLog.writeEvent(EventLogTags.AM_PROVIDER_LOST_PROCESS,
10547                             UserHandle.getUserId(cpi.applicationInfo.uid),
10548                             cpi.applicationInfo.packageName,
10549                             cpi.applicationInfo.uid, name);
10550                     return null;
10551                 }
10552                 try {
10553                     if (DEBUG_MU) Slog.v(TAG_MU,
10554                             "Waiting to start provider " + cpr
10555                             + " launchingApp=" + cpr.launchingApp);
10556                     if (conn != null) {
10557                         conn.waiting = true;
10558                     }
10559                     cpr.wait();
10560                 } catch (InterruptedException ex) {
10561                 } finally {
10562                     if (conn != null) {
10563                         conn.waiting = false;
10564                     }
10565                 }
10566             }
10567         }
10568         return cpr != null ? cpr.newHolder(conn) : null;
10569     }
10570
10571     private boolean requestTargetProviderPermissionsReviewIfNeededLocked(ProviderInfo cpi,
10572             ProcessRecord r, final int userId) {
10573         if (getPackageManagerInternalLocked().isPermissionsReviewRequired(
10574                 cpi.packageName, r.userId)) {
10575
10576             final boolean callerForeground = r != null ? r.setSchedGroup
10577                     != ProcessList.SCHED_GROUP_BACKGROUND : true;
10578
10579             // Show a permission review UI only for starting from a foreground app
10580             if (!callerForeground) {
10581                 Slog.w(TAG, "u" + r.userId + " Instantiating a provider in package"
10582                         + cpi.packageName + " requires a permissions review");
10583                 return false;
10584             }
10585
10586             final Intent intent = new Intent(Intent.ACTION_REVIEW_PERMISSIONS);
10587             intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK
10588                     | Intent.FLAG_ACTIVITY_EXCLUDE_FROM_RECENTS);
10589             intent.putExtra(Intent.EXTRA_PACKAGE_NAME, cpi.packageName);
10590
10591             if (DEBUG_PERMISSIONS_REVIEW) {
10592                 Slog.i(TAG, "u" + r.userId + " Launching permission review "
10593                         + "for package " + cpi.packageName);
10594             }
10595
10596             final UserHandle userHandle = new UserHandle(userId);
10597             mHandler.post(new Runnable() {
10598                 @Override
10599                 public void run() {
10600                     mContext.startActivityAsUser(intent, userHandle);
10601                 }
10602             });
10603
10604             return false;
10605         }
10606
10607         return true;
10608     }
10609
10610     PackageManagerInternal getPackageManagerInternalLocked() {
10611         if (mPackageManagerInt == null) {
10612             mPackageManagerInt = LocalServices.getService(PackageManagerInternal.class);
10613         }
10614         return mPackageManagerInt;
10615     }
10616
10617     @Override
10618     public final ContentProviderHolder getContentProvider(
10619             IApplicationThread caller, String name, int userId, boolean stable) {
10620         enforceNotIsolatedCaller("getContentProvider");
10621         if (caller == null) {
10622             String msg = "null IApplicationThread when getting content provider "
10623                     + name;
10624             Slog.w(TAG, msg);
10625             throw new SecurityException(msg);
10626         }
10627         // The incoming user check is now handled in checkContentProviderPermissionLocked() to deal
10628         // with cross-user grant.
10629         return getContentProviderImpl(caller, name, null, stable, userId);
10630     }
10631
10632     public ContentProviderHolder getContentProviderExternal(
10633             String name, int userId, IBinder token) {
10634         enforceCallingPermission(android.Manifest.permission.ACCESS_CONTENT_PROVIDERS_EXTERNALLY,
10635             "Do not have permission in call getContentProviderExternal()");
10636         userId = mUserController.handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(),
10637                 userId, false, ALLOW_FULL_ONLY, "getContentProvider", null);
10638         return getContentProviderExternalUnchecked(name, token, userId);
10639     }
10640
10641     private ContentProviderHolder getContentProviderExternalUnchecked(String name,
10642             IBinder token, int userId) {
10643         return getContentProviderImpl(null, name, token, true, userId);
10644     }
10645
10646     /**
10647      * Drop a content provider from a ProcessRecord's bookkeeping
10648      */
10649     public void removeContentProvider(IBinder connection, boolean stable) {
10650         enforceNotIsolatedCaller("removeContentProvider");
10651         long ident = Binder.clearCallingIdentity();
10652         try {
10653             synchronized (this) {
10654                 ContentProviderConnection conn;
10655                 try {
10656                     conn = (ContentProviderConnection)connection;
10657                 } catch (ClassCastException e) {
10658                     String msg ="removeContentProvider: " + connection
10659                             + " not a ContentProviderConnection";
10660                     Slog.w(TAG, msg);
10661                     throw new IllegalArgumentException(msg);
10662                 }
10663                 if (conn == null) {
10664                     throw new NullPointerException("connection is null");
10665                 }
10666                 if (decProviderCountLocked(conn, null, null, stable)) {
10667                     updateOomAdjLocked();
10668                 }
10669             }
10670         } finally {
10671             Binder.restoreCallingIdentity(ident);
10672         }
10673     }
10674
10675     public void removeContentProviderExternal(String name, IBinder token) {
10676         enforceCallingPermission(android.Manifest.permission.ACCESS_CONTENT_PROVIDERS_EXTERNALLY,
10677             "Do not have permission in call removeContentProviderExternal()");
10678         int userId = UserHandle.getCallingUserId();
10679         long ident = Binder.clearCallingIdentity();
10680         try {
10681             removeContentProviderExternalUnchecked(name, token, userId);
10682         } finally {
10683             Binder.restoreCallingIdentity(ident);
10684         }
10685     }
10686
10687     private void removeContentProviderExternalUnchecked(String name, IBinder token, int userId) {
10688         synchronized (this) {
10689             ContentProviderRecord cpr = mProviderMap.getProviderByName(name, userId);
10690             if(cpr == null) {
10691                 //remove from mProvidersByClass
10692                 if(DEBUG_ALL) Slog.v(TAG, name+" content provider not found in providers list");
10693                 return;
10694             }
10695
10696             //update content provider record entry info
10697             ComponentName comp = new ComponentName(cpr.info.packageName, cpr.info.name);
10698             ContentProviderRecord localCpr = mProviderMap.getProviderByClass(comp, userId);
10699             if (localCpr.hasExternalProcessHandles()) {
10700                 if (localCpr.removeExternalProcessHandleLocked(token)) {
10701                     updateOomAdjLocked();
10702                 } else {
10703                     Slog.e(TAG, "Attmpt to remove content provider " + localCpr
10704                             + " with no external reference for token: "
10705                             + token + ".");
10706                 }
10707             } else {
10708                 Slog.e(TAG, "Attmpt to remove content provider: " + localCpr
10709                         + " with no external references.");
10710             }
10711         }
10712     }
10713
10714     public final void publishContentProviders(IApplicationThread caller,
10715             List<ContentProviderHolder> providers) {
10716         if (providers == null) {
10717             return;
10718         }
10719
10720         enforceNotIsolatedCaller("publishContentProviders");
10721         synchronized (this) {
10722             final ProcessRecord r = getRecordForAppLocked(caller);
10723             if (DEBUG_MU) Slog.v(TAG_MU, "ProcessRecord uid = " + r.uid);
10724             if (r == null) {
10725                 throw new SecurityException(
10726                         "Unable to find app for caller " + caller
10727                       + " (pid=" + Binder.getCallingPid()
10728                       + ") when publishing content providers");
10729             }
10730
10731             final long origId = Binder.clearCallingIdentity();
10732
10733             final int N = providers.size();
10734             for (int i = 0; i < N; i++) {
10735                 ContentProviderHolder src = providers.get(i);
10736                 if (src == null || src.info == null || src.provider == null) {
10737                     continue;
10738                 }
10739                 ContentProviderRecord dst = r.pubProviders.get(src.info.name);
10740                 if (DEBUG_MU) Slog.v(TAG_MU, "ContentProviderRecord uid = " + dst.uid);
10741                 if (dst != null) {
10742                     ComponentName comp = new ComponentName(dst.info.packageName, dst.info.name);
10743                     mProviderMap.putProviderByClass(comp, dst);
10744                     String names[] = dst.info.authority.split(";");
10745                     for (int j = 0; j < names.length; j++) {
10746                         mProviderMap.putProviderByName(names[j], dst);
10747                     }
10748
10749                     int launchingCount = mLaunchingProviders.size();
10750                     int j;
10751                     boolean wasInLaunchingProviders = false;
10752                     for (j = 0; j < launchingCount; j++) {
10753                         if (mLaunchingProviders.get(j) == dst) {
10754                             mLaunchingProviders.remove(j);
10755                             wasInLaunchingProviders = true;
10756                             j--;
10757                             launchingCount--;
10758                         }
10759                     }
10760                     if (wasInLaunchingProviders) {
10761                         mHandler.removeMessages(CONTENT_PROVIDER_PUBLISH_TIMEOUT_MSG, r);
10762                     }
10763                     synchronized (dst) {
10764                         dst.provider = src.provider;
10765                         dst.proc = r;
10766                         dst.notifyAll();
10767                     }
10768                     updateOomAdjLocked(r);
10769                     maybeUpdateProviderUsageStatsLocked(r, src.info.packageName,
10770                             src.info.authority);
10771                 }
10772             }
10773
10774             Binder.restoreCallingIdentity(origId);
10775         }
10776     }
10777
10778     public boolean refContentProvider(IBinder connection, int stable, int unstable) {
10779         ContentProviderConnection conn;
10780         try {
10781             conn = (ContentProviderConnection)connection;
10782         } catch (ClassCastException e) {
10783             String msg ="refContentProvider: " + connection
10784                     + " not a ContentProviderConnection";
10785             Slog.w(TAG, msg);
10786             throw new IllegalArgumentException(msg);
10787         }
10788         if (conn == null) {
10789             throw new NullPointerException("connection is null");
10790         }
10791
10792         synchronized (this) {
10793             if (stable > 0) {
10794                 conn.numStableIncs += stable;
10795             }
10796             stable = conn.stableCount + stable;
10797             if (stable < 0) {
10798                 throw new IllegalStateException("stableCount < 0: " + stable);
10799             }
10800
10801             if (unstable > 0) {
10802                 conn.numUnstableIncs += unstable;
10803             }
10804             unstable = conn.unstableCount + unstable;
10805             if (unstable < 0) {
10806                 throw new IllegalStateException("unstableCount < 0: " + unstable);
10807             }
10808
10809             if ((stable+unstable) <= 0) {
10810                 throw new IllegalStateException("ref counts can't go to zero here: stable="
10811                         + stable + " unstable=" + unstable);
10812             }
10813             conn.stableCount = stable;
10814             conn.unstableCount = unstable;
10815             return !conn.dead;
10816         }
10817     }
10818
10819     public void unstableProviderDied(IBinder connection) {
10820         ContentProviderConnection conn;
10821         try {
10822             conn = (ContentProviderConnection)connection;
10823         } catch (ClassCastException e) {
10824             String msg ="refContentProvider: " + connection
10825                     + " not a ContentProviderConnection";
10826             Slog.w(TAG, msg);
10827             throw new IllegalArgumentException(msg);
10828         }
10829         if (conn == null) {
10830             throw new NullPointerException("connection is null");
10831         }
10832
10833         // Safely retrieve the content provider associated with the connection.
10834         IContentProvider provider;
10835         synchronized (this) {
10836             provider = conn.provider.provider;
10837         }
10838
10839         if (provider == null) {
10840             // Um, yeah, we're way ahead of you.
10841             return;
10842         }
10843
10844         // Make sure the caller is being honest with us.
10845         if (provider.asBinder().pingBinder()) {
10846             // Er, no, still looks good to us.
10847             synchronized (this) {
10848                 Slog.w(TAG, "unstableProviderDied: caller " + Binder.getCallingUid()
10849                         + " says " + conn + " died, but we don't agree");
10850                 return;
10851             }
10852         }
10853
10854         // Well look at that!  It's dead!
10855         synchronized (this) {
10856             if (conn.provider.provider != provider) {
10857                 // But something changed...  good enough.
10858                 return;
10859             }
10860
10861             ProcessRecord proc = conn.provider.proc;
10862             if (proc == null || proc.thread == null) {
10863                 // Seems like the process is already cleaned up.
10864                 return;
10865             }
10866
10867             // As far as we're concerned, this is just like receiving a
10868             // death notification...  just a bit prematurely.
10869             Slog.i(TAG, "Process " + proc.processName + " (pid " + proc.pid
10870                     + ") early provider death");
10871             final long ident = Binder.clearCallingIdentity();
10872             try {
10873                 appDiedLocked(proc);
10874             } finally {
10875                 Binder.restoreCallingIdentity(ident);
10876             }
10877         }
10878     }
10879
10880     @Override
10881     public void appNotRespondingViaProvider(IBinder connection) {
10882         enforceCallingPermission(
10883                 android.Manifest.permission.REMOVE_TASKS, "appNotRespondingViaProvider()");
10884
10885         final ContentProviderConnection conn = (ContentProviderConnection) connection;
10886         if (conn == null) {
10887             Slog.w(TAG, "ContentProviderConnection is null");
10888             return;
10889         }
10890
10891         final ProcessRecord host = conn.provider.proc;
10892         if (host == null) {
10893             Slog.w(TAG, "Failed to find hosting ProcessRecord");
10894             return;
10895         }
10896
10897         mHandler.post(new Runnable() {
10898             @Override
10899             public void run() {
10900                 mAppErrors.appNotResponding(host, null, null, false,
10901                         "ContentProvider not responding");
10902             }
10903         });
10904     }
10905
10906     public final void installSystemProviders() {
10907         List<ProviderInfo> providers;
10908         synchronized (this) {
10909             ProcessRecord app = mProcessNames.get("system", Process.SYSTEM_UID);
10910             providers = generateApplicationProvidersLocked(app);
10911             if (providers != null) {
10912                 for (int i=providers.size()-1; i>=0; i--) {
10913                     ProviderInfo pi = (ProviderInfo)providers.get(i);
10914                     if ((pi.applicationInfo.flags&ApplicationInfo.FLAG_SYSTEM) == 0) {
10915                         Slog.w(TAG, "Not installing system proc provider " + pi.name
10916                                 + ": not system .apk");
10917                         providers.remove(i);
10918                     }
10919                 }
10920             }
10921         }
10922         if (providers != null) {
10923             mSystemThread.installSystemProviders(providers);
10924         }
10925
10926         mCoreSettingsObserver = new CoreSettingsObserver(this);
10927         mFontScaleSettingObserver = new FontScaleSettingObserver();
10928
10929         //mUsageStatsService.monitorPackages();
10930     }
10931
10932     private void startPersistentApps(int matchFlags) {
10933         if (mFactoryTest == FactoryTest.FACTORY_TEST_LOW_LEVEL) return;
10934
10935         synchronized (this) {
10936             try {
10937                 final List<ApplicationInfo> apps = AppGlobals.getPackageManager()
10938                         .getPersistentApplications(STOCK_PM_FLAGS | matchFlags).getList();
10939                 for (ApplicationInfo app : apps) {
10940                     if (!"android".equals(app.packageName)) {
10941                         addAppLocked(app, false, null /* ABI override */);
10942                     }
10943                 }
10944             } catch (RemoteException ex) {
10945             }
10946         }
10947     }
10948
10949     /**
10950      * When a user is unlocked, we need to install encryption-unaware providers
10951      * belonging to any running apps.
10952      */
10953     private void installEncryptionUnawareProviders(int userId) {
10954         if (!StorageManager.isFileEncryptedNativeOrEmulated()) {
10955             // TODO: eventually pivot this back to look at current user state,
10956             // similar to the comment in UserManager.isUserUnlocked(), but for
10957             // now, if we started apps when "unlocked" then unaware providers
10958             // have already been spun up.
10959             return;
10960         }
10961
10962         // We're only interested in providers that are encryption unaware, and
10963         // we don't care about uninstalled apps, since there's no way they're
10964         // running at this point.
10965         final int matchFlags = GET_PROVIDERS | MATCH_DIRECT_BOOT_UNAWARE;
10966
10967         synchronized (this) {
10968             final int NP = mProcessNames.getMap().size();
10969             for (int ip = 0; ip < NP; ip++) {
10970                 final SparseArray<ProcessRecord> apps = mProcessNames.getMap().valueAt(ip);
10971                 final int NA = apps.size();
10972                 for (int ia = 0; ia < NA; ia++) {
10973                     final ProcessRecord app = apps.valueAt(ia);
10974                     if (app.userId != userId || app.thread == null) continue;
10975
10976                     final int NG = app.pkgList.size();
10977                     for (int ig = 0; ig < NG; ig++) {
10978                         try {
10979                             final String pkgName = app.pkgList.keyAt(ig);
10980                             final PackageInfo pkgInfo = AppGlobals.getPackageManager()
10981                                     .getPackageInfo(pkgName, matchFlags, userId);
10982                             if (pkgInfo != null && !ArrayUtils.isEmpty(pkgInfo.providers)) {
10983                                 for (ProviderInfo provInfo : pkgInfo.providers) {
10984                                     Log.v(TAG, "Installing " + provInfo);
10985                                     app.thread.scheduleInstallProvider(provInfo);
10986                                 }
10987                             }
10988                         } catch (RemoteException ignored) {
10989                         }
10990                     }
10991                 }
10992             }
10993         }
10994     }
10995
10996     /**
10997      * Allows apps to retrieve the MIME type of a URI.
10998      * If an app is in the same user as the ContentProvider, or if it is allowed to interact across
10999      * users, then it does not need permission to access the ContentProvider.
11000      * Either, it needs cross-user uri grants.
11001      *
11002      * CTS tests for this functionality can be run with "runtest cts-appsecurity".
11003      *
11004      * Test cases are at cts/tests/appsecurity-tests/test-apps/UsePermissionDiffCert/
11005      *     src/com/android/cts/usespermissiondiffcertapp/AccessPermissionWithDiffSigTest.java
11006      */
11007     public String getProviderMimeType(Uri uri, int userId) {
11008         enforceNotIsolatedCaller("getProviderMimeType");
11009         final String name = uri.getAuthority();
11010         int callingUid = Binder.getCallingUid();
11011         int callingPid = Binder.getCallingPid();
11012         long ident = 0;
11013         boolean clearedIdentity = false;
11014         synchronized (this) {
11015             userId = mUserController.unsafeConvertIncomingUserLocked(userId);
11016         }
11017         if (canClearIdentity(callingPid, callingUid, userId)) {
11018             clearedIdentity = true;
11019             ident = Binder.clearCallingIdentity();
11020         }
11021         ContentProviderHolder holder = null;
11022         try {
11023             holder = getContentProviderExternalUnchecked(name, null, userId);
11024             if (holder != null) {
11025                 return holder.provider.getType(uri);
11026             }
11027         } catch (RemoteException e) {
11028             Log.w(TAG, "Content provider dead retrieving " + uri, e);
11029             return null;
11030         } finally {
11031             // We need to clear the identity to call removeContentProviderExternalUnchecked
11032             if (!clearedIdentity) {
11033                 ident = Binder.clearCallingIdentity();
11034             }
11035             try {
11036                 if (holder != null) {
11037                     removeContentProviderExternalUnchecked(name, null, userId);
11038                 }
11039             } finally {
11040                 Binder.restoreCallingIdentity(ident);
11041             }
11042         }
11043
11044         return null;
11045     }
11046
11047     private boolean canClearIdentity(int callingPid, int callingUid, int userId) {
11048         if (UserHandle.getUserId(callingUid) == userId) {
11049             return true;
11050         }
11051         if (checkComponentPermission(INTERACT_ACROSS_USERS, callingPid,
11052                 callingUid, -1, true) == PackageManager.PERMISSION_GRANTED
11053                 || checkComponentPermission(INTERACT_ACROSS_USERS_FULL, callingPid,
11054                 callingUid, -1, true) == PackageManager.PERMISSION_GRANTED) {
11055                 return true;
11056         }
11057         return false;
11058     }
11059
11060     // =========================================================
11061     // GLOBAL MANAGEMENT
11062     // =========================================================
11063
11064     final ProcessRecord newProcessRecordLocked(ApplicationInfo info, String customProcess,
11065             boolean isolated, int isolatedUid) {
11066         String proc = customProcess != null ? customProcess : info.processName;
11067         BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
11068         final int userId = UserHandle.getUserId(info.uid);
11069         int uid = info.uid;
11070         if (isolated) {
11071             if (isolatedUid == 0) {
11072                 int stepsLeft = Process.LAST_ISOLATED_UID - Process.FIRST_ISOLATED_UID + 1;
11073                 while (true) {
11074                     if (mNextIsolatedProcessUid < Process.FIRST_ISOLATED_UID
11075                             || mNextIsolatedProcessUid > Process.LAST_ISOLATED_UID) {
11076                         mNextIsolatedProcessUid = Process.FIRST_ISOLATED_UID;
11077                     }
11078                     uid = UserHandle.getUid(userId, mNextIsolatedProcessUid);
11079                     mNextIsolatedProcessUid++;
11080                     if (mIsolatedProcesses.indexOfKey(uid) < 0) {
11081                         // No process for this uid, use it.
11082                         break;
11083                     }
11084                     stepsLeft--;
11085                     if (stepsLeft <= 0) {
11086                         return null;
11087                     }
11088                 }
11089             } else {
11090                 // Special case for startIsolatedProcess (internal only), where
11091                 // the uid of the isolated process is specified by the caller.
11092                 uid = isolatedUid;
11093             }
11094         }
11095         final ProcessRecord r = new ProcessRecord(stats, info, proc, uid);
11096         if (!mBooted && !mBooting
11097                 && userId == UserHandle.USER_SYSTEM
11098                 && (info.flags & PERSISTENT_MASK) == PERSISTENT_MASK) {
11099             r.persistent = true;
11100         }
11101         addProcessNameLocked(r);
11102         return r;
11103     }
11104
11105     final ProcessRecord addAppLocked(ApplicationInfo info, boolean isolated,
11106             String abiOverride) {
11107         ProcessRecord app;
11108         if (!isolated) {
11109             app = getProcessRecordLocked(info.processName, info.uid, true);
11110         } else {
11111             app = null;
11112         }
11113
11114         if (app == null) {
11115             app = newProcessRecordLocked(info, null, isolated, 0);
11116             updateLruProcessLocked(app, false, null);
11117             updateOomAdjLocked();
11118         }
11119
11120         // This package really, really can not be stopped.
11121         try {
11122             AppGlobals.getPackageManager().setPackageStoppedState(
11123                     info.packageName, false, UserHandle.getUserId(app.uid));
11124         } catch (RemoteException e) {
11125         } catch (IllegalArgumentException e) {
11126             Slog.w(TAG, "Failed trying to unstop package "
11127                     + info.packageName + ": " + e);
11128         }
11129
11130         if ((info.flags & PERSISTENT_MASK) == PERSISTENT_MASK) {
11131             app.persistent = true;
11132             app.maxAdj = ProcessList.PERSISTENT_PROC_ADJ;
11133         }
11134         if (app.thread == null && mPersistentStartingProcesses.indexOf(app) < 0) {
11135             mPersistentStartingProcesses.add(app);
11136             startProcessLocked(app, "added application", app.processName, abiOverride,
11137                     null /* entryPoint */, null /* entryPointArgs */);
11138         }
11139
11140         return app;
11141     }
11142
11143     public void unhandledBack() {
11144         enforceCallingPermission(android.Manifest.permission.FORCE_BACK,
11145                 "unhandledBack()");
11146
11147         synchronized(this) {
11148             final long origId = Binder.clearCallingIdentity();
11149             try {
11150                 getFocusedStack().unhandledBackLocked();
11151             } finally {
11152                 Binder.restoreCallingIdentity(origId);
11153             }
11154         }
11155     }
11156
11157     public ParcelFileDescriptor openContentUri(Uri uri) throws RemoteException {
11158         enforceNotIsolatedCaller("openContentUri");
11159         final int userId = UserHandle.getCallingUserId();
11160         String name = uri.getAuthority();
11161         ContentProviderHolder cph = getContentProviderExternalUnchecked(name, null, userId);
11162         ParcelFileDescriptor pfd = null;
11163         if (cph != null) {
11164             // We record the binder invoker's uid in thread-local storage before
11165             // going to the content provider to open the file.  Later, in the code
11166             // that handles all permissions checks, we look for this uid and use
11167             // that rather than the Activity Manager's own uid.  The effect is that
11168             // we do the check against the caller's permissions even though it looks
11169             // to the content provider like the Activity Manager itself is making
11170             // the request.
11171             Binder token = new Binder();
11172             sCallerIdentity.set(new Identity(
11173                     token, Binder.getCallingPid(), Binder.getCallingUid()));
11174             try {
11175                 pfd = cph.provider.openFile(null, uri, "r", null, token);
11176             } catch (FileNotFoundException e) {
11177                 // do nothing; pfd will be returned null
11178             } finally {
11179                 // Ensure that whatever happens, we clean up the identity state
11180                 sCallerIdentity.remove();
11181                 // Ensure we're done with the provider.
11182                 removeContentProviderExternalUnchecked(name, null, userId);
11183             }
11184         } else {
11185             Slog.d(TAG, "Failed to get provider for authority '" + name + "'");
11186         }
11187         return pfd;
11188     }
11189
11190     // Actually is sleeping or shutting down or whatever else in the future
11191     // is an inactive state.
11192     public boolean isSleepingOrShuttingDown() {
11193         return isSleeping() || mShuttingDown;
11194     }
11195
11196     public boolean isSleeping() {
11197         return mSleeping;
11198     }
11199
11200     void onWakefulnessChanged(int wakefulness) {
11201         synchronized(this) {
11202             mWakefulness = wakefulness;
11203             updateSleepIfNeededLocked();
11204         }
11205     }
11206
11207     void finishRunningVoiceLocked() {
11208         if (mRunningVoice != null) {
11209             mRunningVoice = null;
11210             mVoiceWakeLock.release();
11211             updateSleepIfNeededLocked();
11212         }
11213     }
11214
11215     void startTimeTrackingFocusedActivityLocked() {
11216         if (!mSleeping && mCurAppTimeTracker != null && mFocusedActivity != null) {
11217             mCurAppTimeTracker.start(mFocusedActivity.packageName);
11218         }
11219     }
11220
11221     void updateSleepIfNeededLocked() {
11222         if (mSleeping && !shouldSleepLocked()) {
11223             mSleeping = false;
11224             startTimeTrackingFocusedActivityLocked();
11225             mTopProcessState = ActivityManager.PROCESS_STATE_TOP;
11226             mStackSupervisor.comeOutOfSleepIfNeededLocked();
11227             updateOomAdjLocked();
11228         } else if (!mSleeping && shouldSleepLocked()) {
11229             mSleeping = true;
11230             if (mCurAppTimeTracker != null) {
11231                 mCurAppTimeTracker.stop();
11232             }
11233             mTopProcessState = ActivityManager.PROCESS_STATE_TOP_SLEEPING;
11234             mStackSupervisor.goingToSleepLocked();
11235             updateOomAdjLocked();
11236
11237             // Initialize the wake times of all processes.
11238             checkExcessivePowerUsageLocked(false);
11239             mHandler.removeMessages(CHECK_EXCESSIVE_WAKE_LOCKS_MSG);
11240             Message nmsg = mHandler.obtainMessage(CHECK_EXCESSIVE_WAKE_LOCKS_MSG);
11241             mHandler.sendMessageDelayed(nmsg, POWER_CHECK_DELAY);
11242         }
11243     }
11244
11245     private boolean shouldSleepLocked() {
11246         // Resume applications while running a voice interactor.
11247         if (mRunningVoice != null) {
11248             return false;
11249         }
11250
11251         // TODO: Transform the lock screen state into a sleep token instead.
11252         switch (mWakefulness) {
11253             case PowerManagerInternal.WAKEFULNESS_AWAKE:
11254             case PowerManagerInternal.WAKEFULNESS_DREAMING:
11255             case PowerManagerInternal.WAKEFULNESS_DOZING:
11256                 // Pause applications whenever the lock screen is shown or any sleep
11257                 // tokens have been acquired.
11258                 return (mLockScreenShown != LOCK_SCREEN_HIDDEN || !mSleepTokens.isEmpty());
11259             case PowerManagerInternal.WAKEFULNESS_ASLEEP:
11260             default:
11261                 // If we're asleep then pause applications unconditionally.
11262                 return true;
11263         }
11264     }
11265
11266     /** Pokes the task persister. */
11267     void notifyTaskPersisterLocked(TaskRecord task, boolean flush) {
11268         mRecentTasks.notifyTaskPersisterLocked(task, flush);
11269     }
11270
11271     /** Notifies all listeners when the task stack has changed. */
11272     void notifyTaskStackChangedLocked() {
11273         mHandler.sendEmptyMessage(LOG_STACK_STATE);
11274         mHandler.removeMessages(NOTIFY_TASK_STACK_CHANGE_LISTENERS_MSG);
11275         Message nmsg = mHandler.obtainMessage(NOTIFY_TASK_STACK_CHANGE_LISTENERS_MSG);
11276         mHandler.sendMessageDelayed(nmsg, NOTIFY_TASK_STACK_CHANGE_LISTENERS_DELAY);
11277     }
11278
11279     /** Notifies all listeners when an Activity is pinned. */
11280     void notifyActivityPinnedLocked() {
11281         mHandler.removeMessages(NOTIFY_ACTIVITY_PINNED_LISTENERS_MSG);
11282         mHandler.obtainMessage(NOTIFY_ACTIVITY_PINNED_LISTENERS_MSG).sendToTarget();
11283     }
11284
11285     /**
11286      * Notifies all listeners when an attempt was made to start an an activity that is already
11287      * running in the pinned stack and the activity was not actually started, but the task is
11288      * either brought to the front or a new Intent is delivered to it.
11289      */
11290     void notifyPinnedActivityRestartAttemptLocked() {
11291         mHandler.removeMessages(NOTIFY_PINNED_ACTIVITY_RESTART_ATTEMPT_LISTENERS_MSG);
11292         mHandler.obtainMessage(NOTIFY_PINNED_ACTIVITY_RESTART_ATTEMPT_LISTENERS_MSG).sendToTarget();
11293     }
11294
11295     /** Notifies all listeners when the pinned stack animation ends. */
11296     @Override
11297     public void notifyPinnedStackAnimationEnded() {
11298         synchronized (this) {
11299             mHandler.removeMessages(NOTIFY_PINNED_STACK_ANIMATION_ENDED_LISTENERS_MSG);
11300             mHandler.obtainMessage(
11301                     NOTIFY_PINNED_STACK_ANIMATION_ENDED_LISTENERS_MSG).sendToTarget();
11302         }
11303     }
11304
11305     @Override
11306     public void notifyCleartextNetwork(int uid, byte[] firstPacket) {
11307         mHandler.obtainMessage(NOTIFY_CLEARTEXT_NETWORK_MSG, uid, 0, firstPacket).sendToTarget();
11308     }
11309
11310     @Override
11311     public boolean shutdown(int timeout) {
11312         if (checkCallingPermission(android.Manifest.permission.SHUTDOWN)
11313                 != PackageManager.PERMISSION_GRANTED) {
11314             throw new SecurityException("Requires permission "
11315                     + android.Manifest.permission.SHUTDOWN);
11316         }
11317
11318         boolean timedout = false;
11319
11320         synchronized(this) {
11321             mShuttingDown = true;
11322             updateEventDispatchingLocked();
11323             timedout = mStackSupervisor.shutdownLocked(timeout);
11324         }
11325
11326         mAppOpsService.shutdown();
11327         if (mUsageStatsService != null) {
11328             mUsageStatsService.prepareShutdown();
11329         }
11330         mBatteryStatsService.shutdown();
11331         synchronized (this) {
11332             mProcessStats.shutdownLocked();
11333             notifyTaskPersisterLocked(null, true);
11334         }
11335
11336         return timedout;
11337     }
11338
11339     public final void activitySlept(IBinder token) {
11340         if (DEBUG_ALL) Slog.v(TAG, "Activity slept: token=" + token);
11341
11342         final long origId = Binder.clearCallingIdentity();
11343
11344         synchronized (this) {
11345             final ActivityRecord r = ActivityRecord.isInStackLocked(token);
11346             if (r != null) {
11347                 mStackSupervisor.activitySleptLocked(r);
11348             }
11349         }
11350
11351         Binder.restoreCallingIdentity(origId);
11352     }
11353
11354     private String lockScreenShownToString() {
11355         switch (mLockScreenShown) {
11356             case LOCK_SCREEN_HIDDEN: return "LOCK_SCREEN_HIDDEN";
11357             case LOCK_SCREEN_LEAVING: return "LOCK_SCREEN_LEAVING";
11358             case LOCK_SCREEN_SHOWN: return "LOCK_SCREEN_SHOWN";
11359             default: return "Unknown=" + mLockScreenShown;
11360         }
11361     }
11362
11363     void logLockScreen(String msg) {
11364         if (DEBUG_LOCKSCREEN) Slog.d(TAG_LOCKSCREEN, Debug.getCallers(2) + ":" + msg
11365                 + " mLockScreenShown=" + lockScreenShownToString() + " mWakefulness="
11366                 + PowerManagerInternal.wakefulnessToString(mWakefulness)
11367                 + " mSleeping=" + mSleeping);
11368     }
11369
11370     void startRunningVoiceLocked(IVoiceInteractionSession session, int targetUid) {
11371         Slog.d(TAG, "<<<  startRunningVoiceLocked()");
11372         mVoiceWakeLock.setWorkSource(new WorkSource(targetUid));
11373         if (mRunningVoice == null || mRunningVoice.asBinder() != session.asBinder()) {
11374             boolean wasRunningVoice = mRunningVoice != null;
11375             mRunningVoice = session;
11376             if (!wasRunningVoice) {
11377                 mVoiceWakeLock.acquire();
11378                 updateSleepIfNeededLocked();
11379             }
11380         }
11381     }
11382
11383     private void updateEventDispatchingLocked() {
11384         mWindowManager.setEventDispatching(mBooted && !mShuttingDown);
11385     }
11386
11387     public void setLockScreenShown(boolean shown) {
11388         if (checkCallingPermission(android.Manifest.permission.DEVICE_POWER)
11389                 != PackageManager.PERMISSION_GRANTED) {
11390             throw new SecurityException("Requires permission "
11391                     + android.Manifest.permission.DEVICE_POWER);
11392         }
11393
11394         synchronized(this) {
11395             long ident = Binder.clearCallingIdentity();
11396             try {
11397                 if (DEBUG_LOCKSCREEN) logLockScreen(" shown=" + shown);
11398                 mLockScreenShown = shown ? LOCK_SCREEN_SHOWN : LOCK_SCREEN_HIDDEN;
11399                 updateSleepIfNeededLocked();
11400             } finally {
11401                 Binder.restoreCallingIdentity(ident);
11402             }
11403         }
11404     }
11405
11406     @Override
11407     public void notifyLockedProfile(@UserIdInt int userId) {
11408         try {
11409             if (!AppGlobals.getPackageManager().isUidPrivileged(Binder.getCallingUid())) {
11410                 throw new SecurityException("Only privileged app can call notifyLockedProfile");
11411             }
11412         } catch (RemoteException ex) {
11413             throw new SecurityException("Fail to check is caller a privileged app", ex);
11414         }
11415
11416         synchronized (this) {
11417             if (mStackSupervisor.isFocusedUserLockedProfile()) {
11418                 final long ident = Binder.clearCallingIdentity();
11419                 try {
11420                     final int currentUserId = mUserController.getCurrentUserIdLocked();
11421                     startHomeActivityLocked(currentUserId, "notifyProfileLocked");
11422                 } finally {
11423                     Binder.restoreCallingIdentity(ident);
11424                 }
11425             }
11426         }
11427     }
11428
11429     @Override
11430     public void stopAppSwitches() {
11431         if (checkCallingPermission(android.Manifest.permission.STOP_APP_SWITCHES)
11432                 != PackageManager.PERMISSION_GRANTED) {
11433             throw new SecurityException("viewquires permission "
11434                     + android.Manifest.permission.STOP_APP_SWITCHES);
11435         }
11436
11437         synchronized(this) {
11438             mAppSwitchesAllowedTime = SystemClock.uptimeMillis()
11439                     + APP_SWITCH_DELAY_TIME;
11440             mDidAppSwitch = false;
11441             mHandler.removeMessages(DO_PENDING_ACTIVITY_LAUNCHES_MSG);
11442             Message msg = mHandler.obtainMessage(DO_PENDING_ACTIVITY_LAUNCHES_MSG);
11443             mHandler.sendMessageDelayed(msg, APP_SWITCH_DELAY_TIME);
11444         }
11445     }
11446
11447     public void resumeAppSwitches() {
11448         if (checkCallingPermission(android.Manifest.permission.STOP_APP_SWITCHES)
11449                 != PackageManager.PERMISSION_GRANTED) {
11450             throw new SecurityException("Requires permission "
11451                     + android.Manifest.permission.STOP_APP_SWITCHES);
11452         }
11453
11454         synchronized(this) {
11455             // Note that we don't execute any pending app switches... we will
11456             // let those wait until either the timeout, or the next start
11457             // activity request.
11458             mAppSwitchesAllowedTime = 0;
11459         }
11460     }
11461
11462     boolean checkAppSwitchAllowedLocked(int sourcePid, int sourceUid,
11463             int callingPid, int callingUid, String name) {
11464         if (mAppSwitchesAllowedTime < SystemClock.uptimeMillis()) {
11465             return true;
11466         }
11467
11468         int perm = checkComponentPermission(
11469                 android.Manifest.permission.STOP_APP_SWITCHES, sourcePid,
11470                 sourceUid, -1, true);
11471         if (perm == PackageManager.PERMISSION_GRANTED) {
11472             return true;
11473         }
11474
11475         // If the actual IPC caller is different from the logical source, then
11476         // also see if they are allowed to control app switches.
11477         if (callingUid != -1 && callingUid != sourceUid) {
11478             perm = checkComponentPermission(
11479                     android.Manifest.permission.STOP_APP_SWITCHES, callingPid,
11480                     callingUid, -1, true);
11481             if (perm == PackageManager.PERMISSION_GRANTED) {
11482                 return true;
11483             }
11484         }
11485
11486         Slog.w(TAG, name + " request from " + sourceUid + " stopped");
11487         return false;
11488     }
11489
11490     public void setDebugApp(String packageName, boolean waitForDebugger,
11491             boolean persistent) {
11492         enforceCallingPermission(android.Manifest.permission.SET_DEBUG_APP,
11493                 "setDebugApp()");
11494
11495         long ident = Binder.clearCallingIdentity();
11496         try {
11497             // Note that this is not really thread safe if there are multiple
11498             // callers into it at the same time, but that's not a situation we
11499             // care about.
11500             if (persistent) {
11501                 final ContentResolver resolver = mContext.getContentResolver();
11502                 Settings.Global.putString(
11503                     resolver, Settings.Global.DEBUG_APP,
11504                     packageName);
11505                 Settings.Global.putInt(
11506                     resolver, Settings.Global.WAIT_FOR_DEBUGGER,
11507                     waitForDebugger ? 1 : 0);
11508             }
11509
11510             synchronized (this) {
11511                 if (!persistent) {
11512                     mOrigDebugApp = mDebugApp;
11513                     mOrigWaitForDebugger = mWaitForDebugger;
11514                 }
11515                 mDebugApp = packageName;
11516                 mWaitForDebugger = waitForDebugger;
11517                 mDebugTransient = !persistent;
11518                 if (packageName != null) {
11519                     forceStopPackageLocked(packageName, -1, false, false, true, true,
11520                             false, UserHandle.USER_ALL, "set debug app");
11521                 }
11522             }
11523         } finally {
11524             Binder.restoreCallingIdentity(ident);
11525         }
11526     }
11527
11528     void setTrackAllocationApp(ApplicationInfo app, String processName) {
11529         synchronized (this) {
11530             boolean isDebuggable = "1".equals(SystemProperties.get(SYSTEM_DEBUGGABLE, "0"));
11531             if (!isDebuggable) {
11532                 if ((app.flags & ApplicationInfo.FLAG_DEBUGGABLE) == 0) {
11533                     throw new SecurityException("Process not debuggable: " + app.packageName);
11534                 }
11535             }
11536
11537             mTrackAllocationApp = processName;
11538         }
11539     }
11540
11541     void setProfileApp(ApplicationInfo app, String processName, ProfilerInfo profilerInfo) {
11542         synchronized (this) {
11543             boolean isDebuggable = "1".equals(SystemProperties.get(SYSTEM_DEBUGGABLE, "0"));
11544             if (!isDebuggable) {
11545                 if ((app.flags & ApplicationInfo.FLAG_DEBUGGABLE) == 0) {
11546                     throw new SecurityException("Process not debuggable: " + app.packageName);
11547                 }
11548             }
11549             mProfileApp = processName;
11550             mProfileFile = profilerInfo.profileFile;
11551             if (mProfileFd != null) {
11552                 try {
11553                     mProfileFd.close();
11554                 } catch (IOException e) {
11555                 }
11556                 mProfileFd = null;
11557             }
11558             mProfileFd = profilerInfo.profileFd;
11559             mSamplingInterval = profilerInfo.samplingInterval;
11560             mAutoStopProfiler = profilerInfo.autoStopProfiler;
11561             mProfileType = 0;
11562         }
11563     }
11564
11565     void setNativeDebuggingAppLocked(ApplicationInfo app, String processName) {
11566         boolean isDebuggable = "1".equals(SystemProperties.get(SYSTEM_DEBUGGABLE, "0"));
11567         if (!isDebuggable) {
11568             if ((app.flags & ApplicationInfo.FLAG_DEBUGGABLE) == 0) {
11569                 throw new SecurityException("Process not debuggable: " + app.packageName);
11570             }
11571         }
11572         mNativeDebuggingApp = processName;
11573     }
11574
11575     @Override
11576     public void setAlwaysFinish(boolean enabled) {
11577         enforceCallingPermission(android.Manifest.permission.SET_ALWAYS_FINISH,
11578                 "setAlwaysFinish()");
11579
11580         long ident = Binder.clearCallingIdentity();
11581         try {
11582             Settings.Global.putInt(
11583                     mContext.getContentResolver(),
11584                     Settings.Global.ALWAYS_FINISH_ACTIVITIES, enabled ? 1 : 0);
11585
11586             synchronized (this) {
11587                 mAlwaysFinishActivities = enabled;
11588             }
11589         } finally {
11590             Binder.restoreCallingIdentity(ident);
11591         }
11592     }
11593
11594     @Override
11595     public void setLenientBackgroundCheck(boolean enabled) {
11596         enforceCallingPermission(android.Manifest.permission.SET_PROCESS_LIMIT,
11597                 "setLenientBackgroundCheck()");
11598
11599         long ident = Binder.clearCallingIdentity();
11600         try {
11601             Settings.Global.putInt(
11602                     mContext.getContentResolver(),
11603                     Settings.Global.LENIENT_BACKGROUND_CHECK, enabled ? 1 : 0);
11604
11605             synchronized (this) {
11606                 mLenientBackgroundCheck = enabled;
11607             }
11608         } finally {
11609             Binder.restoreCallingIdentity(ident);
11610         }
11611     }
11612
11613     @Override
11614     public void setActivityController(IActivityController controller, boolean imAMonkey) {
11615         enforceCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER,
11616                 "setActivityController()");
11617         synchronized (this) {
11618             mController = controller;
11619             mControllerIsAMonkey = imAMonkey;
11620             Watchdog.getInstance().setActivityController(controller);
11621         }
11622     }
11623
11624     @Override
11625     public void setUserIsMonkey(boolean userIsMonkey) {
11626         synchronized (this) {
11627             synchronized (mPidsSelfLocked) {
11628                 final int callingPid = Binder.getCallingPid();
11629                 ProcessRecord precessRecord = mPidsSelfLocked.get(callingPid);
11630                 if (precessRecord == null) {
11631                     throw new SecurityException("Unknown process: " + callingPid);
11632                 }
11633                 if (precessRecord.instrumentationUiAutomationConnection  == null) {
11634                     throw new SecurityException("Only an instrumentation process "
11635                             + "with a UiAutomation can call setUserIsMonkey");
11636                 }
11637             }
11638             mUserIsMonkey = userIsMonkey;
11639         }
11640     }
11641
11642     @Override
11643     public boolean isUserAMonkey() {
11644         synchronized (this) {
11645             // If there is a controller also implies the user is a monkey.
11646             return (mUserIsMonkey || (mController != null && mControllerIsAMonkey));
11647         }
11648     }
11649
11650     public void requestBugReport(int bugreportType) {
11651         String service = null;
11652         switch (bugreportType) {
11653             case ActivityManager.BUGREPORT_OPTION_FULL:
11654                 service = "bugreport";
11655                 break;
11656             case ActivityManager.BUGREPORT_OPTION_INTERACTIVE:
11657                 service = "bugreportplus";
11658                 break;
11659             case ActivityManager.BUGREPORT_OPTION_REMOTE:
11660                 service = "bugreportremote";
11661                 break;
11662         }
11663         if (service == null) {
11664             throw new IllegalArgumentException("Provided bugreport type is not correct, value: "
11665                     + bugreportType);
11666         }
11667         enforceCallingPermission(android.Manifest.permission.DUMP, "requestBugReport");
11668         SystemProperties.set("ctl.start", service);
11669     }
11670
11671     public static long getInputDispatchingTimeoutLocked(ActivityRecord r) {
11672         return r != null ? getInputDispatchingTimeoutLocked(r.app) : KEY_DISPATCHING_TIMEOUT;
11673     }
11674
11675     public static long getInputDispatchingTimeoutLocked(ProcessRecord r) {
11676         if (r != null && (r.instrumentationClass != null || r.usingWrapper)) {
11677             return INSTRUMENTATION_KEY_DISPATCHING_TIMEOUT;
11678         }
11679         return KEY_DISPATCHING_TIMEOUT;
11680     }
11681
11682     @Override
11683     public long inputDispatchingTimedOut(int pid, final boolean aboveSystem, String reason) {
11684         if (checkCallingPermission(android.Manifest.permission.FILTER_EVENTS)
11685                 != PackageManager.PERMISSION_GRANTED) {
11686             throw new SecurityException("Requires permission "
11687                     + android.Manifest.permission.FILTER_EVENTS);
11688         }
11689         ProcessRecord proc;
11690         long timeout;
11691         synchronized (this) {
11692             synchronized (mPidsSelfLocked) {
11693                 proc = mPidsSelfLocked.get(pid);
11694             }
11695             timeout = getInputDispatchingTimeoutLocked(proc);
11696         }
11697
11698         if (!inputDispatchingTimedOut(proc, null, null, aboveSystem, reason)) {
11699             return -1;
11700         }
11701
11702         return timeout;
11703     }
11704
11705     /**
11706      * Handle input dispatching timeouts.
11707      * Returns whether input dispatching should be aborted or not.
11708      */
11709     public boolean inputDispatchingTimedOut(final ProcessRecord proc,
11710             final ActivityRecord activity, final ActivityRecord parent,
11711             final boolean aboveSystem, String reason) {
11712         if (checkCallingPermission(android.Manifest.permission.FILTER_EVENTS)
11713                 != PackageManager.PERMISSION_GRANTED) {
11714             throw new SecurityException("Requires permission "
11715                     + android.Manifest.permission.FILTER_EVENTS);
11716         }
11717
11718         final String annotation;
11719         if (reason == null) {
11720             annotation = "Input dispatching timed out";
11721         } else {
11722             annotation = "Input dispatching timed out (" + reason + ")";
11723         }
11724
11725         if (proc != null) {
11726             synchronized (this) {
11727                 if (proc.debugging) {
11728                     return false;
11729                 }
11730
11731                 if (mDidDexOpt) {
11732                     // Give more time since we were dexopting.
11733                     mDidDexOpt = false;
11734                     return false;
11735                 }
11736
11737                 if (proc.instrumentationClass != null) {
11738                     Bundle info = new Bundle();
11739                     info.putString("shortMsg", "keyDispatchingTimedOut");
11740                     info.putString("longMsg", annotation);
11741                     finishInstrumentationLocked(proc, Activity.RESULT_CANCELED, info);
11742                     return true;
11743                 }
11744             }
11745             mHandler.post(new Runnable() {
11746                 @Override
11747                 public void run() {
11748                     mAppErrors.appNotResponding(proc, activity, parent, aboveSystem, annotation);
11749                 }
11750             });
11751         }
11752
11753         return true;
11754     }
11755
11756     @Override
11757     public Bundle getAssistContextExtras(int requestType) {
11758         PendingAssistExtras pae = enqueueAssistContext(requestType, null, null, null,
11759                 null, UserHandle.getCallingUserId(), null, PENDING_ASSIST_EXTRAS_TIMEOUT);
11760         if (pae == null) {
11761             return null;
11762         }
11763         synchronized (pae) {
11764             while (!pae.haveResult) {
11765                 try {
11766                     pae.wait();
11767                 } catch (InterruptedException e) {
11768                 }
11769             }
11770         }
11771         synchronized (this) {
11772             buildAssistBundleLocked(pae, pae.result);
11773             mPendingAssistExtras.remove(pae);
11774             mUiHandler.removeCallbacks(pae);
11775         }
11776         return pae.extras;
11777     }
11778
11779     @Override
11780     public boolean isAssistDataAllowedOnCurrentActivity() {
11781         int userId;
11782         synchronized (this) {
11783             userId = mUserController.getCurrentUserIdLocked();
11784             ActivityRecord activity = getFocusedStack().topActivity();
11785             if (activity == null) {
11786                 return false;
11787             }
11788             userId = activity.userId;
11789         }
11790         DevicePolicyManager dpm = (DevicePolicyManager) mContext.getSystemService(
11791                 Context.DEVICE_POLICY_SERVICE);
11792         return (dpm == null) || (!dpm.getScreenCaptureDisabled(null, userId));
11793     }
11794
11795     @Override
11796     public boolean showAssistFromActivity(IBinder token, Bundle args) {
11797         long ident = Binder.clearCallingIdentity();
11798         try {
11799             synchronized (this) {
11800                 ActivityRecord caller = ActivityRecord.forTokenLocked(token);
11801                 ActivityRecord top = getFocusedStack().topActivity();
11802                 if (top != caller) {
11803                     Slog.w(TAG, "showAssistFromActivity failed: caller " + caller
11804                             + " is not current top " + top);
11805                     return false;
11806                 }
11807                 if (!top.nowVisible) {
11808                     Slog.w(TAG, "showAssistFromActivity failed: caller " + caller
11809                             + " is not visible");
11810                     return false;
11811                 }
11812             }
11813             AssistUtils utils = new AssistUtils(mContext);
11814             return utils.showSessionForActiveService(args,
11815                     VoiceInteractionSession.SHOW_SOURCE_APPLICATION, null, token);
11816         } finally {
11817             Binder.restoreCallingIdentity(ident);
11818         }
11819     }
11820
11821     @Override
11822     public boolean requestAssistContextExtras(int requestType, IResultReceiver receiver,
11823             IBinder activityToken) {
11824         return enqueueAssistContext(requestType, null, null, receiver, activityToken,
11825                 UserHandle.getCallingUserId(), null, PENDING_ASSIST_EXTRAS_LONG_TIMEOUT) != null;
11826     }
11827
11828     private PendingAssistExtras enqueueAssistContext(int requestType, Intent intent, String hint,
11829             IResultReceiver receiver, IBinder activityToken, int userHandle, Bundle args,
11830             long timeout) {
11831         enforceCallingPermission(android.Manifest.permission.GET_TOP_ACTIVITY_INFO,
11832                 "enqueueAssistContext()");
11833         synchronized (this) {
11834             ActivityRecord activity = getFocusedStack().topActivity();
11835             if (activity == null) {
11836                 Slog.w(TAG, "getAssistContextExtras failed: no top activity");
11837                 return null;
11838             }
11839             if (activity.app == null || activity.app.thread == null) {
11840                 Slog.w(TAG, "getAssistContextExtras failed: no process for " + activity);
11841                 return null;
11842             }
11843             if (activityToken != null) {
11844                 ActivityRecord caller = ActivityRecord.forTokenLocked(activityToken);
11845                 if (activity != caller) {
11846                     Slog.w(TAG, "enqueueAssistContext failed: caller " + caller
11847                             + " is not current top " + activity);
11848                     return null;
11849                 }
11850             }
11851             PendingAssistExtras pae;
11852             Bundle extras = new Bundle();
11853             if (args != null) {
11854                 extras.putAll(args);
11855             }
11856             extras.putString(Intent.EXTRA_ASSIST_PACKAGE, activity.packageName);
11857             extras.putInt(Intent.EXTRA_ASSIST_UID, activity.app.uid);
11858             pae = new PendingAssistExtras(activity, extras, intent, hint, receiver, userHandle);
11859             try {
11860                 activity.app.thread.requestAssistContextExtras(activity.appToken, pae,
11861                         requestType);
11862                 mPendingAssistExtras.add(pae);
11863                 mUiHandler.postDelayed(pae, timeout);
11864             } catch (RemoteException e) {
11865                 Slog.w(TAG, "getAssistContextExtras failed: crash calling " + activity);
11866                 return null;
11867             }
11868             return pae;
11869         }
11870     }
11871
11872     void pendingAssistExtrasTimedOut(PendingAssistExtras pae) {
11873         IResultReceiver receiver;
11874         synchronized (this) {
11875             mPendingAssistExtras.remove(pae);
11876             receiver = pae.receiver;
11877         }
11878         if (receiver != null) {
11879             // Caller wants result sent back to them.
11880             try {
11881                 pae.receiver.send(0, null);
11882             } catch (RemoteException e) {
11883             }
11884         }
11885     }
11886
11887     private void buildAssistBundleLocked(PendingAssistExtras pae, Bundle result) {
11888         if (result != null) {
11889             pae.extras.putBundle(Intent.EXTRA_ASSIST_CONTEXT, result);
11890         }
11891         if (pae.hint != null) {
11892             pae.extras.putBoolean(pae.hint, true);
11893         }
11894     }
11895
11896     public void reportAssistContextExtras(IBinder token, Bundle extras, AssistStructure structure,
11897             AssistContent content, Uri referrer) {
11898         PendingAssistExtras pae = (PendingAssistExtras)token;
11899         synchronized (pae) {
11900             pae.result = extras;
11901             pae.structure = structure;
11902             pae.content = content;
11903             if (referrer != null) {
11904                 pae.extras.putParcelable(Intent.EXTRA_REFERRER, referrer);
11905             }
11906             pae.haveResult = true;
11907             pae.notifyAll();
11908             if (pae.intent == null && pae.receiver == null) {
11909                 // Caller is just waiting for the result.
11910                 return;
11911             }
11912         }
11913
11914         // We are now ready to launch the assist activity.
11915         IResultReceiver sendReceiver = null;
11916         Bundle sendBundle = null;
11917         synchronized (this) {
11918             buildAssistBundleLocked(pae, extras);
11919             boolean exists = mPendingAssistExtras.remove(pae);
11920             mUiHandler.removeCallbacks(pae);
11921             if (!exists) {
11922                 // Timed out.
11923                 return;
11924             }
11925             if ((sendReceiver=pae.receiver) != null) {
11926                 // Caller wants result sent back to them.
11927                 sendBundle = new Bundle();
11928                 sendBundle.putBundle("data", pae.extras);
11929                 sendBundle.putParcelable("structure", pae.structure);
11930                 sendBundle.putParcelable("content", pae.content);
11931             }
11932         }
11933         if (sendReceiver != null) {
11934             try {
11935                 sendReceiver.send(0, sendBundle);
11936             } catch (RemoteException e) {
11937             }
11938             return;
11939         }
11940
11941         long ident = Binder.clearCallingIdentity();
11942         try {
11943             pae.intent.replaceExtras(pae.extras);
11944             pae.intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK
11945                     | Intent.FLAG_ACTIVITY_SINGLE_TOP
11946                     | Intent.FLAG_ACTIVITY_CLEAR_TOP);
11947             closeSystemDialogs("assist");
11948             try {
11949                 mContext.startActivityAsUser(pae.intent, new UserHandle(pae.userHandle));
11950             } catch (ActivityNotFoundException e) {
11951                 Slog.w(TAG, "No activity to handle assist action.", e);
11952             }
11953         } finally {
11954             Binder.restoreCallingIdentity(ident);
11955         }
11956     }
11957
11958     public boolean launchAssistIntent(Intent intent, int requestType, String hint, int userHandle,
11959             Bundle args) {
11960         return enqueueAssistContext(requestType, intent, hint, null, null, userHandle, args,
11961                 PENDING_ASSIST_EXTRAS_TIMEOUT) != null;
11962     }
11963
11964     public void registerProcessObserver(IProcessObserver observer) {
11965         enforceCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER,
11966                 "registerProcessObserver()");
11967         synchronized (this) {
11968             mProcessObservers.register(observer);
11969         }
11970     }
11971
11972     @Override
11973     public void unregisterProcessObserver(IProcessObserver observer) {
11974         synchronized (this) {
11975             mProcessObservers.unregister(observer);
11976         }
11977     }
11978
11979     @Override
11980     public void registerUidObserver(IUidObserver observer, int which) {
11981         enforceCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER,
11982                 "registerUidObserver()");
11983         synchronized (this) {
11984             mUidObservers.register(observer, which);
11985         }
11986     }
11987
11988     @Override
11989     public void unregisterUidObserver(IUidObserver observer) {
11990         synchronized (this) {
11991             mUidObservers.unregister(observer);
11992         }
11993     }
11994
11995     @Override
11996     public boolean convertFromTranslucent(IBinder token) {
11997         final long origId = Binder.clearCallingIdentity();
11998         try {
11999             synchronized (this) {
12000                 final ActivityRecord r = ActivityRecord.isInStackLocked(token);
12001                 if (r == null) {
12002                     return false;
12003                 }
12004                 final boolean translucentChanged = r.changeWindowTranslucency(true);
12005                 if (translucentChanged) {
12006                     r.task.stack.releaseBackgroundResources(r);
12007                     mStackSupervisor.ensureActivitiesVisibleLocked(null, 0, !PRESERVE_WINDOWS);
12008                 }
12009                 mWindowManager.setAppFullscreen(token, true);
12010                 return translucentChanged;
12011             }
12012         } finally {
12013             Binder.restoreCallingIdentity(origId);
12014         }
12015     }
12016
12017     @Override
12018     public boolean convertToTranslucent(IBinder token, ActivityOptions options) {
12019         final long origId = Binder.clearCallingIdentity();
12020         try {
12021             synchronized (this) {
12022                 final ActivityRecord r = ActivityRecord.isInStackLocked(token);
12023                 if (r == null) {
12024                     return false;
12025                 }
12026                 int index = r.task.mActivities.lastIndexOf(r);
12027                 if (index > 0) {
12028                     ActivityRecord under = r.task.mActivities.get(index - 1);
12029                     under.returningOptions = options;
12030                 }
12031                 final boolean translucentChanged = r.changeWindowTranslucency(false);
12032                 if (translucentChanged) {
12033                     r.task.stack.convertActivityToTranslucent(r);
12034                 }
12035                 mStackSupervisor.ensureActivitiesVisibleLocked(null, 0, !PRESERVE_WINDOWS);
12036                 mWindowManager.setAppFullscreen(token, false);
12037                 return translucentChanged;
12038             }
12039         } finally {
12040             Binder.restoreCallingIdentity(origId);
12041         }
12042     }
12043
12044     @Override
12045     public boolean requestVisibleBehind(IBinder token, boolean visible) {
12046         final long origId = Binder.clearCallingIdentity();
12047         try {
12048             synchronized (this) {
12049                 final ActivityRecord r = ActivityRecord.isInStackLocked(token);
12050                 if (r != null) {
12051                     return mStackSupervisor.requestVisibleBehindLocked(r, visible);
12052                 }
12053             }
12054             return false;
12055         } finally {
12056             Binder.restoreCallingIdentity(origId);
12057         }
12058     }
12059
12060     @Override
12061     public boolean isBackgroundVisibleBehind(IBinder token) {
12062         final long origId = Binder.clearCallingIdentity();
12063         try {
12064             synchronized (this) {
12065                 final ActivityStack stack = ActivityRecord.getStackLocked(token);
12066                 final boolean visible = stack == null ? false : stack.hasVisibleBehindActivity();
12067                 if (DEBUG_VISIBLE_BEHIND) Slog.d(TAG_VISIBLE_BEHIND,
12068                         "isBackgroundVisibleBehind: stack=" + stack + " visible=" + visible);
12069                 return visible;
12070             }
12071         } finally {
12072             Binder.restoreCallingIdentity(origId);
12073         }
12074     }
12075
12076     @Override
12077     public ActivityOptions getActivityOptions(IBinder token) {
12078         final long origId = Binder.clearCallingIdentity();
12079         try {
12080             synchronized (this) {
12081                 final ActivityRecord r = ActivityRecord.isInStackLocked(token);
12082                 if (r != null) {
12083                     final ActivityOptions activityOptions = r.pendingOptions;
12084                     r.pendingOptions = null;
12085                     return activityOptions;
12086                 }
12087                 return null;
12088             }
12089         } finally {
12090             Binder.restoreCallingIdentity(origId);
12091         }
12092     }
12093
12094     @Override
12095     public void setImmersive(IBinder token, boolean immersive) {
12096         synchronized(this) {
12097             final ActivityRecord r = ActivityRecord.isInStackLocked(token);
12098             if (r == null) {
12099                 throw new IllegalArgumentException();
12100             }
12101             r.immersive = immersive;
12102
12103             // update associated state if we're frontmost
12104             if (r == mFocusedActivity) {
12105                 if (DEBUG_IMMERSIVE) Slog.d(TAG_IMMERSIVE, "Frontmost changed immersion: "+ r);
12106                 applyUpdateLockStateLocked(r);
12107             }
12108         }
12109     }
12110
12111     @Override
12112     public boolean isImmersive(IBinder token) {
12113         synchronized (this) {
12114             ActivityRecord r = ActivityRecord.isInStackLocked(token);
12115             if (r == null) {
12116                 throw new IllegalArgumentException();
12117             }
12118             return r.immersive;
12119         }
12120     }
12121
12122     @Override
12123     public int setVrMode(IBinder token, boolean enabled, ComponentName packageName) {
12124         if (!mContext.getPackageManager().hasSystemFeature(PackageManager.FEATURE_VR_MODE)) {
12125             throw new UnsupportedOperationException("VR mode not supported on this device!");
12126         }
12127
12128         final VrManagerInternal vrService = LocalServices.getService(VrManagerInternal.class);
12129
12130         ActivityRecord r;
12131         synchronized (this) {
12132             r = ActivityRecord.isInStackLocked(token);
12133         }
12134
12135         if (r == null) {
12136             throw new IllegalArgumentException();
12137         }
12138
12139         int err;
12140         if ((err = vrService.hasVrPackage(packageName, r.userId)) !=
12141                 VrManagerInternal.NO_ERROR) {
12142             return err;
12143         }
12144
12145         synchronized(this) {
12146             r.requestedVrComponent = (enabled) ? packageName : null;
12147
12148             // Update associated state if this activity is currently focused
12149             if (r == mFocusedActivity) {
12150                 applyUpdateVrModeLocked(r);
12151             }
12152             return 0;
12153         }
12154     }
12155
12156     @Override
12157     public boolean isVrModePackageEnabled(ComponentName packageName) {
12158         if (!mContext.getPackageManager().hasSystemFeature(PackageManager.FEATURE_VR_MODE)) {
12159             throw new UnsupportedOperationException("VR mode not supported on this device!");
12160         }
12161
12162         final VrManagerInternal vrService = LocalServices.getService(VrManagerInternal.class);
12163
12164         return vrService.hasVrPackage(packageName, UserHandle.getCallingUserId()) ==
12165                 VrManagerInternal.NO_ERROR;
12166     }
12167
12168     public boolean isTopActivityImmersive() {
12169         enforceNotIsolatedCaller("startActivity");
12170         synchronized (this) {
12171             ActivityRecord r = getFocusedStack().topRunningActivityLocked();
12172             return (r != null) ? r.immersive : false;
12173         }
12174     }
12175
12176     @Override
12177     public boolean isTopOfTask(IBinder token) {
12178         synchronized (this) {
12179             ActivityRecord r = ActivityRecord.isInStackLocked(token);
12180             if (r == null) {
12181                 throw new IllegalArgumentException();
12182             }
12183             return r.task.getTopActivity() == r;
12184         }
12185     }
12186
12187     public final void enterSafeMode() {
12188         synchronized(this) {
12189             // It only makes sense to do this before the system is ready
12190             // and started launching other packages.
12191             if (!mSystemReady) {
12192                 try {
12193                     AppGlobals.getPackageManager().enterSafeMode();
12194                 } catch (RemoteException e) {
12195                 }
12196             }
12197
12198             mSafeMode = true;
12199         }
12200     }
12201
12202     public final void showSafeModeOverlay() {
12203         View v = LayoutInflater.from(mContext).inflate(
12204                 com.android.internal.R.layout.safe_mode, null);
12205         WindowManager.LayoutParams lp = new WindowManager.LayoutParams();
12206         lp.type = WindowManager.LayoutParams.TYPE_SECURE_SYSTEM_OVERLAY;
12207         lp.width = WindowManager.LayoutParams.WRAP_CONTENT;
12208         lp.height = WindowManager.LayoutParams.WRAP_CONTENT;
12209         lp.gravity = Gravity.BOTTOM | Gravity.START;
12210         lp.format = v.getBackground().getOpacity();
12211         lp.flags = WindowManager.LayoutParams.FLAG_NOT_FOCUSABLE
12212                 | WindowManager.LayoutParams.FLAG_NOT_TOUCHABLE;
12213         lp.privateFlags |= WindowManager.LayoutParams.PRIVATE_FLAG_SHOW_FOR_ALL_USERS;
12214         ((WindowManager)mContext.getSystemService(
12215                 Context.WINDOW_SERVICE)).addView(v, lp);
12216     }
12217
12218     public void noteWakeupAlarm(IIntentSender sender, int sourceUid, String sourcePkg, String tag) {
12219         if (sender != null && !(sender instanceof PendingIntentRecord)) {
12220             return;
12221         }
12222         final PendingIntentRecord rec = (PendingIntentRecord)sender;
12223         final BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
12224         synchronized (stats) {
12225             if (mBatteryStatsService.isOnBattery()) {
12226                 mBatteryStatsService.enforceCallingPermission();
12227                 int MY_UID = Binder.getCallingUid();
12228                 final int uid;
12229                 if (sender == null) {
12230                     uid = sourceUid;
12231                 } else {
12232                     uid = rec.uid == MY_UID ? Process.SYSTEM_UID : rec.uid;
12233                 }
12234                 BatteryStatsImpl.Uid.Pkg pkg =
12235                     stats.getPackageStatsLocked(sourceUid >= 0 ? sourceUid : uid,
12236                             sourcePkg != null ? sourcePkg : rec.key.packageName);
12237                 pkg.noteWakeupAlarmLocked(tag);
12238             }
12239         }
12240     }
12241
12242     public void noteAlarmStart(IIntentSender sender, int sourceUid, String tag) {
12243         if (sender != null && !(sender instanceof PendingIntentRecord)) {
12244             return;
12245         }
12246         final PendingIntentRecord rec = (PendingIntentRecord)sender;
12247         final BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
12248         synchronized (stats) {
12249             mBatteryStatsService.enforceCallingPermission();
12250             int MY_UID = Binder.getCallingUid();
12251             final int uid;
12252             if (sender == null) {
12253                 uid = sourceUid;
12254             } else {
12255                 uid = rec.uid == MY_UID ? Process.SYSTEM_UID : rec.uid;
12256             }
12257             mBatteryStatsService.noteAlarmStart(tag, sourceUid >= 0 ? sourceUid : uid);
12258         }
12259     }
12260
12261     public void noteAlarmFinish(IIntentSender sender, int sourceUid, String tag) {
12262         if (sender != null && !(sender instanceof PendingIntentRecord)) {
12263             return;
12264         }
12265         final PendingIntentRecord rec = (PendingIntentRecord)sender;
12266         final BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
12267         synchronized (stats) {
12268             mBatteryStatsService.enforceCallingPermission();
12269             int MY_UID = Binder.getCallingUid();
12270             final int uid;
12271             if (sender == null) {
12272                 uid = sourceUid;
12273             } else {
12274                 uid = rec.uid == MY_UID ? Process.SYSTEM_UID : rec.uid;
12275             }
12276             mBatteryStatsService.noteAlarmFinish(tag, sourceUid >= 0 ? sourceUid : uid);
12277         }
12278     }
12279
12280     public boolean killPids(int[] pids, String pReason, boolean secure) {
12281         if (Binder.getCallingUid() != Process.SYSTEM_UID) {
12282             throw new SecurityException("killPids only available to the system");
12283         }
12284         String reason = (pReason == null) ? "Unknown" : pReason;
12285         // XXX Note: don't acquire main activity lock here, because the window
12286         // manager calls in with its locks held.
12287
12288         boolean killed = false;
12289         synchronized (mPidsSelfLocked) {
12290             int worstType = 0;
12291             for (int i=0; i<pids.length; i++) {
12292                 ProcessRecord proc = mPidsSelfLocked.get(pids[i]);
12293                 if (proc != null) {
12294                     int type = proc.setAdj;
12295                     if (type > worstType) {
12296                         worstType = type;
12297                     }
12298                 }
12299             }
12300
12301             // If the worst oom_adj is somewhere in the cached proc LRU range,
12302             // then constrain it so we will kill all cached procs.
12303             if (worstType < ProcessList.CACHED_APP_MAX_ADJ
12304                     && worstType > ProcessList.CACHED_APP_MIN_ADJ) {
12305                 worstType = ProcessList.CACHED_APP_MIN_ADJ;
12306             }
12307
12308             // If this is not a secure call, don't let it kill processes that
12309             // are important.
12310             if (!secure && worstType < ProcessList.SERVICE_ADJ) {
12311                 worstType = ProcessList.SERVICE_ADJ;
12312             }
12313
12314             Slog.w(TAG, "Killing processes " + reason + " at adjustment " + worstType);
12315             for (int i=0; i<pids.length; i++) {
12316                 ProcessRecord proc = mPidsSelfLocked.get(pids[i]);
12317                 if (proc == null) {
12318                     continue;
12319                 }
12320                 int adj = proc.setAdj;
12321                 if (adj >= worstType && !proc.killedByAm) {
12322                     proc.kill(reason, true);
12323                     killed = true;
12324                 }
12325             }
12326         }
12327         return killed;
12328     }
12329
12330     @Override
12331     public void killUid(int appId, int userId, String reason) {
12332         enforceCallingPermission(Manifest.permission.KILL_UID, "killUid");
12333         synchronized (this) {
12334             final long identity = Binder.clearCallingIdentity();
12335             try {
12336                 killPackageProcessesLocked(null, appId, userId,
12337                         ProcessList.PERSISTENT_PROC_ADJ, false, true, true, true,
12338                         reason != null ? reason : "kill uid");
12339             } finally {
12340                 Binder.restoreCallingIdentity(identity);
12341             }
12342         }
12343     }
12344
12345     @Override
12346     public boolean killProcessesBelowForeground(String reason) {
12347         if (Binder.getCallingUid() != Process.SYSTEM_UID) {
12348             throw new SecurityException("killProcessesBelowForeground() only available to system");
12349         }
12350
12351         return killProcessesBelowAdj(ProcessList.FOREGROUND_APP_ADJ, reason);
12352     }
12353
12354     private boolean killProcessesBelowAdj(int belowAdj, String reason) {
12355         if (Binder.getCallingUid() != Process.SYSTEM_UID) {
12356             throw new SecurityException("killProcessesBelowAdj() only available to system");
12357         }
12358
12359         boolean killed = false;
12360         synchronized (mPidsSelfLocked) {
12361             final int size = mPidsSelfLocked.size();
12362             for (int i = 0; i < size; i++) {
12363                 final int pid = mPidsSelfLocked.keyAt(i);
12364                 final ProcessRecord proc = mPidsSelfLocked.valueAt(i);
12365                 if (proc == null) continue;
12366
12367                 final int adj = proc.setAdj;
12368                 if (adj > belowAdj && !proc.killedByAm) {
12369                     proc.kill(reason, true);
12370                     killed = true;
12371                 }
12372             }
12373         }
12374         return killed;
12375     }
12376
12377     @Override
12378     public void hang(final IBinder who, boolean allowRestart) {
12379         if (checkCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER)
12380                 != PackageManager.PERMISSION_GRANTED) {
12381             throw new SecurityException("Requires permission "
12382                     + android.Manifest.permission.SET_ACTIVITY_WATCHER);
12383         }
12384
12385         final IBinder.DeathRecipient death = new DeathRecipient() {
12386             @Override
12387             public void binderDied() {
12388                 synchronized (this) {
12389                     notifyAll();
12390                 }
12391             }
12392         };
12393
12394         try {
12395             who.linkToDeath(death, 0);
12396         } catch (RemoteException e) {
12397             Slog.w(TAG, "hang: given caller IBinder is already dead.");
12398             return;
12399         }
12400
12401         synchronized (this) {
12402             Watchdog.getInstance().setAllowRestart(allowRestart);
12403             Slog.i(TAG, "Hanging system process at request of pid " + Binder.getCallingPid());
12404             synchronized (death) {
12405                 while (who.isBinderAlive()) {
12406                     try {
12407                         death.wait();
12408                     } catch (InterruptedException e) {
12409                     }
12410                 }
12411             }
12412             Watchdog.getInstance().setAllowRestart(true);
12413         }
12414     }
12415
12416     @Override
12417     public void restart() {
12418         if (checkCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER)
12419                 != PackageManager.PERMISSION_GRANTED) {
12420             throw new SecurityException("Requires permission "
12421                     + android.Manifest.permission.SET_ACTIVITY_WATCHER);
12422         }
12423
12424         Log.i(TAG, "Sending shutdown broadcast...");
12425
12426         BroadcastReceiver br = new BroadcastReceiver() {
12427             @Override public void onReceive(Context context, Intent intent) {
12428                 // Now the broadcast is done, finish up the low-level shutdown.
12429                 Log.i(TAG, "Shutting down activity manager...");
12430                 shutdown(10000);
12431                 Log.i(TAG, "Shutdown complete, restarting!");
12432                 Process.killProcess(Process.myPid());
12433                 System.exit(10);
12434             }
12435         };
12436
12437         // First send the high-level shut down broadcast.
12438         Intent intent = new Intent(Intent.ACTION_SHUTDOWN);
12439         intent.addFlags(Intent.FLAG_RECEIVER_FOREGROUND);
12440         intent.putExtra(Intent.EXTRA_SHUTDOWN_USERSPACE_ONLY, true);
12441         /* For now we are not doing a clean shutdown, because things seem to get unhappy.
12442         mContext.sendOrderedBroadcastAsUser(intent,
12443                 UserHandle.ALL, null, br, mHandler, 0, null, null);
12444         */
12445         br.onReceive(mContext, intent);
12446     }
12447
12448     private long getLowRamTimeSinceIdle(long now) {
12449         return mLowRamTimeSinceLastIdle + (mLowRamStartTime > 0 ? (now-mLowRamStartTime) : 0);
12450     }
12451
12452     @Override
12453     public void performIdleMaintenance() {
12454         if (checkCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER)
12455                 != PackageManager.PERMISSION_GRANTED) {
12456             throw new SecurityException("Requires permission "
12457                     + android.Manifest.permission.SET_ACTIVITY_WATCHER);
12458         }
12459
12460         synchronized (this) {
12461             final long now = SystemClock.uptimeMillis();
12462             final long timeSinceLastIdle = now - mLastIdleTime;
12463             final long lowRamSinceLastIdle = getLowRamTimeSinceIdle(now);
12464             mLastIdleTime = now;
12465             mLowRamTimeSinceLastIdle = 0;
12466             if (mLowRamStartTime != 0) {
12467                 mLowRamStartTime = now;
12468             }
12469
12470             StringBuilder sb = new StringBuilder(128);
12471             sb.append("Idle maintenance over ");
12472             TimeUtils.formatDuration(timeSinceLastIdle, sb);
12473             sb.append(" low RAM for ");
12474             TimeUtils.formatDuration(lowRamSinceLastIdle, sb);
12475             Slog.i(TAG, sb.toString());
12476
12477             // If at least 1/3 of our time since the last idle period has been spent
12478             // with RAM low, then we want to kill processes.
12479             boolean doKilling = lowRamSinceLastIdle > (timeSinceLastIdle/3);
12480
12481             for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) {
12482                 ProcessRecord proc = mLruProcesses.get(i);
12483                 if (proc.notCachedSinceIdle) {
12484                     if (proc.setProcState != ActivityManager.PROCESS_STATE_TOP_SLEEPING
12485                             && proc.setProcState >= ActivityManager.PROCESS_STATE_FOREGROUND_SERVICE
12486                             && proc.setProcState <= ActivityManager.PROCESS_STATE_SERVICE) {
12487                         if (doKilling && proc.initialIdlePss != 0
12488                                 && proc.lastPss > ((proc.initialIdlePss*3)/2)) {
12489                             sb = new StringBuilder(128);
12490                             sb.append("Kill");
12491                             sb.append(proc.processName);
12492                             sb.append(" in idle maint: pss=");
12493                             sb.append(proc.lastPss);
12494                             sb.append(", swapPss=");
12495                             sb.append(proc.lastSwapPss);
12496                             sb.append(", initialPss=");
12497                             sb.append(proc.initialIdlePss);
12498                             sb.append(", period=");
12499                             TimeUtils.formatDuration(timeSinceLastIdle, sb);
12500                             sb.append(", lowRamPeriod=");
12501                             TimeUtils.formatDuration(lowRamSinceLastIdle, sb);
12502                             Slog.wtfQuiet(TAG, sb.toString());
12503                             proc.kill("idle maint (pss " + proc.lastPss
12504                                     + " from " + proc.initialIdlePss + ")", true);
12505                         }
12506                     }
12507                 } else if (proc.setProcState < ActivityManager.PROCESS_STATE_HOME
12508                         && proc.setProcState > ActivityManager.PROCESS_STATE_NONEXISTENT) {
12509                     proc.notCachedSinceIdle = true;
12510                     proc.initialIdlePss = 0;
12511                     proc.nextPssTime = ProcessList.computeNextPssTime(proc.setProcState, true,
12512                             mTestPssMode, isSleeping(), now);
12513                 }
12514             }
12515
12516             mHandler.removeMessages(REQUEST_ALL_PSS_MSG);
12517             mHandler.sendEmptyMessageDelayed(REQUEST_ALL_PSS_MSG, 2*60*1000);
12518         }
12519     }
12520
12521     private void retrieveSettings() {
12522         final ContentResolver resolver = mContext.getContentResolver();
12523         final boolean freeformWindowManagement =
12524                 mContext.getPackageManager().hasSystemFeature(FEATURE_FREEFORM_WINDOW_MANAGEMENT)
12525                         || Settings.Global.getInt(
12526                                 resolver, DEVELOPMENT_ENABLE_FREEFORM_WINDOWS_SUPPORT, 0) != 0;
12527         final boolean supportsPictureInPicture =
12528                 mContext.getPackageManager().hasSystemFeature(FEATURE_PICTURE_IN_PICTURE);
12529
12530         final boolean supportsMultiWindow = ActivityManager.supportsMultiWindow();
12531         final String debugApp = Settings.Global.getString(resolver, DEBUG_APP);
12532         final boolean waitForDebugger = Settings.Global.getInt(resolver, WAIT_FOR_DEBUGGER, 0) != 0;
12533         final boolean alwaysFinishActivities =
12534                 Settings.Global.getInt(resolver, ALWAYS_FINISH_ACTIVITIES, 0) != 0;
12535         final boolean lenientBackgroundCheck =
12536                 Settings.Global.getInt(resolver, LENIENT_BACKGROUND_CHECK, 0) != 0;
12537         final boolean forceRtl = Settings.Global.getInt(resolver, DEVELOPMENT_FORCE_RTL, 0) != 0;
12538         final boolean forceResizable = Settings.Global.getInt(
12539                 resolver, DEVELOPMENT_FORCE_RESIZABLE_ACTIVITIES, 0) != 0;
12540         // Transfer any global setting for forcing RTL layout, into a System Property
12541         SystemProperties.set(DEVELOPMENT_FORCE_RTL, forceRtl ? "1":"0");
12542
12543         final Configuration configuration = new Configuration();
12544         Settings.System.getConfiguration(resolver, configuration);
12545         if (forceRtl) {
12546             // This will take care of setting the correct layout direction flags
12547             configuration.setLayoutDirection(configuration.locale);
12548         }
12549
12550         synchronized (this) {
12551             mDebugApp = mOrigDebugApp = debugApp;
12552             mWaitForDebugger = mOrigWaitForDebugger = waitForDebugger;
12553             mAlwaysFinishActivities = alwaysFinishActivities;
12554             mLenientBackgroundCheck = lenientBackgroundCheck;
12555             mForceResizableActivities = forceResizable;
12556             mWindowManager.setForceResizableTasks(mForceResizableActivities);
12557             if (supportsMultiWindow || forceResizable) {
12558                 mSupportsMultiWindow = true;
12559                 mSupportsFreeformWindowManagement = freeformWindowManagement || forceResizable;
12560                 mSupportsPictureInPicture = supportsPictureInPicture || forceResizable;
12561             } else {
12562                 mSupportsMultiWindow = false;
12563                 mSupportsFreeformWindowManagement = false;
12564                 mSupportsPictureInPicture = false;
12565             }
12566             // This happens before any activities are started, so we can
12567             // change mConfiguration in-place.
12568             updateConfigurationLocked(configuration, null, true);
12569             if (DEBUG_CONFIGURATION) Slog.v(TAG_CONFIGURATION,
12570                     "Initial config: " + mConfiguration);
12571
12572             // Load resources only after the current configuration has been set.
12573             final Resources res = mContext.getResources();
12574             mHasRecents = res.getBoolean(com.android.internal.R.bool.config_hasRecents);
12575             mThumbnailWidth = res.getDimensionPixelSize(
12576                     com.android.internal.R.dimen.thumbnail_width);
12577             mThumbnailHeight = res.getDimensionPixelSize(
12578                     com.android.internal.R.dimen.thumbnail_height);
12579             mDefaultPinnedStackBounds = Rect.unflattenFromString(res.getString(
12580                     com.android.internal.R.string.config_defaultPictureInPictureBounds));
12581             mAppErrors.loadAppsNotReportingCrashesFromConfigLocked(res.getString(
12582                     com.android.internal.R.string.config_appsNotReportingCrashes));
12583         }
12584     }
12585
12586     public boolean testIsSystemReady() {
12587         // no need to synchronize(this) just to read & return the value
12588         return mSystemReady;
12589     }
12590
12591     private static File getCalledPreBootReceiversFile() {
12592         File dataDir = Environment.getDataDirectory();
12593         File systemDir = new File(dataDir, "system");
12594         File fname = new File(systemDir, CALLED_PRE_BOOTS_FILENAME);
12595         return fname;
12596     }
12597
12598     private static ArrayList<ComponentName> readLastDonePreBootReceivers() {
12599         ArrayList<ComponentName> lastDoneReceivers = new ArrayList<ComponentName>();
12600         File file = getCalledPreBootReceiversFile();
12601         FileInputStream fis = null;
12602         try {
12603             fis = new FileInputStream(file);
12604             DataInputStream dis = new DataInputStream(new BufferedInputStream(fis, 2048));
12605             int fvers = dis.readInt();
12606             if (fvers == LAST_PREBOOT_DELIVERED_FILE_VERSION) {
12607                 String vers = dis.readUTF();
12608                 String codename = dis.readUTF();
12609                 String build = dis.readUTF();
12610                 if (android.os.Build.VERSION.RELEASE.equals(vers)
12611                         && android.os.Build.VERSION.CODENAME.equals(codename)
12612                         && android.os.Build.VERSION.INCREMENTAL.equals(build)) {
12613                     int num = dis.readInt();
12614                     while (num > 0) {
12615                         num--;
12616                         String pkg = dis.readUTF();
12617                         String cls = dis.readUTF();
12618                         lastDoneReceivers.add(new ComponentName(pkg, cls));
12619                     }
12620                 }
12621             }
12622         } catch (FileNotFoundException e) {
12623         } catch (IOException e) {
12624             Slog.w(TAG, "Failure reading last done pre-boot receivers", e);
12625         } finally {
12626             if (fis != null) {
12627                 try {
12628                     fis.close();
12629                 } catch (IOException e) {
12630                 }
12631             }
12632         }
12633         return lastDoneReceivers;
12634     }
12635
12636     private static void writeLastDonePreBootReceivers(ArrayList<ComponentName> list) {
12637         File file = getCalledPreBootReceiversFile();
12638         FileOutputStream fos = null;
12639         DataOutputStream dos = null;
12640         try {
12641             fos = new FileOutputStream(file);
12642             dos = new DataOutputStream(new BufferedOutputStream(fos, 2048));
12643             dos.writeInt(LAST_PREBOOT_DELIVERED_FILE_VERSION);
12644             dos.writeUTF(android.os.Build.VERSION.RELEASE);
12645             dos.writeUTF(android.os.Build.VERSION.CODENAME);
12646             dos.writeUTF(android.os.Build.VERSION.INCREMENTAL);
12647             dos.writeInt(list.size());
12648             for (int i=0; i<list.size(); i++) {
12649                 dos.writeUTF(list.get(i).getPackageName());
12650                 dos.writeUTF(list.get(i).getClassName());
12651             }
12652         } catch (IOException e) {
12653             Slog.w(TAG, "Failure writing last done pre-boot receivers", e);
12654             file.delete();
12655         } finally {
12656             FileUtils.sync(fos);
12657             if (dos != null) {
12658                 try {
12659                     dos.close();
12660                 } catch (IOException e) {
12661                     // TODO Auto-generated catch block
12662                     e.printStackTrace();
12663                 }
12664             }
12665         }
12666     }
12667
12668     final class PreBootContinuation extends IIntentReceiver.Stub {
12669         final Intent intent;
12670         final Runnable onFinishCallback;
12671         final ArrayList<ComponentName> doneReceivers;
12672         final List<ResolveInfo> ris;
12673         final int[] users;
12674         int lastRi = -1;
12675         int curRi = 0;
12676         int curUser = 0;
12677
12678         PreBootContinuation(Intent _intent, Runnable _onFinishCallback,
12679                 ArrayList<ComponentName> _doneReceivers, List<ResolveInfo> _ris, int[] _users) {
12680             intent = _intent;
12681             onFinishCallback = _onFinishCallback;
12682             doneReceivers = _doneReceivers;
12683             ris = _ris;
12684             users = _users;
12685         }
12686
12687         void go() {
12688             if (lastRi != curRi) {
12689                 ActivityInfo ai = ris.get(curRi).activityInfo;
12690                 ComponentName comp = new ComponentName(ai.packageName, ai.name);
12691                 intent.setComponent(comp);
12692                 doneReceivers.add(comp);
12693                 lastRi = curRi;
12694                 CharSequence label = ai.loadLabel(mContext.getPackageManager());
12695                 showBootMessage(mContext.getString(R.string.android_preparing_apk, label), false);
12696             }
12697             Slog.i(TAG, "Pre-boot of " + intent.getComponent().toShortString()
12698                     + " for user " + users[curUser]);
12699             EventLogTags.writeAmPreBoot(users[curUser], intent.getComponent().getPackageName());
12700             broadcastIntentLocked(null, null, intent, null, this,
12701                     0, null, null, null, AppOpsManager.OP_NONE,
12702                     null, true, false, MY_PID, Process.SYSTEM_UID, users[curUser]);
12703         }
12704
12705         public void performReceive(Intent intent, int resultCode,
12706                 String data, Bundle extras, boolean ordered,
12707                 boolean sticky, int sendingUser) {
12708             curUser++;
12709             if (curUser >= users.length) {
12710                 curUser = 0;
12711                 curRi++;
12712                 if (curRi >= ris.size()) {
12713                     // All done sending broadcasts!
12714                     if (onFinishCallback != null) {
12715                         // The raw IIntentReceiver interface is called
12716                         // with the AM lock held, so redispatch to
12717                         // execute our code without the lock.
12718                         mHandler.post(onFinishCallback);
12719                     }
12720                     return;
12721                 }
12722             }
12723             go();
12724         }
12725     }
12726
12727     private boolean deliverPreBootCompleted(final Runnable onFinishCallback,
12728             ArrayList<ComponentName> doneReceivers) {
12729         Intent intent = new Intent(Intent.ACTION_PRE_BOOT_COMPLETED);
12730         List<ResolveInfo> ris = null;
12731         try {
12732             ris = AppGlobals.getPackageManager().queryIntentReceivers(
12733                     intent, null, MATCH_SYSTEM_ONLY, UserHandle.USER_SYSTEM).getList();
12734         } catch (RemoteException e) {
12735         }
12736         if (ris == null) {
12737             return false;
12738         }
12739         intent.addFlags(Intent.FLAG_RECEIVER_BOOT_UPGRADE | Intent.FLAG_DEBUG_TRIAGED_MISSING);
12740
12741         ArrayList<ComponentName> lastDoneReceivers = readLastDonePreBootReceivers();
12742         for (int i=0; i<ris.size(); i++) {
12743             ActivityInfo ai = ris.get(i).activityInfo;
12744             ComponentName comp = new ComponentName(ai.packageName, ai.name);
12745             if (lastDoneReceivers.contains(comp)) {
12746                 // We already did the pre boot receiver for this app with the current
12747                 // platform version, so don't do it again...
12748                 ris.remove(i);
12749                 i--;
12750                 // ...however, do keep it as one that has been done, so we don't
12751                 // forget about it when rewriting the file of last done receivers.
12752                 doneReceivers.add(comp);
12753             }
12754         }
12755
12756         if (ris.size() <= 0) {
12757             return false;
12758         }
12759
12760         // TODO: can we still do this with per user encryption?
12761         final int[] users = mUserController.getUsers();
12762         if (users.length <= 0) {
12763             return false;
12764         }
12765
12766         PreBootContinuation cont = new PreBootContinuation(intent, onFinishCallback, doneReceivers,
12767                 ris, users);
12768         cont.go();
12769         return true;
12770     }
12771
12772     public void systemReady(final Runnable goingCallback) {
12773         synchronized(this) {
12774             if (mSystemReady) {
12775                 // If we're done calling all the receivers, run the next "boot phase" passed in
12776                 // by the SystemServer
12777                 if (goingCallback != null) {
12778                     goingCallback.run();
12779                 }
12780                 return;
12781             }
12782
12783             mLocalDeviceIdleController
12784                     = LocalServices.getService(DeviceIdleController.LocalService.class);
12785
12786             // Make sure we have the current profile info, since it is needed for security checks.
12787             mUserController.onSystemReady();
12788
12789             mRecentTasks.onSystemReadyLocked();
12790             // Check to see if there are any update receivers to run.
12791             if (!mDidUpdate) {
12792                 if (mWaitingUpdate) {
12793                     return;
12794                 }
12795                 final ArrayList<ComponentName> doneReceivers = new ArrayList<ComponentName>();
12796                 mWaitingUpdate = deliverPreBootCompleted(new Runnable() {
12797                     public void run() {
12798                         synchronized (ActivityManagerService.this) {
12799                             mDidUpdate = true;
12800                         }
12801                         showBootMessage(mContext.getText(
12802                                 R.string.android_upgrading_complete),
12803                                 false);
12804                         writeLastDonePreBootReceivers(doneReceivers);
12805                         systemReady(goingCallback);
12806                     }
12807                 }, doneReceivers);
12808
12809                 if (mWaitingUpdate) {
12810                     return;
12811                 }
12812                 mDidUpdate = true;
12813             }
12814
12815             mAppOpsService.systemReady();
12816             mSystemReady = true;
12817         }
12818
12819         ArrayList<ProcessRecord> procsToKill = null;
12820         synchronized(mPidsSelfLocked) {
12821             for (int i=mPidsSelfLocked.size()-1; i>=0; i--) {
12822                 ProcessRecord proc = mPidsSelfLocked.valueAt(i);
12823                 if (!isAllowedWhileBooting(proc.info)){
12824                     if (procsToKill == null) {
12825                         procsToKill = new ArrayList<ProcessRecord>();
12826                     }
12827                     procsToKill.add(proc);
12828                 }
12829             }
12830         }
12831
12832         synchronized(this) {
12833             if (procsToKill != null) {
12834                 for (int i=procsToKill.size()-1; i>=0; i--) {
12835                     ProcessRecord proc = procsToKill.get(i);
12836                     Slog.i(TAG, "Removing system update proc: " + proc);
12837                     removeProcessLocked(proc, true, false, "system update done");
12838                 }
12839             }
12840
12841             // Now that we have cleaned up any update processes, we
12842             // are ready to start launching real processes and know that
12843             // we won't trample on them any more.
12844             mProcessesReady = true;
12845         }
12846
12847         Slog.i(TAG, "System now ready");
12848         EventLog.writeEvent(EventLogTags.BOOT_PROGRESS_AMS_READY,
12849             SystemClock.uptimeMillis());
12850
12851         synchronized(this) {
12852             // Make sure we have no pre-ready processes sitting around.
12853
12854             if (mFactoryTest == FactoryTest.FACTORY_TEST_LOW_LEVEL) {
12855                 ResolveInfo ri = mContext.getPackageManager()
12856                         .resolveActivity(new Intent(Intent.ACTION_FACTORY_TEST),
12857                                 STOCK_PM_FLAGS);
12858                 CharSequence errorMsg = null;
12859                 if (ri != null) {
12860                     ActivityInfo ai = ri.activityInfo;
12861                     ApplicationInfo app = ai.applicationInfo;
12862                     if ((app.flags&ApplicationInfo.FLAG_SYSTEM) != 0) {
12863                         mTopAction = Intent.ACTION_FACTORY_TEST;
12864                         mTopData = null;
12865                         mTopComponent = new ComponentName(app.packageName,
12866                                 ai.name);
12867                     } else {
12868                         errorMsg = mContext.getResources().getText(
12869                                 com.android.internal.R.string.factorytest_not_system);
12870                     }
12871                 } else {
12872                     errorMsg = mContext.getResources().getText(
12873                             com.android.internal.R.string.factorytest_no_action);
12874                 }
12875                 if (errorMsg != null) {
12876                     mTopAction = null;
12877                     mTopData = null;
12878                     mTopComponent = null;
12879                     Message msg = Message.obtain();
12880                     msg.what = SHOW_FACTORY_ERROR_UI_MSG;
12881                     msg.getData().putCharSequence("msg", errorMsg);
12882                     mUiHandler.sendMessage(msg);
12883                 }
12884             }
12885         }
12886
12887         retrieveSettings();
12888         final int currentUserId;
12889         synchronized (this) {
12890             currentUserId = mUserController.getCurrentUserIdLocked();
12891             readGrantedUriPermissionsLocked();
12892         }
12893
12894         if (goingCallback != null) goingCallback.run();
12895
12896         mBatteryStatsService.noteEvent(BatteryStats.HistoryItem.EVENT_USER_RUNNING_START,
12897                 Integer.toString(currentUserId), currentUserId);
12898         mBatteryStatsService.noteEvent(BatteryStats.HistoryItem.EVENT_USER_FOREGROUND_START,
12899                 Integer.toString(currentUserId), currentUserId);
12900         mSystemServiceManager.startUser(currentUserId);
12901
12902         synchronized (this) {
12903             // Only start up encryption-aware persistent apps; once user is
12904             // unlocked we'll come back around and start unaware apps
12905             startPersistentApps(PackageManager.MATCH_DIRECT_BOOT_AWARE);
12906
12907             // Start up initial activity.
12908             mBooting = true;
12909             // Enable home activity for system user, so that the system can always boot
12910             if (UserManager.isSplitSystemUser()) {
12911                 ComponentName cName = new ComponentName(mContext, SystemUserHomeActivity.class);
12912                 try {
12913                     AppGlobals.getPackageManager().setComponentEnabledSetting(cName,
12914                             PackageManager.COMPONENT_ENABLED_STATE_ENABLED, 0,
12915                             UserHandle.USER_SYSTEM);
12916                 } catch (RemoteException e) {
12917                     throw e.rethrowAsRuntimeException();
12918                 }
12919             }
12920             startHomeActivityLocked(currentUserId, "systemReady");
12921
12922             try {
12923                 if (AppGlobals.getPackageManager().hasSystemUidErrors()) {
12924                     Slog.e(TAG, "UIDs on the system are inconsistent, you need to wipe your"
12925                             + " data partition or your device will be unstable.");
12926                     mUiHandler.obtainMessage(SHOW_UID_ERROR_UI_MSG).sendToTarget();
12927                 }
12928             } catch (RemoteException e) {
12929             }
12930
12931             if (!Build.isBuildConsistent()) {
12932                 Slog.e(TAG, "Build fingerprint is not consistent, warning user");
12933                 mUiHandler.obtainMessage(SHOW_FINGERPRINT_ERROR_UI_MSG).sendToTarget();
12934             }
12935
12936             long ident = Binder.clearCallingIdentity();
12937             try {
12938                 Intent intent = new Intent(Intent.ACTION_USER_STARTED);
12939                 intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY
12940                         | Intent.FLAG_RECEIVER_FOREGROUND);
12941                 intent.putExtra(Intent.EXTRA_USER_HANDLE, currentUserId);
12942                 broadcastIntentLocked(null, null, intent,
12943                         null, null, 0, null, null, null, AppOpsManager.OP_NONE,
12944                         null, false, false, MY_PID, Process.SYSTEM_UID,
12945                         currentUserId);
12946                 intent = new Intent(Intent.ACTION_USER_STARTING);
12947                 intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY);
12948                 intent.putExtra(Intent.EXTRA_USER_HANDLE, currentUserId);
12949                 broadcastIntentLocked(null, null, intent,
12950                         null, new IIntentReceiver.Stub() {
12951                             @Override
12952                             public void performReceive(Intent intent, int resultCode, String data,
12953                                     Bundle extras, boolean ordered, boolean sticky, int sendingUser)
12954                                     throws RemoteException {
12955                             }
12956                         }, 0, null, null,
12957                         new String[] {INTERACT_ACROSS_USERS}, AppOpsManager.OP_NONE,
12958                         null, true, false, MY_PID, Process.SYSTEM_UID, UserHandle.USER_ALL);
12959             } catch (Throwable t) {
12960                 Slog.wtf(TAG, "Failed sending first user broadcasts", t);
12961             } finally {
12962                 Binder.restoreCallingIdentity(ident);
12963             }
12964             mStackSupervisor.resumeFocusedStackTopActivityLocked();
12965             mUserController.sendUserSwitchBroadcastsLocked(-1, currentUserId);
12966         }
12967     }
12968
12969     void killAppAtUsersRequest(ProcessRecord app, Dialog fromDialog) {
12970         synchronized (this) {
12971             mAppErrors.killAppAtUserRequestLocked(app, fromDialog);
12972         }
12973     }
12974
12975     void skipCurrentReceiverLocked(ProcessRecord app) {
12976         for (BroadcastQueue queue : mBroadcastQueues) {
12977             queue.skipCurrentReceiverLocked(app);
12978         }
12979     }
12980
12981     /**
12982      * Used by {@link com.android.internal.os.RuntimeInit} to report when an application crashes.
12983      * The application process will exit immediately after this call returns.
12984      * @param app object of the crashing app, null for the system server
12985      * @param crashInfo describing the exception
12986      */
12987     public void handleApplicationCrash(IBinder app, ApplicationErrorReport.CrashInfo crashInfo) {
12988         ProcessRecord r = findAppProcess(app, "Crash");
12989         final String processName = app == null ? "system_server"
12990                 : (r == null ? "unknown" : r.processName);
12991
12992         handleApplicationCrashInner("crash", r, processName, crashInfo);
12993     }
12994
12995     /* Native crash reporting uses this inner version because it needs to be somewhat
12996      * decoupled from the AM-managed cleanup lifecycle
12997      */
12998     void handleApplicationCrashInner(String eventType, ProcessRecord r, String processName,
12999             ApplicationErrorReport.CrashInfo crashInfo) {
13000         EventLog.writeEvent(EventLogTags.AM_CRASH, Binder.getCallingPid(),
13001                 UserHandle.getUserId(Binder.getCallingUid()), processName,
13002                 r == null ? -1 : r.info.flags,
13003                 crashInfo.exceptionClassName,
13004                 crashInfo.exceptionMessage,
13005                 crashInfo.throwFileName,
13006                 crashInfo.throwLineNumber);
13007
13008         addErrorToDropBox(eventType, r, processName, null, null, null, null, null, crashInfo);
13009
13010         mAppErrors.crashApplication(r, crashInfo);
13011     }
13012
13013     public void handleApplicationStrictModeViolation(
13014             IBinder app,
13015             int violationMask,
13016             StrictMode.ViolationInfo info) {
13017         ProcessRecord r = findAppProcess(app, "StrictMode");
13018         if (r == null) {
13019             return;
13020         }
13021
13022         if ((violationMask & StrictMode.PENALTY_DROPBOX) != 0) {
13023             Integer stackFingerprint = info.hashCode();
13024             boolean logIt = true;
13025             synchronized (mAlreadyLoggedViolatedStacks) {
13026                 if (mAlreadyLoggedViolatedStacks.contains(stackFingerprint)) {
13027                     logIt = false;
13028                     // TODO: sub-sample into EventLog for these, with
13029                     // the info.durationMillis?  Then we'd get
13030                     // the relative pain numbers, without logging all
13031                     // the stack traces repeatedly.  We'd want to do
13032                     // likewise in the client code, which also does
13033                     // dup suppression, before the Binder call.
13034                 } else {
13035                     if (mAlreadyLoggedViolatedStacks.size() >= MAX_DUP_SUPPRESSED_STACKS) {
13036                         mAlreadyLoggedViolatedStacks.clear();
13037                     }
13038                     mAlreadyLoggedViolatedStacks.add(stackFingerprint);
13039                 }
13040             }
13041             if (logIt) {
13042                 logStrictModeViolationToDropBox(r, info);
13043             }
13044         }
13045
13046         if ((violationMask & StrictMode.PENALTY_DIALOG) != 0) {
13047             AppErrorResult result = new AppErrorResult();
13048             synchronized (this) {
13049                 final long origId = Binder.clearCallingIdentity();
13050
13051                 Message msg = Message.obtain();
13052                 msg.what = SHOW_STRICT_MODE_VIOLATION_UI_MSG;
13053                 HashMap<String, Object> data = new HashMap<String, Object>();
13054                 data.put("result", result);
13055                 data.put("app", r);
13056                 data.put("violationMask", violationMask);
13057                 data.put("info", info);
13058                 msg.obj = data;
13059                 mUiHandler.sendMessage(msg);
13060
13061                 Binder.restoreCallingIdentity(origId);
13062             }
13063             int res = result.get();
13064             Slog.w(TAG, "handleApplicationStrictModeViolation; res=" + res);
13065         }
13066     }
13067
13068     // Depending on the policy in effect, there could be a bunch of
13069     // these in quick succession so we try to batch these together to
13070     // minimize disk writes, number of dropbox entries, and maximize
13071     // compression, by having more fewer, larger records.
13072     private void logStrictModeViolationToDropBox(
13073             ProcessRecord process,
13074             StrictMode.ViolationInfo info) {
13075         if (info == null) {
13076             return;
13077         }
13078         final boolean isSystemApp = process == null ||
13079                 (process.info.flags & (ApplicationInfo.FLAG_SYSTEM |
13080                                        ApplicationInfo.FLAG_UPDATED_SYSTEM_APP)) != 0;
13081         final String processName = process == null ? "unknown" : process.processName;
13082         final String dropboxTag = isSystemApp ? "system_app_strictmode" : "data_app_strictmode";
13083         final DropBoxManager dbox = (DropBoxManager)
13084                 mContext.getSystemService(Context.DROPBOX_SERVICE);
13085
13086         // Exit early if the dropbox isn't configured to accept this report type.
13087         if (dbox == null || !dbox.isTagEnabled(dropboxTag)) return;
13088
13089         boolean bufferWasEmpty;
13090         boolean needsFlush;
13091         final StringBuilder sb = isSystemApp ? mStrictModeBuffer : new StringBuilder(1024);
13092         synchronized (sb) {
13093             bufferWasEmpty = sb.length() == 0;
13094             appendDropBoxProcessHeaders(process, processName, sb);
13095             sb.append("Build: ").append(Build.FINGERPRINT).append("\n");
13096             sb.append("System-App: ").append(isSystemApp).append("\n");
13097             sb.append("Uptime-Millis: ").append(info.violationUptimeMillis).append("\n");
13098             if (info.violationNumThisLoop != 0) {
13099                 sb.append("Loop-Violation-Number: ").append(info.violationNumThisLoop).append("\n");
13100             }
13101             if (info.numAnimationsRunning != 0) {
13102                 sb.append("Animations-Running: ").append(info.numAnimationsRunning).append("\n");
13103             }
13104             if (info.broadcastIntentAction != null) {
13105                 sb.append("Broadcast-Intent-Action: ").append(info.broadcastIntentAction).append("\n");
13106             }
13107             if (info.durationMillis != -1) {
13108                 sb.append("Duration-Millis: ").append(info.durationMillis).append("\n");
13109             }
13110             if (info.numInstances != -1) {
13111                 sb.append("Instance-Count: ").append(info.numInstances).append("\n");
13112             }
13113             if (info.tags != null) {
13114                 for (String tag : info.tags) {
13115                     sb.append("Span-Tag: ").append(tag).append("\n");
13116                 }
13117             }
13118             sb.append("\n");
13119             if (info.crashInfo != null && info.crashInfo.stackTrace != null) {
13120                 sb.append(info.crashInfo.stackTrace);
13121                 sb.append("\n");
13122             }
13123             if (info.message != null) {
13124                 sb.append(info.message);
13125                 sb.append("\n");
13126             }
13127
13128             // Only buffer up to ~64k.  Various logging bits truncate
13129             // things at 128k.
13130             needsFlush = (sb.length() > 64 * 1024);
13131         }
13132
13133         // Flush immediately if the buffer's grown too large, or this
13134         // is a non-system app.  Non-system apps are isolated with a
13135         // different tag & policy and not batched.
13136         //
13137         // Batching is useful during internal testing with
13138         // StrictMode settings turned up high.  Without batching,
13139         // thousands of separate files could be created on boot.
13140         if (!isSystemApp || needsFlush) {
13141             new Thread("Error dump: " + dropboxTag) {
13142                 @Override
13143                 public void run() {
13144                     String report;
13145                     synchronized (sb) {
13146                         report = sb.toString();
13147                         sb.delete(0, sb.length());
13148                         sb.trimToSize();
13149                     }
13150                     if (report.length() != 0) {
13151                         dbox.addText(dropboxTag, report);
13152                     }
13153                 }
13154             }.start();
13155             return;
13156         }
13157
13158         // System app batching:
13159         if (!bufferWasEmpty) {
13160             // An existing dropbox-writing thread is outstanding, so
13161             // we don't need to start it up.  The existing thread will
13162             // catch the buffer appends we just did.
13163             return;
13164         }
13165
13166         // Worker thread to both batch writes and to avoid blocking the caller on I/O.
13167         // (After this point, we shouldn't access AMS internal data structures.)
13168         new Thread("Error dump: " + dropboxTag) {
13169             @Override
13170             public void run() {
13171                 // 5 second sleep to let stacks arrive and be batched together
13172                 try {
13173                     Thread.sleep(5000);  // 5 seconds
13174                 } catch (InterruptedException e) {}
13175
13176                 String errorReport;
13177                 synchronized (mStrictModeBuffer) {
13178                     errorReport = mStrictModeBuffer.toString();
13179                     if (errorReport.length() == 0) {
13180                         return;
13181                     }
13182                     mStrictModeBuffer.delete(0, mStrictModeBuffer.length());
13183                     mStrictModeBuffer.trimToSize();
13184                 }
13185                 dbox.addText(dropboxTag, errorReport);
13186             }
13187         }.start();
13188     }
13189
13190     /**
13191      * Used by {@link Log} via {@link com.android.internal.os.RuntimeInit} to report serious errors.
13192      * @param app object of the crashing app, null for the system server
13193      * @param tag reported by the caller
13194      * @param system whether this wtf is coming from the system
13195      * @param crashInfo describing the context of the error
13196      * @return true if the process should exit immediately (WTF is fatal)
13197      */
13198     public boolean handleApplicationWtf(final IBinder app, final String tag, boolean system,
13199             final ApplicationErrorReport.CrashInfo crashInfo) {
13200         final int callingUid = Binder.getCallingUid();
13201         final int callingPid = Binder.getCallingPid();
13202
13203         if (system) {
13204             // If this is coming from the system, we could very well have low-level
13205             // system locks held, so we want to do this all asynchronously.  And we
13206             // never want this to become fatal, so there is that too.
13207             mHandler.post(new Runnable() {
13208                 @Override public void run() {
13209                     handleApplicationWtfInner(callingUid, callingPid, app, tag, crashInfo);
13210                 }
13211             });
13212             return false;
13213         }
13214
13215         final ProcessRecord r = handleApplicationWtfInner(callingUid, callingPid, app, tag,
13216                 crashInfo);
13217
13218         if (r != null && r.pid != Process.myPid() &&
13219                 Settings.Global.getInt(mContext.getContentResolver(),
13220                         Settings.Global.WTF_IS_FATAL, 0) != 0) {
13221             mAppErrors.crashApplication(r, crashInfo);
13222             return true;
13223         } else {
13224             return false;
13225         }
13226     }
13227
13228     ProcessRecord handleApplicationWtfInner(int callingUid, int callingPid, IBinder app, String tag,
13229             final ApplicationErrorReport.CrashInfo crashInfo) {
13230         final ProcessRecord r = findAppProcess(app, "WTF");
13231         final String processName = app == null ? "system_server"
13232                 : (r == null ? "unknown" : r.processName);
13233
13234         EventLog.writeEvent(EventLogTags.AM_WTF, UserHandle.getUserId(callingUid), callingPid,
13235                 processName, r == null ? -1 : r.info.flags, tag, crashInfo.exceptionMessage);
13236
13237         addErrorToDropBox("wtf", r, processName, null, null, tag, null, null, crashInfo);
13238
13239         return r;
13240     }
13241
13242     /**
13243      * @param app object of some object (as stored in {@link com.android.internal.os.RuntimeInit})
13244      * @return the corresponding {@link ProcessRecord} object, or null if none could be found
13245      */
13246     private ProcessRecord findAppProcess(IBinder app, String reason) {
13247         if (app == null) {
13248             return null;
13249         }
13250
13251         synchronized (this) {
13252             final int NP = mProcessNames.getMap().size();
13253             for (int ip=0; ip<NP; ip++) {
13254                 SparseArray<ProcessRecord> apps = mProcessNames.getMap().valueAt(ip);
13255                 final int NA = apps.size();
13256                 for (int ia=0; ia<NA; ia++) {
13257                     ProcessRecord p = apps.valueAt(ia);
13258                     if (p.thread != null && p.thread.asBinder() == app) {
13259                         return p;
13260                     }
13261                 }
13262             }
13263
13264             Slog.w(TAG, "Can't find mystery application for " + reason
13265                     + " from pid=" + Binder.getCallingPid()
13266                     + " uid=" + Binder.getCallingUid() + ": " + app);
13267             return null;
13268         }
13269     }
13270
13271     /**
13272      * Utility function for addErrorToDropBox and handleStrictModeViolation's logging
13273      * to append various headers to the dropbox log text.
13274      */
13275     private void appendDropBoxProcessHeaders(ProcessRecord process, String processName,
13276             StringBuilder sb) {
13277         // Watchdog thread ends up invoking this function (with
13278         // a null ProcessRecord) to add the stack file to dropbox.
13279         // Do not acquire a lock on this (am) in such cases, as it
13280         // could cause a potential deadlock, if and when watchdog
13281         // is invoked due to unavailability of lock on am and it
13282         // would prevent watchdog from killing system_server.
13283         if (process == null) {
13284             sb.append("Process: ").append(processName).append("\n");
13285             return;
13286         }
13287         // Note: ProcessRecord 'process' is guarded by the service
13288         // instance.  (notably process.pkgList, which could otherwise change
13289         // concurrently during execution of this method)
13290         synchronized (this) {
13291             sb.append("Process: ").append(processName).append("\n");
13292             int flags = process.info.flags;
13293             IPackageManager pm = AppGlobals.getPackageManager();
13294             sb.append("Flags: 0x").append(Integer.toString(flags, 16)).append("\n");
13295             for (int ip=0; ip<process.pkgList.size(); ip++) {
13296                 String pkg = process.pkgList.keyAt(ip);
13297                 sb.append("Package: ").append(pkg);
13298                 try {
13299                     PackageInfo pi = pm.getPackageInfo(pkg, 0, UserHandle.getCallingUserId());
13300                     if (pi != null) {
13301                         sb.append(" v").append(pi.versionCode);
13302                         if (pi.versionName != null) {
13303                             sb.append(" (").append(pi.versionName).append(")");
13304                         }
13305                     }
13306                 } catch (RemoteException e) {
13307                     Slog.e(TAG, "Error getting package info: " + pkg, e);
13308                 }
13309                 sb.append("\n");
13310             }
13311         }
13312     }
13313
13314     private static String processClass(ProcessRecord process) {
13315         if (process == null || process.pid == MY_PID) {
13316             return "system_server";
13317         } else if ((process.info.flags & ApplicationInfo.FLAG_SYSTEM) != 0) {
13318             return "system_app";
13319         } else {
13320             return "data_app";
13321         }
13322     }
13323
13324     /**
13325      * Write a description of an error (crash, WTF, ANR) to the drop box.
13326      * @param eventType to include in the drop box tag ("crash", "wtf", etc.)
13327      * @param process which caused the error, null means the system server
13328      * @param activity which triggered the error, null if unknown
13329      * @param parent activity related to the error, null if unknown
13330      * @param subject line related to the error, null if absent
13331      * @param report in long form describing the error, null if absent
13332      * @param logFile to include in the report, null if none
13333      * @param crashInfo giving an application stack trace, null if absent
13334      */
13335     public void addErrorToDropBox(String eventType,
13336             ProcessRecord process, String processName, ActivityRecord activity,
13337             ActivityRecord parent, String subject,
13338             final String report, final File logFile,
13339             final ApplicationErrorReport.CrashInfo crashInfo) {
13340         // NOTE -- this must never acquire the ActivityManagerService lock,
13341         // otherwise the watchdog may be prevented from resetting the system.
13342
13343         final String dropboxTag = processClass(process) + "_" + eventType;
13344         final DropBoxManager dbox = (DropBoxManager)
13345                 mContext.getSystemService(Context.DROPBOX_SERVICE);
13346
13347         // Exit early if the dropbox isn't configured to accept this report type.
13348         if (dbox == null || !dbox.isTagEnabled(dropboxTag)) return;
13349
13350         final StringBuilder sb = new StringBuilder(1024);
13351         appendDropBoxProcessHeaders(process, processName, sb);
13352         if (process != null) {
13353             sb.append("Foreground: ")
13354                     .append(process.isInterestingToUserLocked() ? "Yes" : "No")
13355                     .append("\n");
13356         }
13357         if (activity != null) {
13358             sb.append("Activity: ").append(activity.shortComponentName).append("\n");
13359         }
13360         if (parent != null && parent.app != null && parent.app.pid != process.pid) {
13361             sb.append("Parent-Process: ").append(parent.app.processName).append("\n");
13362         }
13363         if (parent != null && parent != activity) {
13364             sb.append("Parent-Activity: ").append(parent.shortComponentName).append("\n");
13365         }
13366         if (subject != null) {
13367             sb.append("Subject: ").append(subject).append("\n");
13368         }
13369         sb.append("Build: ").append(Build.FINGERPRINT).append("\n");
13370         if (Debug.isDebuggerConnected()) {
13371             sb.append("Debugger: Connected\n");
13372         }
13373         sb.append("\n");
13374
13375         // Do the rest in a worker thread to avoid blocking the caller on I/O
13376         // (After this point, we shouldn't access AMS internal data structures.)
13377         Thread worker = new Thread("Error dump: " + dropboxTag) {
13378             @Override
13379             public void run() {
13380                 if (report != null) {
13381                     sb.append(report);
13382                 }
13383                 if (logFile != null) {
13384                     try {
13385                         sb.append(FileUtils.readTextFile(logFile, DROPBOX_MAX_SIZE,
13386                                     "\n\n[[TRUNCATED]]"));
13387                     } catch (IOException e) {
13388                         Slog.e(TAG, "Error reading " + logFile, e);
13389                     }
13390                 }
13391                 if (crashInfo != null && crashInfo.stackTrace != null) {
13392                     sb.append(crashInfo.stackTrace);
13393                 }
13394
13395                 String setting = Settings.Global.ERROR_LOGCAT_PREFIX + dropboxTag;
13396                 int lines = Settings.Global.getInt(mContext.getContentResolver(), setting, 0);
13397                 if (lines > 0) {
13398                     sb.append("\n");
13399
13400                     // Merge several logcat streams, and take the last N lines
13401                     InputStreamReader input = null;
13402                     try {
13403                         java.lang.Process logcat = new ProcessBuilder("/system/bin/logcat",
13404                                 "-v", "time", "-b", "events", "-b", "system", "-b", "main",
13405                                 "-b", "crash",
13406                                 "-t", String.valueOf(lines)).redirectErrorStream(true).start();
13407
13408                         try { logcat.getOutputStream().close(); } catch (IOException e) {}
13409                         try { logcat.getErrorStream().close(); } catch (IOException e) {}
13410                         input = new InputStreamReader(logcat.getInputStream());
13411
13412                         int num;
13413                         char[] buf = new char[8192];
13414                         while ((num = input.read(buf)) > 0) sb.append(buf, 0, num);
13415                     } catch (IOException e) {
13416                         Slog.e(TAG, "Error running logcat", e);
13417                     } finally {
13418                         if (input != null) try { input.close(); } catch (IOException e) {}
13419                     }
13420                 }
13421
13422                 dbox.addText(dropboxTag, sb.toString());
13423             }
13424         };
13425
13426         if (process == null) {
13427             // If process is null, we are being called from some internal code
13428             // and may be about to die -- run this synchronously.
13429             worker.run();
13430         } else {
13431             worker.start();
13432         }
13433     }
13434
13435     public List<ActivityManager.ProcessErrorStateInfo> getProcessesInErrorState() {
13436         enforceNotIsolatedCaller("getProcessesInErrorState");
13437         // assume our apps are happy - lazy create the list
13438         List<ActivityManager.ProcessErrorStateInfo> errList = null;
13439
13440         final boolean allUsers = ActivityManager.checkUidPermission(INTERACT_ACROSS_USERS_FULL,
13441                 Binder.getCallingUid()) == PackageManager.PERMISSION_GRANTED;
13442         int userId = UserHandle.getUserId(Binder.getCallingUid());
13443
13444         synchronized (this) {
13445
13446             // iterate across all processes
13447             for (int i=mLruProcesses.size()-1; i>=0; i--) {
13448                 ProcessRecord app = mLruProcesses.get(i);
13449                 if (!allUsers && app.userId != userId) {
13450                     continue;
13451                 }
13452                 if ((app.thread != null) && (app.crashing || app.notResponding)) {
13453                     // This one's in trouble, so we'll generate a report for it
13454                     // crashes are higher priority (in case there's a crash *and* an anr)
13455                     ActivityManager.ProcessErrorStateInfo report = null;
13456                     if (app.crashing) {
13457                         report = app.crashingReport;
13458                     } else if (app.notResponding) {
13459                         report = app.notRespondingReport;
13460                     }
13461
13462                     if (report != null) {
13463                         if (errList == null) {
13464                             errList = new ArrayList<ActivityManager.ProcessErrorStateInfo>(1);
13465                         }
13466                         errList.add(report);
13467                     } else {
13468                         Slog.w(TAG, "Missing app error report, app = " + app.processName +
13469                                 " crashing = " + app.crashing +
13470                                 " notResponding = " + app.notResponding);
13471                     }
13472                 }
13473             }
13474         }
13475
13476         return errList;
13477     }
13478
13479     static int procStateToImportance(int procState, int memAdj,
13480             ActivityManager.RunningAppProcessInfo currApp) {
13481         int imp = ActivityManager.RunningAppProcessInfo.procStateToImportance(procState);
13482         if (imp == ActivityManager.RunningAppProcessInfo.IMPORTANCE_BACKGROUND) {
13483             currApp.lru = memAdj;
13484         } else {
13485             currApp.lru = 0;
13486         }
13487         return imp;
13488     }
13489
13490     private void fillInProcMemInfo(ProcessRecord app,
13491             ActivityManager.RunningAppProcessInfo outInfo) {
13492         outInfo.pid = app.pid;
13493         outInfo.uid = app.info.uid;
13494         if (mHeavyWeightProcess == app) {
13495             outInfo.flags |= ActivityManager.RunningAppProcessInfo.FLAG_CANT_SAVE_STATE;
13496         }
13497         if (app.persistent) {
13498             outInfo.flags |= ActivityManager.RunningAppProcessInfo.FLAG_PERSISTENT;
13499         }
13500         if (app.activities.size() > 0) {
13501             outInfo.flags |= ActivityManager.RunningAppProcessInfo.FLAG_HAS_ACTIVITIES;
13502         }
13503         outInfo.lastTrimLevel = app.trimMemoryLevel;
13504         int adj = app.curAdj;
13505         int procState = app.curProcState;
13506         outInfo.importance = procStateToImportance(procState, adj, outInfo);
13507         outInfo.importanceReasonCode = app.adjTypeCode;
13508         outInfo.processState = app.curProcState;
13509     }
13510
13511     public List<ActivityManager.RunningAppProcessInfo> getRunningAppProcesses() {
13512         enforceNotIsolatedCaller("getRunningAppProcesses");
13513
13514         final int callingUid = Binder.getCallingUid();
13515
13516         // Lazy instantiation of list
13517         List<ActivityManager.RunningAppProcessInfo> runList = null;
13518         final boolean allUsers = ActivityManager.checkUidPermission(INTERACT_ACROSS_USERS_FULL,
13519                 callingUid) == PackageManager.PERMISSION_GRANTED;
13520         final int userId = UserHandle.getUserId(callingUid);
13521         final boolean allUids = isGetTasksAllowed(
13522                 "getRunningAppProcesses", Binder.getCallingPid(), callingUid);
13523
13524         synchronized (this) {
13525             // Iterate across all processes
13526             for (int i = mLruProcesses.size() - 1; i >= 0; i--) {
13527                 ProcessRecord app = mLruProcesses.get(i);
13528                 if ((!allUsers && app.userId != userId)
13529                         || (!allUids && app.uid != callingUid)) {
13530                     continue;
13531                 }
13532                 if ((app.thread != null) && (!app.crashing && !app.notResponding)) {
13533                     // Generate process state info for running application
13534                     ActivityManager.RunningAppProcessInfo currApp =
13535                         new ActivityManager.RunningAppProcessInfo(app.processName,
13536                                 app.pid, app.getPackageList());
13537                     fillInProcMemInfo(app, currApp);
13538                     if (app.adjSource instanceof ProcessRecord) {
13539                         currApp.importanceReasonPid = ((ProcessRecord)app.adjSource).pid;
13540                         currApp.importanceReasonImportance =
13541                                 ActivityManager.RunningAppProcessInfo.procStateToImportance(
13542                                         app.adjSourceProcState);
13543                     } else if (app.adjSource instanceof ActivityRecord) {
13544                         ActivityRecord r = (ActivityRecord)app.adjSource;
13545                         if (r.app != null) currApp.importanceReasonPid = r.app.pid;
13546                     }
13547                     if (app.adjTarget instanceof ComponentName) {
13548                         currApp.importanceReasonComponent = (ComponentName)app.adjTarget;
13549                     }
13550                     //Slog.v(TAG, "Proc " + app.processName + ": imp=" + currApp.importance
13551                     //        + " lru=" + currApp.lru);
13552                     if (runList == null) {
13553                         runList = new ArrayList<>();
13554                     }
13555                     runList.add(currApp);
13556                 }
13557             }
13558         }
13559         return runList;
13560     }
13561
13562     public List<ApplicationInfo> getRunningExternalApplications() {
13563         enforceNotIsolatedCaller("getRunningExternalApplications");
13564         List<ActivityManager.RunningAppProcessInfo> runningApps = getRunningAppProcesses();
13565         List<ApplicationInfo> retList = new ArrayList<ApplicationInfo>();
13566         if (runningApps != null && runningApps.size() > 0) {
13567             Set<String> extList = new HashSet<String>();
13568             for (ActivityManager.RunningAppProcessInfo app : runningApps) {
13569                 if (app.pkgList != null) {
13570                     for (String pkg : app.pkgList) {
13571                         extList.add(pkg);
13572                     }
13573                 }
13574             }
13575             IPackageManager pm = AppGlobals.getPackageManager();
13576             for (String pkg : extList) {
13577                 try {
13578                     ApplicationInfo info = pm.getApplicationInfo(pkg, 0, UserHandle.getCallingUserId());
13579                     if ((info.flags & ApplicationInfo.FLAG_EXTERNAL_STORAGE) != 0) {
13580                         retList.add(info);
13581                     }
13582                 } catch (RemoteException e) {
13583                 }
13584             }
13585         }
13586         return retList;
13587     }
13588
13589     @Override
13590     public void getMyMemoryState(ActivityManager.RunningAppProcessInfo outInfo) {
13591         enforceNotIsolatedCaller("getMyMemoryState");
13592         synchronized (this) {
13593             ProcessRecord proc;
13594             synchronized (mPidsSelfLocked) {
13595                 proc = mPidsSelfLocked.get(Binder.getCallingPid());
13596             }
13597             fillInProcMemInfo(proc, outInfo);
13598         }
13599     }
13600
13601     @Override
13602     public int getMemoryTrimLevel() {
13603         enforceNotIsolatedCaller("getMyMemoryState");
13604         synchronized (this) {
13605             return mLastMemoryLevel;
13606         }
13607     }
13608
13609     @Override
13610     public void onShellCommand(FileDescriptor in, FileDescriptor out,
13611             FileDescriptor err, String[] args, ResultReceiver resultReceiver) {
13612         (new ActivityManagerShellCommand(this, false)).exec(
13613                 this, in, out, err, args, resultReceiver);
13614     }
13615
13616     @Override
13617     protected void dump(FileDescriptor fd, PrintWriter pw, String[] args) {
13618         if (checkCallingPermission(android.Manifest.permission.DUMP)
13619                 != PackageManager.PERMISSION_GRANTED) {
13620             pw.println("Permission Denial: can't dump ActivityManager from from pid="
13621                     + Binder.getCallingPid()
13622                     + ", uid=" + Binder.getCallingUid()
13623                     + " without permission "
13624                     + android.Manifest.permission.DUMP);
13625             return;
13626         }
13627
13628         boolean dumpAll = false;
13629         boolean dumpClient = false;
13630         String dumpPackage = null;
13631
13632         int opti = 0;
13633         while (opti < args.length) {
13634             String opt = args[opti];
13635             if (opt == null || opt.length() <= 0 || opt.charAt(0) != '-') {
13636                 break;
13637             }
13638             opti++;
13639             if ("-a".equals(opt)) {
13640                 dumpAll = true;
13641             } else if ("-c".equals(opt)) {
13642                 dumpClient = true;
13643             } else if ("-p".equals(opt)) {
13644                 if (opti < args.length) {
13645                     dumpPackage = args[opti];
13646                     opti++;
13647                 } else {
13648                     pw.println("Error: -p option requires package argument");
13649                     return;
13650                 }
13651                 dumpClient = true;
13652             } else if ("-h".equals(opt)) {
13653                 ActivityManagerShellCommand.dumpHelp(pw, true);
13654                 return;
13655             } else {
13656                 pw.println("Unknown argument: " + opt + "; use -h for help");
13657             }
13658         }
13659
13660         long origId = Binder.clearCallingIdentity();
13661         boolean more = false;
13662         // Is the caller requesting to dump a particular piece of data?
13663         if (opti < args.length) {
13664             String cmd = args[opti];
13665             opti++;
13666             if ("activities".equals(cmd) || "a".equals(cmd)) {
13667                 synchronized (this) {
13668                     dumpActivitiesLocked(fd, pw, args, opti, true, dumpClient, dumpPackage);
13669                 }
13670             } else if ("recents".equals(cmd) || "r".equals(cmd)) {
13671                 synchronized (this) {
13672                     dumpRecentsLocked(fd, pw, args, opti, true, dumpPackage);
13673                 }
13674             } else if ("broadcasts".equals(cmd) || "b".equals(cmd)) {
13675                 String[] newArgs;
13676                 String name;
13677                 if (opti >= args.length) {
13678                     name = null;
13679                     newArgs = EMPTY_STRING_ARRAY;
13680                 } else {
13681                     dumpPackage = args[opti];
13682                     opti++;
13683                     newArgs = new String[args.length - opti];
13684                     if (args.length > 2) System.arraycopy(args, opti, newArgs, 0,
13685                             args.length - opti);
13686                 }
13687                 synchronized (this) {
13688                     dumpBroadcastsLocked(fd, pw, args, opti, true, dumpPackage);
13689                 }
13690             } else if ("intents".equals(cmd) || "i".equals(cmd)) {
13691                 String[] newArgs;
13692                 String name;
13693                 if (opti >= args.length) {
13694                     name = null;
13695                     newArgs = EMPTY_STRING_ARRAY;
13696                 } else {
13697                     dumpPackage = args[opti];
13698                     opti++;
13699                     newArgs = new String[args.length - opti];
13700                     if (args.length > 2) System.arraycopy(args, opti, newArgs, 0,
13701                             args.length - opti);
13702                 }
13703                 synchronized (this) {
13704                     dumpPendingIntentsLocked(fd, pw, args, opti, true, dumpPackage);
13705                 }
13706             } else if ("processes".equals(cmd) || "p".equals(cmd)) {
13707                 String[] newArgs;
13708                 String name;
13709                 if (opti >= args.length) {
13710                     name = null;
13711                     newArgs = EMPTY_STRING_ARRAY;
13712                 } else {
13713                     dumpPackage = args[opti];
13714                     opti++;
13715                     newArgs = new String[args.length - opti];
13716                     if (args.length > 2) System.arraycopy(args, opti, newArgs, 0,
13717                             args.length - opti);
13718                 }
13719                 synchronized (this) {
13720                     dumpProcessesLocked(fd, pw, args, opti, true, dumpPackage);
13721                 }
13722             } else if ("oom".equals(cmd) || "o".equals(cmd)) {
13723                 synchronized (this) {
13724                     dumpOomLocked(fd, pw, args, opti, true);
13725                 }
13726             } else if ("permissions".equals(cmd) || "perm".equals(cmd)) {
13727                 synchronized (this) {
13728                     dumpPermissionsLocked(fd, pw, args, opti, true, null);
13729                 }
13730             } else if ("provider".equals(cmd)) {
13731                 String[] newArgs;
13732                 String name;
13733                 if (opti >= args.length) {
13734                     name = null;
13735                     newArgs = EMPTY_STRING_ARRAY;
13736                 } else {
13737                     name = args[opti];
13738                     opti++;
13739                     newArgs = new String[args.length - opti];
13740                     if (args.length > 2) System.arraycopy(args, opti, newArgs, 0, args.length - opti);
13741                 }
13742                 if (!dumpProvider(fd, pw, name, newArgs, 0, dumpAll)) {
13743                     pw.println("No providers match: " + name);
13744                     pw.println("Use -h for help.");
13745                 }
13746             } else if ("providers".equals(cmd) || "prov".equals(cmd)) {
13747                 synchronized (this) {
13748                     dumpProvidersLocked(fd, pw, args, opti, true, null);
13749                 }
13750             } else if ("service".equals(cmd)) {
13751                 String[] newArgs;
13752                 String name;
13753                 if (opti >= args.length) {
13754                     name = null;
13755                     newArgs = EMPTY_STRING_ARRAY;
13756                 } else {
13757                     name = args[opti];
13758                     opti++;
13759                     newArgs = new String[args.length - opti];
13760                     if (args.length > 2) System.arraycopy(args, opti, newArgs, 0,
13761                             args.length - opti);
13762                 }
13763                 if (!mServices.dumpService(fd, pw, name, newArgs, 0, dumpAll)) {
13764                     pw.println("No services match: " + name);
13765                     pw.println("Use -h for help.");
13766                 }
13767             } else if ("package".equals(cmd)) {
13768                 String[] newArgs;
13769                 if (opti >= args.length) {
13770                     pw.println("package: no package name specified");
13771                     pw.println("Use -h for help.");
13772                 } else {
13773                     dumpPackage = args[opti];
13774                     opti++;
13775                     newArgs = new String[args.length - opti];
13776                     if (args.length > 2) System.arraycopy(args, opti, newArgs, 0,
13777                             args.length - opti);
13778                     args = newArgs;
13779                     opti = 0;
13780                     more = true;
13781                 }
13782             } else if ("associations".equals(cmd) || "as".equals(cmd)) {
13783                 synchronized (this) {
13784                     dumpAssociationsLocked(fd, pw, args, opti, true, dumpClient, dumpPackage);
13785                 }
13786             } else if ("services".equals(cmd) || "s".equals(cmd)) {
13787                 synchronized (this) {
13788                     mServices.dumpServicesLocked(fd, pw, args, opti, true, dumpClient, dumpPackage);
13789                 }
13790             } else if ("locks".equals(cmd)) {
13791                 LockGuard.dump(fd, pw, args);
13792             } else {
13793                 // Dumping a single activity?
13794                 if (!dumpActivity(fd, pw, cmd, args, opti, dumpAll)) {
13795                     ActivityManagerShellCommand shell = new ActivityManagerShellCommand(this, true);
13796                     int res = shell.exec(this, null, fd, null, args, new ResultReceiver(null));
13797                     if (res < 0) {
13798                         pw.println("Bad activity command, or no activities match: " + cmd);
13799                         pw.println("Use -h for help.");
13800                     }
13801                 }
13802             }
13803             if (!more) {
13804                 Binder.restoreCallingIdentity(origId);
13805                 return;
13806             }
13807         }
13808
13809         // No piece of data specified, dump everything.
13810         synchronized (this) {
13811             dumpPendingIntentsLocked(fd, pw, args, opti, dumpAll, dumpPackage);
13812             pw.println();
13813             if (dumpAll) {
13814                 pw.println("-------------------------------------------------------------------------------");
13815             }
13816             dumpBroadcastsLocked(fd, pw, args, opti, dumpAll, dumpPackage);
13817             pw.println();
13818             if (dumpAll) {
13819                 pw.println("-------------------------------------------------------------------------------");
13820             }
13821             dumpProvidersLocked(fd, pw, args, opti, dumpAll, dumpPackage);
13822             pw.println();
13823             if (dumpAll) {
13824                 pw.println("-------------------------------------------------------------------------------");
13825             }
13826             dumpPermissionsLocked(fd, pw, args, opti, dumpAll, dumpPackage);
13827             pw.println();
13828             if (dumpAll) {
13829                 pw.println("-------------------------------------------------------------------------------");
13830             }
13831             mServices.dumpServicesLocked(fd, pw, args, opti, dumpAll, dumpClient, dumpPackage);
13832             pw.println();
13833             if (dumpAll) {
13834                 pw.println("-------------------------------------------------------------------------------");
13835             }
13836             dumpRecentsLocked(fd, pw, args, opti, dumpAll, dumpPackage);
13837             pw.println();
13838             if (dumpAll) {
13839                 pw.println("-------------------------------------------------------------------------------");
13840             }
13841             dumpActivitiesLocked(fd, pw, args, opti, dumpAll, dumpClient, dumpPackage);
13842             if (mAssociations.size() > 0) {
13843                 pw.println();
13844                 if (dumpAll) {
13845                     pw.println("-------------------------------------------------------------------------------");
13846                 }
13847                 dumpAssociationsLocked(fd, pw, args, opti, dumpAll, dumpClient, dumpPackage);
13848             }
13849             pw.println();
13850             if (dumpAll) {
13851                 pw.println("-------------------------------------------------------------------------------");
13852             }
13853             dumpProcessesLocked(fd, pw, args, opti, dumpAll, dumpPackage);
13854         }
13855         Binder.restoreCallingIdentity(origId);
13856     }
13857
13858     void dumpActivitiesLocked(FileDescriptor fd, PrintWriter pw, String[] args,
13859             int opti, boolean dumpAll, boolean dumpClient, String dumpPackage) {
13860         pw.println("ACTIVITY MANAGER ACTIVITIES (dumpsys activity activities)");
13861
13862         boolean printedAnything = mStackSupervisor.dumpActivitiesLocked(fd, pw, dumpAll, dumpClient,
13863                 dumpPackage);
13864         boolean needSep = printedAnything;
13865
13866         boolean printed = ActivityStackSupervisor.printThisActivity(pw, mFocusedActivity,
13867                 dumpPackage, needSep, "  mFocusedActivity: ");
13868         if (printed) {
13869             printedAnything = true;
13870             needSep = false;
13871         }
13872
13873         if (dumpPackage == null) {
13874             if (needSep) {
13875                 pw.println();
13876             }
13877             needSep = true;
13878             printedAnything = true;
13879             mStackSupervisor.dump(pw, "  ");
13880         }
13881
13882         if (!printedAnything) {
13883             pw.println("  (nothing)");
13884         }
13885     }
13886
13887     void dumpRecentsLocked(FileDescriptor fd, PrintWriter pw, String[] args,
13888             int opti, boolean dumpAll, String dumpPackage) {
13889         pw.println("ACTIVITY MANAGER RECENT TASKS (dumpsys activity recents)");
13890
13891         boolean printedAnything = false;
13892
13893         if (mRecentTasks != null && mRecentTasks.size() > 0) {
13894             boolean printedHeader = false;
13895
13896             final int N = mRecentTasks.size();
13897             for (int i=0; i<N; i++) {
13898                 TaskRecord tr = mRecentTasks.get(i);
13899                 if (dumpPackage != null) {
13900                     if (tr.realActivity == null ||
13901                             !dumpPackage.equals(tr.realActivity)) {
13902                         continue;
13903                     }
13904                 }
13905                 if (!printedHeader) {
13906                     pw.println("  Recent tasks:");
13907                     printedHeader = true;
13908                     printedAnything = true;
13909                 }
13910                 pw.print("  * Recent #"); pw.print(i); pw.print(": ");
13911                         pw.println(tr);
13912                 if (dumpAll) {
13913                     mRecentTasks.get(i).dump(pw, "    ");
13914                 }
13915             }
13916         }
13917
13918         if (!printedAnything) {
13919             pw.println("  (nothing)");
13920         }
13921     }
13922
13923     void dumpAssociationsLocked(FileDescriptor fd, PrintWriter pw, String[] args,
13924             int opti, boolean dumpAll, boolean dumpClient, String dumpPackage) {
13925         pw.println("ACTIVITY MANAGER ASSOCIATIONS (dumpsys activity associations)");
13926
13927         int dumpUid = 0;
13928         if (dumpPackage != null) {
13929             IPackageManager pm = AppGlobals.getPackageManager();
13930             try {
13931                 dumpUid = pm.getPackageUid(dumpPackage, MATCH_UNINSTALLED_PACKAGES, 0);
13932             } catch (RemoteException e) {
13933             }
13934         }
13935
13936         boolean printedAnything = false;
13937
13938         final long now = SystemClock.uptimeMillis();
13939
13940         for (int i1=0, N1=mAssociations.size(); i1<N1; i1++) {
13941             ArrayMap<ComponentName, SparseArray<ArrayMap<String, Association>>> targetComponents
13942                     = mAssociations.valueAt(i1);
13943             for (int i2=0, N2=targetComponents.size(); i2<N2; i2++) {
13944                 SparseArray<ArrayMap<String, Association>> sourceUids
13945                         = targetComponents.valueAt(i2);
13946                 for (int i3=0, N3=sourceUids.size(); i3<N3; i3++) {
13947                     ArrayMap<String, Association> sourceProcesses = sourceUids.valueAt(i3);
13948                     for (int i4=0, N4=sourceProcesses.size(); i4<N4; i4++) {
13949                         Association ass = sourceProcesses.valueAt(i4);
13950                         if (dumpPackage != null) {
13951                             if (!ass.mTargetComponent.getPackageName().equals(dumpPackage)
13952                                     && UserHandle.getAppId(ass.mSourceUid) != dumpUid) {
13953                                 continue;
13954                             }
13955                         }
13956                         printedAnything = true;
13957                         pw.print("  ");
13958                         pw.print(ass.mTargetProcess);
13959                         pw.print("/");
13960                         UserHandle.formatUid(pw, ass.mTargetUid);
13961                         pw.print(" <- ");
13962                         pw.print(ass.mSourceProcess);
13963                         pw.print("/");
13964                         UserHandle.formatUid(pw, ass.mSourceUid);
13965                         pw.println();
13966                         pw.print("    via ");
13967                         pw.print(ass.mTargetComponent.flattenToShortString());
13968                         pw.println();
13969                         pw.print("    ");
13970                         long dur = ass.mTime;
13971                         if (ass.mNesting > 0) {
13972                             dur += now - ass.mStartTime;
13973                         }
13974                         TimeUtils.formatDuration(dur, pw);
13975                         pw.print(" (");
13976                         pw.print(ass.mCount);
13977                         pw.println(" times)");
13978                         if (ass.mNesting > 0) {
13979                             pw.print("    ");
13980                             pw.print(" Currently active: ");
13981                             TimeUtils.formatDuration(now - ass.mStartTime, pw);
13982                             pw.println();
13983                         }
13984                     }
13985                 }
13986             }
13987
13988         }
13989
13990         if (!printedAnything) {
13991             pw.println("  (nothing)");
13992         }
13993     }
13994
13995     boolean dumpUids(PrintWriter pw, String dumpPackage, SparseArray<UidRecord> uids,
13996             String header, boolean needSep) {
13997         boolean printed = false;
13998         int whichAppId = -1;
13999         if (dumpPackage != null) {
14000             try {
14001                 ApplicationInfo info = mContext.getPackageManager().getApplicationInfo(
14002                         dumpPackage, 0);
14003                 whichAppId = UserHandle.getAppId(info.uid);
14004             } catch (NameNotFoundException e) {
14005                 e.printStackTrace();
14006             }
14007         }
14008         for (int i=0; i<uids.size(); i++) {
14009             UidRecord uidRec = uids.valueAt(i);
14010             if (dumpPackage != null && UserHandle.getAppId(uidRec.uid) != whichAppId) {
14011                 continue;
14012             }
14013             if (!printed) {
14014                 printed = true;
14015                 if (needSep) {
14016                     pw.println();
14017                 }
14018                 pw.print("  ");
14019                 pw.println(header);
14020                 needSep = true;
14021             }
14022             pw.print("    UID "); UserHandle.formatUid(pw, uidRec.uid);
14023             pw.print(": "); pw.println(uidRec);
14024         }
14025         return printed;
14026     }
14027
14028     void dumpProcessesLocked(FileDescriptor fd, PrintWriter pw, String[] args,
14029             int opti, boolean dumpAll, String dumpPackage) {
14030         boolean needSep = false;
14031         boolean printedAnything = false;
14032         int numPers = 0;
14033
14034         pw.println("ACTIVITY MANAGER RUNNING PROCESSES (dumpsys activity processes)");
14035
14036         if (dumpAll) {
14037             final int NP = mProcessNames.getMap().size();
14038             for (int ip=0; ip<NP; ip++) {
14039                 SparseArray<ProcessRecord> procs = mProcessNames.getMap().valueAt(ip);
14040                 final int NA = procs.size();
14041                 for (int ia=0; ia<NA; ia++) {
14042                     ProcessRecord r = procs.valueAt(ia);
14043                     if (dumpPackage != null && !r.pkgList.containsKey(dumpPackage)) {
14044                         continue;
14045                     }
14046                     if (!needSep) {
14047                         pw.println("  All known processes:");
14048                         needSep = true;
14049                         printedAnything = true;
14050                     }
14051                     pw.print(r.persistent ? "  *PERS*" : "  *APP*");
14052                         pw.print(" UID "); pw.print(procs.keyAt(ia));
14053                         pw.print(" "); pw.println(r);
14054                     r.dump(pw, "    ");
14055                     if (r.persistent) {
14056                         numPers++;
14057                     }
14058                 }
14059             }
14060         }
14061
14062         if (mIsolatedProcesses.size() > 0) {
14063             boolean printed = false;
14064             for (int i=0; i<mIsolatedProcesses.size(); i++) {
14065                 ProcessRecord r = mIsolatedProcesses.valueAt(i);
14066                 if (dumpPackage != null && !r.pkgList.containsKey(dumpPackage)) {
14067                     continue;
14068                 }
14069                 if (!printed) {
14070                     if (needSep) {
14071                         pw.println();
14072                     }
14073                     pw.println("  Isolated process list (sorted by uid):");
14074                     printedAnything = true;
14075                     printed = true;
14076                     needSep = true;
14077                 }
14078                 pw.println(String.format("%sIsolated #%2d: %s",
14079                         "    ", i, r.toString()));
14080             }
14081         }
14082
14083         if (mActiveUids.size() > 0) {
14084             if (dumpUids(pw, dumpPackage, mActiveUids, "UID states:", needSep)) {
14085                 printedAnything = needSep = true;
14086             }
14087         }
14088         if (mValidateUids.size() > 0) {
14089             if (dumpUids(pw, dumpPackage, mValidateUids, "UID validation:", needSep)) {
14090                 printedAnything = needSep = true;
14091             }
14092         }
14093
14094         if (mLruProcesses.size() > 0) {
14095             if (needSep) {
14096                 pw.println();
14097             }
14098             pw.print("  Process LRU list (sorted by oom_adj, "); pw.print(mLruProcesses.size());
14099                     pw.print(" total, non-act at ");
14100                     pw.print(mLruProcesses.size()-mLruProcessActivityStart);
14101                     pw.print(", non-svc at ");
14102                     pw.print(mLruProcesses.size()-mLruProcessServiceStart);
14103                     pw.println("):");
14104             dumpProcessOomList(pw, this, mLruProcesses, "    ", "Proc", "PERS", false, dumpPackage);
14105             needSep = true;
14106             printedAnything = true;
14107         }
14108
14109         if (dumpAll || dumpPackage != null) {
14110             synchronized (mPidsSelfLocked) {
14111                 boolean printed = false;
14112                 for (int i=0; i<mPidsSelfLocked.size(); i++) {
14113                     ProcessRecord r = mPidsSelfLocked.valueAt(i);
14114                     if (dumpPackage != null && !r.pkgList.containsKey(dumpPackage)) {
14115                         continue;
14116                     }
14117                     if (!printed) {
14118                         if (needSep) pw.println();
14119                         needSep = true;
14120                         pw.println("  PID mappings:");
14121                         printed = true;
14122                         printedAnything = true;
14123                     }
14124                     pw.print("    PID #"); pw.print(mPidsSelfLocked.keyAt(i));
14125                         pw.print(": "); pw.println(mPidsSelfLocked.valueAt(i));
14126                 }
14127             }
14128         }
14129
14130         if (mForegroundProcesses.size() > 0) {
14131             synchronized (mPidsSelfLocked) {
14132                 boolean printed = false;
14133                 for (int i=0; i<mForegroundProcesses.size(); i++) {
14134                     ProcessRecord r = mPidsSelfLocked.get(
14135                             mForegroundProcesses.valueAt(i).pid);
14136                     if (dumpPackage != null && (r == null
14137                             || !r.pkgList.containsKey(dumpPackage))) {
14138                         continue;
14139                     }
14140                     if (!printed) {
14141                         if (needSep) pw.println();
14142                         needSep = true;
14143                         pw.println("  Foreground Processes:");
14144                         printed = true;
14145                         printedAnything = true;
14146                     }
14147                     pw.print("    PID #"); pw.print(mForegroundProcesses.keyAt(i));
14148                             pw.print(": "); pw.println(mForegroundProcesses.valueAt(i));
14149                 }
14150             }
14151         }
14152
14153         if (mPersistentStartingProcesses.size() > 0) {
14154             if (needSep) pw.println();
14155             needSep = true;
14156             printedAnything = true;
14157             pw.println("  Persisent processes that are starting:");
14158             dumpProcessList(pw, this, mPersistentStartingProcesses, "    ",
14159                     "Starting Norm", "Restarting PERS", dumpPackage);
14160         }
14161
14162         if (mRemovedProcesses.size() > 0) {
14163             if (needSep) pw.println();
14164             needSep = true;
14165             printedAnything = true;
14166             pw.println("  Processes that are being removed:");
14167             dumpProcessList(pw, this, mRemovedProcesses, "    ",
14168                     "Removed Norm", "Removed PERS", dumpPackage);
14169         }
14170
14171         if (mProcessesOnHold.size() > 0) {
14172             if (needSep) pw.println();
14173             needSep = true;
14174             printedAnything = true;
14175             pw.println("  Processes that are on old until the system is ready:");
14176             dumpProcessList(pw, this, mProcessesOnHold, "    ",
14177                     "OnHold Norm", "OnHold PERS", dumpPackage);
14178         }
14179
14180         needSep = dumpProcessesToGc(fd, pw, args, opti, needSep, dumpAll, dumpPackage);
14181
14182         needSep = mAppErrors.dumpLocked(fd, pw, needSep, dumpPackage);
14183         if (needSep) {
14184             printedAnything = true;
14185         }
14186
14187         if (dumpPackage == null) {
14188             pw.println();
14189             needSep = false;
14190             mUserController.dump(pw, dumpAll);
14191         }
14192         if (mHomeProcess != null && (dumpPackage == null
14193                 || mHomeProcess.pkgList.containsKey(dumpPackage))) {
14194             if (needSep) {
14195                 pw.println();
14196                 needSep = false;
14197             }
14198             pw.println("  mHomeProcess: " + mHomeProcess);
14199         }
14200         if (mPreviousProcess != null && (dumpPackage == null
14201                 || mPreviousProcess.pkgList.containsKey(dumpPackage))) {
14202             if (needSep) {
14203                 pw.println();
14204                 needSep = false;
14205             }
14206             pw.println("  mPreviousProcess: " + mPreviousProcess);
14207         }
14208         if (dumpAll) {
14209             StringBuilder sb = new StringBuilder(128);
14210             sb.append("  mPreviousProcessVisibleTime: ");
14211             TimeUtils.formatDuration(mPreviousProcessVisibleTime, sb);
14212             pw.println(sb);
14213         }
14214         if (mHeavyWeightProcess != null && (dumpPackage == null
14215                 || mHeavyWeightProcess.pkgList.containsKey(dumpPackage))) {
14216             if (needSep) {
14217                 pw.println();
14218                 needSep = false;
14219             }
14220             pw.println("  mHeavyWeightProcess: " + mHeavyWeightProcess);
14221         }
14222         if (dumpPackage == null) {
14223             pw.println("  mConfiguration: " + mConfiguration);
14224         }
14225         if (dumpAll) {
14226             pw.println("  mConfigWillChange: " + getFocusedStack().mConfigWillChange);
14227             if (mCompatModePackages.getPackages().size() > 0) {
14228                 boolean printed = false;
14229                 for (Map.Entry<String, Integer> entry
14230                         : mCompatModePackages.getPackages().entrySet()) {
14231                     String pkg = entry.getKey();
14232                     int mode = entry.getValue();
14233                     if (dumpPackage != null && !dumpPackage.equals(pkg)) {
14234                         continue;
14235                     }
14236                     if (!printed) {
14237                         pw.println("  mScreenCompatPackages:");
14238                         printed = true;
14239                     }
14240                     pw.print("    "); pw.print(pkg); pw.print(": ");
14241                             pw.print(mode); pw.println();
14242                 }
14243             }
14244         }
14245         if (dumpPackage == null) {
14246             pw.println("  mWakefulness="
14247                     + PowerManagerInternal.wakefulnessToString(mWakefulness));
14248             pw.println("  mSleepTokens=" + mSleepTokens);
14249             pw.println("  mSleeping=" + mSleeping + " mLockScreenShown="
14250                     + lockScreenShownToString());
14251             pw.println("  mShuttingDown=" + mShuttingDown + " mTestPssMode=" + mTestPssMode);
14252             if (mRunningVoice != null) {
14253                 pw.println("  mRunningVoice=" + mRunningVoice);
14254                 pw.println("  mVoiceWakeLock" + mVoiceWakeLock);
14255             }
14256         }
14257         if (mDebugApp != null || mOrigDebugApp != null || mDebugTransient
14258                 || mOrigWaitForDebugger) {
14259             if (dumpPackage == null || dumpPackage.equals(mDebugApp)
14260                     || dumpPackage.equals(mOrigDebugApp)) {
14261                 if (needSep) {
14262                     pw.println();
14263                     needSep = false;
14264                 }
14265                 pw.println("  mDebugApp=" + mDebugApp + "/orig=" + mOrigDebugApp
14266                         + " mDebugTransient=" + mDebugTransient
14267                         + " mOrigWaitForDebugger=" + mOrigWaitForDebugger);
14268             }
14269         }
14270         if (mCurAppTimeTracker != null) {
14271             mCurAppTimeTracker.dumpWithHeader(pw, "  ", true);
14272         }
14273         if (mMemWatchProcesses.getMap().size() > 0) {
14274             pw.println("  Mem watch processes:");
14275             final ArrayMap<String, SparseArray<Pair<Long, String>>> procs
14276                     = mMemWatchProcesses.getMap();
14277             for (int i=0; i<procs.size(); i++) {
14278                 final String proc = procs.keyAt(i);
14279                 final SparseArray<Pair<Long, String>> uids = procs.valueAt(i);
14280                 for (int j=0; j<uids.size(); j++) {
14281                     if (needSep) {
14282                         pw.println();
14283                         needSep = false;
14284                     }
14285                     StringBuilder sb = new StringBuilder();
14286                     sb.append("    ").append(proc).append('/');
14287                     UserHandle.formatUid(sb, uids.keyAt(j));
14288                     Pair<Long, String> val = uids.valueAt(j);
14289                     sb.append(": "); DebugUtils.sizeValueToString(val.first, sb);
14290                     if (val.second != null) {
14291                         sb.append(", report to ").append(val.second);
14292                     }
14293                     pw.println(sb.toString());
14294                 }
14295             }
14296             pw.print("  mMemWatchDumpProcName="); pw.println(mMemWatchDumpProcName);
14297             pw.print("  mMemWatchDumpFile="); pw.println(mMemWatchDumpFile);
14298             pw.print("  mMemWatchDumpPid="); pw.print(mMemWatchDumpPid);
14299                     pw.print(" mMemWatchDumpUid="); pw.println(mMemWatchDumpUid);
14300         }
14301         if (mTrackAllocationApp != null) {
14302             if (dumpPackage == null || dumpPackage.equals(mTrackAllocationApp)) {
14303                 if (needSep) {
14304                     pw.println();
14305                     needSep = false;
14306                 }
14307                 pw.println("  mTrackAllocationApp=" + mTrackAllocationApp);
14308             }
14309         }
14310         if (mProfileApp != null || mProfileProc != null || mProfileFile != null
14311                 || mProfileFd != null) {
14312             if (dumpPackage == null || dumpPackage.equals(mProfileApp)) {
14313                 if (needSep) {
14314                     pw.println();
14315                     needSep = false;
14316                 }
14317                 pw.println("  mProfileApp=" + mProfileApp + " mProfileProc=" + mProfileProc);
14318                 pw.println("  mProfileFile=" + mProfileFile + " mProfileFd=" + mProfileFd);
14319                 pw.println("  mSamplingInterval=" + mSamplingInterval + " mAutoStopProfiler="
14320                         + mAutoStopProfiler);
14321                 pw.println("  mProfileType=" + mProfileType);
14322             }
14323         }
14324         if (mNativeDebuggingApp != null) {
14325             if (dumpPackage == null || dumpPackage.equals(mNativeDebuggingApp)) {
14326                 if (needSep) {
14327                     pw.println();
14328                     needSep = false;
14329                 }
14330                 pw.println("  mNativeDebuggingApp=" + mNativeDebuggingApp);
14331             }
14332         }
14333         if (dumpPackage == null) {
14334             if (mAlwaysFinishActivities || mLenientBackgroundCheck) {
14335                 pw.println("  mAlwaysFinishActivities=" + mAlwaysFinishActivities
14336                         + " mLenientBackgroundCheck=" + mLenientBackgroundCheck);
14337             }
14338             if (mController != null) {
14339                 pw.println("  mController=" + mController
14340                         + " mControllerIsAMonkey=" + mControllerIsAMonkey);
14341             }
14342             if (dumpAll) {
14343                 pw.println("  Total persistent processes: " + numPers);
14344                 pw.println("  mProcessesReady=" + mProcessesReady
14345                         + " mSystemReady=" + mSystemReady
14346                         + " mBooted=" + mBooted
14347                         + " mFactoryTest=" + mFactoryTest);
14348                 pw.println("  mBooting=" + mBooting
14349                         + " mCallFinishBooting=" + mCallFinishBooting
14350                         + " mBootAnimationComplete=" + mBootAnimationComplete);
14351                 pw.print("  mLastPowerCheckRealtime=");
14352                         TimeUtils.formatDuration(mLastPowerCheckRealtime, pw);
14353                         pw.println("");
14354                 pw.print("  mLastPowerCheckUptime=");
14355                         TimeUtils.formatDuration(mLastPowerCheckUptime, pw);
14356                         pw.println("");
14357                 pw.println("  mGoingToSleep=" + mStackSupervisor.mGoingToSleep);
14358                 pw.println("  mLaunchingActivity=" + mStackSupervisor.mLaunchingActivity);
14359                 pw.println("  mAdjSeq=" + mAdjSeq + " mLruSeq=" + mLruSeq);
14360                 pw.println("  mNumNonCachedProcs=" + mNumNonCachedProcs
14361                         + " (" + mLruProcesses.size() + " total)"
14362                         + " mNumCachedHiddenProcs=" + mNumCachedHiddenProcs
14363                         + " mNumServiceProcs=" + mNumServiceProcs
14364                         + " mNewNumServiceProcs=" + mNewNumServiceProcs);
14365                 pw.println("  mAllowLowerMemLevel=" + mAllowLowerMemLevel
14366                         + " mLastMemoryLevel" + mLastMemoryLevel
14367                         + " mLastNumProcesses" + mLastNumProcesses);
14368                 long now = SystemClock.uptimeMillis();
14369                 pw.print("  mLastIdleTime=");
14370                         TimeUtils.formatDuration(now, mLastIdleTime, pw);
14371                         pw.print(" mLowRamSinceLastIdle=");
14372                         TimeUtils.formatDuration(getLowRamTimeSinceIdle(now), pw);
14373                         pw.println();
14374             }
14375         }
14376
14377         if (!printedAnything) {
14378             pw.println("  (nothing)");
14379         }
14380     }
14381
14382     boolean dumpProcessesToGc(FileDescriptor fd, PrintWriter pw, String[] args,
14383             int opti, boolean needSep, boolean dumpAll, String dumpPackage) {
14384         if (mProcessesToGc.size() > 0) {
14385             boolean printed = false;
14386             long now = SystemClock.uptimeMillis();
14387             for (int i=0; i<mProcessesToGc.size(); i++) {
14388                 ProcessRecord proc = mProcessesToGc.get(i);
14389                 if (dumpPackage != null && !dumpPackage.equals(proc.info.packageName)) {
14390                     continue;
14391                 }
14392                 if (!printed) {
14393                     if (needSep) pw.println();
14394                     needSep = true;
14395                     pw.println("  Processes that are waiting to GC:");
14396                     printed = true;
14397                 }
14398                 pw.print("    Process "); pw.println(proc);
14399                 pw.print("      lowMem="); pw.print(proc.reportLowMemory);
14400                         pw.print(", last gced=");
14401                         pw.print(now-proc.lastRequestedGc);
14402                         pw.print(" ms ago, last lowMem=");
14403                         pw.print(now-proc.lastLowMemory);
14404                         pw.println(" ms ago");
14405
14406             }
14407         }
14408         return needSep;
14409     }
14410
14411     void printOomLevel(PrintWriter pw, String name, int adj) {
14412         pw.print("    ");
14413         if (adj >= 0) {
14414             pw.print(' ');
14415             if (adj < 10) pw.print(' ');
14416         } else {
14417             if (adj > -10) pw.print(' ');
14418         }
14419         pw.print(adj);
14420         pw.print(": ");
14421         pw.print(name);
14422         pw.print(" (");
14423         pw.print(stringifySize(mProcessList.getMemLevel(adj), 1024));
14424         pw.println(")");
14425     }
14426
14427     boolean dumpOomLocked(FileDescriptor fd, PrintWriter pw, String[] args,
14428             int opti, boolean dumpAll) {
14429         boolean needSep = false;
14430
14431         if (mLruProcesses.size() > 0) {
14432             if (needSep) pw.println();
14433             needSep = true;
14434             pw.println("  OOM levels:");
14435             printOomLevel(pw, "SYSTEM_ADJ", ProcessList.SYSTEM_ADJ);
14436             printOomLevel(pw, "PERSISTENT_PROC_ADJ", ProcessList.PERSISTENT_PROC_ADJ);
14437             printOomLevel(pw, "PERSISTENT_SERVICE_ADJ", ProcessList.PERSISTENT_SERVICE_ADJ);
14438             printOomLevel(pw, "FOREGROUND_APP_ADJ", ProcessList.FOREGROUND_APP_ADJ);
14439             printOomLevel(pw, "VISIBLE_APP_ADJ", ProcessList.VISIBLE_APP_ADJ);
14440             printOomLevel(pw, "PERCEPTIBLE_APP_ADJ", ProcessList.PERCEPTIBLE_APP_ADJ);
14441             printOomLevel(pw, "BACKUP_APP_ADJ", ProcessList.BACKUP_APP_ADJ);
14442             printOomLevel(pw, "HEAVY_WEIGHT_APP_ADJ", ProcessList.HEAVY_WEIGHT_APP_ADJ);
14443             printOomLevel(pw, "SERVICE_ADJ", ProcessList.SERVICE_ADJ);
14444             printOomLevel(pw, "HOME_APP_ADJ", ProcessList.HOME_APP_ADJ);
14445             printOomLevel(pw, "PREVIOUS_APP_ADJ", ProcessList.PREVIOUS_APP_ADJ);
14446             printOomLevel(pw, "SERVICE_B_ADJ", ProcessList.SERVICE_B_ADJ);
14447             printOomLevel(pw, "CACHED_APP_MIN_ADJ", ProcessList.CACHED_APP_MIN_ADJ);
14448             printOomLevel(pw, "CACHED_APP_MAX_ADJ", ProcessList.CACHED_APP_MAX_ADJ);
14449
14450             if (needSep) pw.println();
14451             pw.print("  Process OOM control ("); pw.print(mLruProcesses.size());
14452                     pw.print(" total, non-act at ");
14453                     pw.print(mLruProcesses.size()-mLruProcessActivityStart);
14454                     pw.print(", non-svc at ");
14455                     pw.print(mLruProcesses.size()-mLruProcessServiceStart);
14456                     pw.println("):");
14457             dumpProcessOomList(pw, this, mLruProcesses, "    ", "Proc", "PERS", true, null);
14458             needSep = true;
14459         }
14460
14461         dumpProcessesToGc(fd, pw, args, opti, needSep, dumpAll, null);
14462
14463         pw.println();
14464         pw.println("  mHomeProcess: " + mHomeProcess);
14465         pw.println("  mPreviousProcess: " + mPreviousProcess);
14466         if (mHeavyWeightProcess != null) {
14467             pw.println("  mHeavyWeightProcess: " + mHeavyWeightProcess);
14468         }
14469
14470         return true;
14471     }
14472
14473     /**
14474      * There are three ways to call this:
14475      *  - no provider specified: dump all the providers
14476      *  - a flattened component name that matched an existing provider was specified as the
14477      *    first arg: dump that one provider
14478      *  - the first arg isn't the flattened component name of an existing provider:
14479      *    dump all providers whose component contains the first arg as a substring
14480      */
14481     protected boolean dumpProvider(FileDescriptor fd, PrintWriter pw, String name, String[] args,
14482             int opti, boolean dumpAll) {
14483         return mProviderMap.dumpProvider(fd, pw, name, args, opti, dumpAll);
14484     }
14485
14486     static class ItemMatcher {
14487         ArrayList<ComponentName> components;
14488         ArrayList<String> strings;
14489         ArrayList<Integer> objects;
14490         boolean all;
14491
14492         ItemMatcher() {
14493             all = true;
14494         }
14495
14496         void build(String name) {
14497             ComponentName componentName = ComponentName.unflattenFromString(name);
14498             if (componentName != null) {
14499                 if (components == null) {
14500                     components = new ArrayList<ComponentName>();
14501                 }
14502                 components.add(componentName);
14503                 all = false;
14504             } else {
14505                 int objectId = 0;
14506                 // Not a '/' separated full component name; maybe an object ID?
14507                 try {
14508                     objectId = Integer.parseInt(name, 16);
14509                     if (objects == null) {
14510                         objects = new ArrayList<Integer>();
14511                     }
14512                     objects.add(objectId);
14513                     all = false;
14514                 } catch (RuntimeException e) {
14515                     // Not an integer; just do string match.
14516                     if (strings == null) {
14517                         strings = new ArrayList<String>();
14518                     }
14519                     strings.add(name);
14520                     all = false;
14521                 }
14522             }
14523         }
14524
14525         int build(String[] args, int opti) {
14526             for (; opti<args.length; opti++) {
14527                 String name = args[opti];
14528                 if ("--".equals(name)) {
14529                     return opti+1;
14530                 }
14531                 build(name);
14532             }
14533             return opti;
14534         }
14535
14536         boolean match(Object object, ComponentName comp) {
14537             if (all) {
14538                 return true;
14539             }
14540             if (components != null) {
14541                 for (int i=0; i<components.size(); i++) {
14542                     if (components.get(i).equals(comp)) {
14543                         return true;
14544                     }
14545                 }
14546             }
14547             if (objects != null) {
14548                 for (int i=0; i<objects.size(); i++) {
14549                     if (System.identityHashCode(object) == objects.get(i)) {
14550                         return true;
14551                     }
14552                 }
14553             }
14554             if (strings != null) {
14555                 String flat = comp.flattenToString();
14556                 for (int i=0; i<strings.size(); i++) {
14557                     if (flat.contains(strings.get(i))) {
14558                         return true;
14559                     }
14560                 }
14561             }
14562             return false;
14563         }
14564     }
14565
14566     /**
14567      * There are three things that cmd can be:
14568      *  - a flattened component name that matches an existing activity
14569      *  - the cmd arg isn't the flattened component name of an existing activity:
14570      *    dump all activity whose component contains the cmd as a substring
14571      *  - A hex number of the ActivityRecord object instance.
14572      */
14573     protected boolean dumpActivity(FileDescriptor fd, PrintWriter pw, String name, String[] args,
14574             int opti, boolean dumpAll) {
14575         ArrayList<ActivityRecord> activities;
14576
14577         synchronized (this) {
14578             activities = mStackSupervisor.getDumpActivitiesLocked(name);
14579         }
14580
14581         if (activities.size() <= 0) {
14582             return false;
14583         }
14584
14585         String[] newArgs = new String[args.length - opti];
14586         System.arraycopy(args, opti, newArgs, 0, args.length - opti);
14587
14588         TaskRecord lastTask = null;
14589         boolean needSep = false;
14590         for (int i=activities.size()-1; i>=0; i--) {
14591             ActivityRecord r = activities.get(i);
14592             if (needSep) {
14593                 pw.println();
14594             }
14595             needSep = true;
14596             synchronized (this) {
14597                 if (lastTask != r.task) {
14598                     lastTask = r.task;
14599                     pw.print("TASK "); pw.print(lastTask.affinity);
14600                             pw.print(" id="); pw.println(lastTask.taskId);
14601                     if (dumpAll) {
14602                         lastTask.dump(pw, "  ");
14603                     }
14604                 }
14605             }
14606             dumpActivity("  ", fd, pw, activities.get(i), newArgs, dumpAll);
14607         }
14608         return true;
14609     }
14610
14611     /**
14612      * Invokes IApplicationThread.dumpActivity() on the thread of the specified activity if
14613      * there is a thread associated with the activity.
14614      */
14615     private void dumpActivity(String prefix, FileDescriptor fd, PrintWriter pw,
14616             final ActivityRecord r, String[] args, boolean dumpAll) {
14617         String innerPrefix = prefix + "  ";
14618         synchronized (this) {
14619             pw.print(prefix); pw.print("ACTIVITY "); pw.print(r.shortComponentName);
14620                     pw.print(" "); pw.print(Integer.toHexString(System.identityHashCode(r)));
14621                     pw.print(" pid=");
14622                     if (r.app != null) pw.println(r.app.pid);
14623                     else pw.println("(not running)");
14624             if (dumpAll) {
14625                 r.dump(pw, innerPrefix);
14626             }
14627         }
14628         if (r.app != null && r.app.thread != null) {
14629             // flush anything that is already in the PrintWriter since the thread is going
14630             // to write to the file descriptor directly
14631             pw.flush();
14632             try {
14633                 TransferPipe tp = new TransferPipe();
14634                 try {
14635                     r.app.thread.dumpActivity(tp.getWriteFd().getFileDescriptor(),
14636                             r.appToken, innerPrefix, args);
14637                     tp.go(fd);
14638                 } finally {
14639                     tp.kill();
14640                 }
14641             } catch (IOException e) {
14642                 pw.println(innerPrefix + "Failure while dumping the activity: " + e);
14643             } catch (RemoteException e) {
14644                 pw.println(innerPrefix + "Got a RemoteException while dumping the activity");
14645             }
14646         }
14647     }
14648
14649     void dumpBroadcastsLocked(FileDescriptor fd, PrintWriter pw, String[] args,
14650             int opti, boolean dumpAll, String dumpPackage) {
14651         boolean needSep = false;
14652         boolean onlyHistory = false;
14653         boolean printedAnything = false;
14654
14655         if ("history".equals(dumpPackage)) {
14656             if (opti < args.length && "-s".equals(args[opti])) {
14657                 dumpAll = false;
14658             }
14659             onlyHistory = true;
14660             dumpPackage = null;
14661         }
14662
14663         pw.println("ACTIVITY MANAGER BROADCAST STATE (dumpsys activity broadcasts)");
14664         if (!onlyHistory && dumpAll) {
14665             if (mRegisteredReceivers.size() > 0) {
14666                 boolean printed = false;
14667                 Iterator it = mRegisteredReceivers.values().iterator();
14668                 while (it.hasNext()) {
14669                     ReceiverList r = (ReceiverList)it.next();
14670                     if (dumpPackage != null && (r.app == null ||
14671                             !dumpPackage.equals(r.app.info.packageName))) {
14672                         continue;
14673                     }
14674                     if (!printed) {
14675                         pw.println("  Registered Receivers:");
14676                         needSep = true;
14677                         printed = true;
14678                         printedAnything = true;
14679                     }
14680                     pw.print("  * "); pw.println(r);
14681                     r.dump(pw, "    ");
14682                 }
14683             }
14684
14685             if (mReceiverResolver.dump(pw, needSep ?
14686                     "\n  Receiver Resolver Table:" : "  Receiver Resolver Table:",
14687                     "    ", dumpPackage, false, false)) {
14688                 needSep = true;
14689                 printedAnything = true;
14690             }
14691         }
14692
14693         for (BroadcastQueue q : mBroadcastQueues) {
14694             needSep = q.dumpLocked(fd, pw, args, opti, dumpAll, dumpPackage, needSep);
14695             printedAnything |= needSep;
14696         }
14697
14698         needSep = true;
14699
14700         if (!onlyHistory && mStickyBroadcasts != null && dumpPackage == null) {
14701             for (int user=0; user<mStickyBroadcasts.size(); user++) {
14702                 if (needSep) {
14703                     pw.println();
14704                 }
14705                 needSep = true;
14706                 printedAnything = true;
14707                 pw.print("  Sticky broadcasts for user ");
14708                         pw.print(mStickyBroadcasts.keyAt(user)); pw.println(":");
14709                 StringBuilder sb = new StringBuilder(128);
14710                 for (Map.Entry<String, ArrayList<Intent>> ent
14711                         : mStickyBroadcasts.valueAt(user).entrySet()) {
14712                     pw.print("  * Sticky action "); pw.print(ent.getKey());
14713                     if (dumpAll) {
14714                         pw.println(":");
14715                         ArrayList<Intent> intents = ent.getValue();
14716                         final int N = intents.size();
14717                         for (int i=0; i<N; i++) {
14718                             sb.setLength(0);
14719                             sb.append("    Intent: ");
14720                             intents.get(i).toShortString(sb, false, true, false, false);
14721                             pw.println(sb.toString());
14722                             Bundle bundle = intents.get(i).getExtras();
14723                             if (bundle != null) {
14724                                 pw.print("      ");
14725                                 pw.println(bundle.toString());
14726                             }
14727                         }
14728                     } else {
14729                         pw.println("");
14730                     }
14731                 }
14732             }
14733         }
14734
14735         if (!onlyHistory && dumpAll) {
14736             pw.println();
14737             for (BroadcastQueue queue : mBroadcastQueues) {
14738                 pw.println("  mBroadcastsScheduled [" + queue.mQueueName + "]="
14739                         + queue.mBroadcastsScheduled);
14740             }
14741             pw.println("  mHandler:");
14742             mHandler.dump(new PrintWriterPrinter(pw), "    ");
14743             needSep = true;
14744             printedAnything = true;
14745         }
14746
14747         if (!printedAnything) {
14748             pw.println("  (nothing)");
14749         }
14750     }
14751
14752     void dumpProvidersLocked(FileDescriptor fd, PrintWriter pw, String[] args,
14753             int opti, boolean dumpAll, String dumpPackage) {
14754         boolean needSep;
14755         boolean printedAnything = false;
14756
14757         ItemMatcher matcher = new ItemMatcher();
14758         matcher.build(args, opti);
14759
14760         pw.println("ACTIVITY MANAGER CONTENT PROVIDERS (dumpsys activity providers)");
14761
14762         needSep = mProviderMap.dumpProvidersLocked(pw, dumpAll, dumpPackage);
14763         printedAnything |= needSep;
14764
14765         if (mLaunchingProviders.size() > 0) {
14766             boolean printed = false;
14767             for (int i=mLaunchingProviders.size()-1; i>=0; i--) {
14768                 ContentProviderRecord r = mLaunchingProviders.get(i);
14769                 if (dumpPackage != null && !dumpPackage.equals(r.name.getPackageName())) {
14770                     continue;
14771                 }
14772                 if (!printed) {
14773                     if (needSep) pw.println();
14774                     needSep = true;
14775                     pw.println("  Launching content providers:");
14776                     printed = true;
14777                     printedAnything = true;
14778                 }
14779                 pw.print("  Launching #"); pw.print(i); pw.print(": ");
14780                         pw.println(r);
14781             }
14782         }
14783
14784         if (!printedAnything) {
14785             pw.println("  (nothing)");
14786         }
14787     }
14788
14789     void dumpPermissionsLocked(FileDescriptor fd, PrintWriter pw, String[] args,
14790             int opti, boolean dumpAll, String dumpPackage) {
14791         boolean needSep = false;
14792         boolean printedAnything = false;
14793
14794         pw.println("ACTIVITY MANAGER URI PERMISSIONS (dumpsys activity permissions)");
14795
14796         if (mGrantedUriPermissions.size() > 0) {
14797             boolean printed = false;
14798             int dumpUid = -2;
14799             if (dumpPackage != null) {
14800                 try {
14801                     dumpUid = mContext.getPackageManager().getPackageUidAsUser(dumpPackage,
14802                             MATCH_UNINSTALLED_PACKAGES, 0);
14803                 } catch (NameNotFoundException e) {
14804                     dumpUid = -1;
14805                 }
14806             }
14807             for (int i=0; i<mGrantedUriPermissions.size(); i++) {
14808                 int uid = mGrantedUriPermissions.keyAt(i);
14809                 if (dumpUid >= -1 && UserHandle.getAppId(uid) != dumpUid) {
14810                     continue;
14811                 }
14812                 final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.valueAt(i);
14813                 if (!printed) {
14814                     if (needSep) pw.println();
14815                     needSep = true;
14816                     pw.println("  Granted Uri Permissions:");
14817                     printed = true;
14818                     printedAnything = true;
14819                 }
14820                 pw.print("  * UID "); pw.print(uid); pw.println(" holds:");
14821                 for (UriPermission perm : perms.values()) {
14822                     pw.print("    "); pw.println(perm);
14823                     if (dumpAll) {
14824                         perm.dump(pw, "      ");
14825                     }
14826                 }
14827             }
14828         }
14829
14830         if (!printedAnything) {
14831             pw.println("  (nothing)");
14832         }
14833     }
14834
14835     void dumpPendingIntentsLocked(FileDescriptor fd, PrintWriter pw, String[] args,
14836             int opti, boolean dumpAll, String dumpPackage) {
14837         boolean printed = false;
14838
14839         pw.println("ACTIVITY MANAGER PENDING INTENTS (dumpsys activity intents)");
14840
14841         if (mIntentSenderRecords.size() > 0) {
14842             Iterator<WeakReference<PendingIntentRecord>> it
14843                     = mIntentSenderRecords.values().iterator();
14844             while (it.hasNext()) {
14845                 WeakReference<PendingIntentRecord> ref = it.next();
14846                 PendingIntentRecord rec = ref != null ? ref.get(): null;
14847                 if (dumpPackage != null && (rec == null
14848                         || !dumpPackage.equals(rec.key.packageName))) {
14849                     continue;
14850                 }
14851                 printed = true;
14852                 if (rec != null) {
14853                     pw.print("  * "); pw.println(rec);
14854                     if (dumpAll) {
14855                         rec.dump(pw, "    ");
14856                     }
14857                 } else {
14858                     pw.print("  * "); pw.println(ref);
14859                 }
14860             }
14861         }
14862
14863         if (!printed) {
14864             pw.println("  (nothing)");
14865         }
14866     }
14867
14868     private static final int dumpProcessList(PrintWriter pw,
14869             ActivityManagerService service, List list,
14870             String prefix, String normalLabel, String persistentLabel,
14871             String dumpPackage) {
14872         int numPers = 0;
14873         final int N = list.size()-1;
14874         for (int i=N; i>=0; i--) {
14875             ProcessRecord r = (ProcessRecord)list.get(i);
14876             if (dumpPackage != null && !dumpPackage.equals(r.info.packageName)) {
14877                 continue;
14878             }
14879             pw.println(String.format("%s%s #%2d: %s",
14880                     prefix, (r.persistent ? persistentLabel : normalLabel),
14881                     i, r.toString()));
14882             if (r.persistent) {
14883                 numPers++;
14884             }
14885         }
14886         return numPers;
14887     }
14888
14889     private static final boolean dumpProcessOomList(PrintWriter pw,
14890             ActivityManagerService service, List<ProcessRecord> origList,
14891             String prefix, String normalLabel, String persistentLabel,
14892             boolean inclDetails, String dumpPackage) {
14893
14894         ArrayList<Pair<ProcessRecord, Integer>> list
14895                 = new ArrayList<Pair<ProcessRecord, Integer>>(origList.size());
14896         for (int i=0; i<origList.size(); i++) {
14897             ProcessRecord r = origList.get(i);
14898             if (dumpPackage != null && !r.pkgList.containsKey(dumpPackage)) {
14899                 continue;
14900             }
14901             list.add(new Pair<ProcessRecord, Integer>(origList.get(i), i));
14902         }
14903
14904         if (list.size() <= 0) {
14905             return false;
14906         }
14907
14908         Comparator<Pair<ProcessRecord, Integer>> comparator
14909                 = new Comparator<Pair<ProcessRecord, Integer>>() {
14910             @Override
14911             public int compare(Pair<ProcessRecord, Integer> object1,
14912                     Pair<ProcessRecord, Integer> object2) {
14913                 if (object1.first.setAdj != object2.first.setAdj) {
14914                     return object1.first.setAdj > object2.first.setAdj ? -1 : 1;
14915                 }
14916                 if (object1.first.setProcState != object2.first.setProcState) {
14917                     return object1.first.setProcState > object2.first.setProcState ? -1 : 1;
14918                 }
14919                 if (object1.second.intValue() != object2.second.intValue()) {
14920                     return object1.second.intValue() > object2.second.intValue() ? -1 : 1;
14921                 }
14922                 return 0;
14923             }
14924         };
14925
14926         Collections.sort(list, comparator);
14927
14928         final long curRealtime = SystemClock.elapsedRealtime();
14929         final long realtimeSince = curRealtime - service.mLastPowerCheckRealtime;
14930         final long curUptime = SystemClock.uptimeMillis();
14931         final long uptimeSince = curUptime - service.mLastPowerCheckUptime;
14932
14933         for (int i=list.size()-1; i>=0; i--) {
14934             ProcessRecord r = list.get(i).first;
14935             String oomAdj = ProcessList.makeOomAdjString(r.setAdj);
14936             char schedGroup;
14937             switch (r.setSchedGroup) {
14938                 case ProcessList.SCHED_GROUP_BACKGROUND:
14939                     schedGroup = 'B';
14940                     break;
14941                 case ProcessList.SCHED_GROUP_DEFAULT:
14942                     schedGroup = 'F';
14943                     break;
14944                 case ProcessList.SCHED_GROUP_TOP_APP:
14945                     schedGroup = 'T';
14946                     break;
14947                 default:
14948                     schedGroup = '?';
14949                     break;
14950             }
14951             char foreground;
14952             if (r.foregroundActivities) {
14953                 foreground = 'A';
14954             } else if (r.foregroundServices) {
14955                 foreground = 'S';
14956             } else {
14957                 foreground = ' ';
14958             }
14959             String procState = ProcessList.makeProcStateString(r.curProcState);
14960             pw.print(prefix);
14961             pw.print(r.persistent ? persistentLabel : normalLabel);
14962             pw.print(" #");
14963             int num = (origList.size()-1)-list.get(i).second;
14964             if (num < 10) pw.print(' ');
14965             pw.print(num);
14966             pw.print(": ");
14967             pw.print(oomAdj);
14968             pw.print(' ');
14969             pw.print(schedGroup);
14970             pw.print('/');
14971             pw.print(foreground);
14972             pw.print('/');
14973             pw.print(procState);
14974             pw.print(" trm:");
14975             if (r.trimMemoryLevel < 10) pw.print(' ');
14976             pw.print(r.trimMemoryLevel);
14977             pw.print(' ');
14978             pw.print(r.toShortString());
14979             pw.print(" (");
14980             pw.print(r.adjType);
14981             pw.println(')');
14982             if (r.adjSource != null || r.adjTarget != null) {
14983                 pw.print(prefix);
14984                 pw.print("    ");
14985                 if (r.adjTarget instanceof ComponentName) {
14986                     pw.print(((ComponentName)r.adjTarget).flattenToShortString());
14987                 } else if (r.adjTarget != null) {
14988                     pw.print(r.adjTarget.toString());
14989                 } else {
14990                     pw.print("{null}");
14991                 }
14992                 pw.print("<=");
14993                 if (r.adjSource instanceof ProcessRecord) {
14994                     pw.print("Proc{");
14995                     pw.print(((ProcessRecord)r.adjSource).toShortString());
14996                     pw.println("}");
14997                 } else if (r.adjSource != null) {
14998                     pw.println(r.adjSource.toString());
14999                 } else {
15000                     pw.println("{null}");
15001                 }
15002             }
15003             if (inclDetails) {
15004                 pw.print(prefix);
15005                 pw.print("    ");
15006                 pw.print("oom: max="); pw.print(r.maxAdj);
15007                 pw.print(" curRaw="); pw.print(r.curRawAdj);
15008                 pw.print(" setRaw="); pw.print(r.setRawAdj);
15009                 pw.print(" cur="); pw.print(r.curAdj);
15010                 pw.print(" set="); pw.println(r.setAdj);
15011                 pw.print(prefix);
15012                 pw.print("    ");
15013                 pw.print("state: cur="); pw.print(ProcessList.makeProcStateString(r.curProcState));
15014                 pw.print(" set="); pw.print(ProcessList.makeProcStateString(r.setProcState));
15015                 pw.print(" lastPss="); DebugUtils.printSizeValue(pw, r.lastPss*1024);
15016                 pw.print(" lastSwapPss="); DebugUtils.printSizeValue(pw, r.lastSwapPss*1024);
15017                 pw.print(" lastCachedPss="); DebugUtils.printSizeValue(pw, r.lastCachedPss*1024);
15018                 pw.println();
15019                 pw.print(prefix);
15020                 pw.print("    ");
15021                 pw.print("cached="); pw.print(r.cached);
15022                 pw.print(" empty="); pw.print(r.empty);
15023                 pw.print(" hasAboveClient="); pw.println(r.hasAboveClient);
15024
15025                 if (r.setProcState >= ActivityManager.PROCESS_STATE_SERVICE) {
15026                     if (r.lastWakeTime != 0) {
15027                         long wtime;
15028                         BatteryStatsImpl stats = service.mBatteryStatsService.getActiveStatistics();
15029                         synchronized (stats) {
15030                             wtime = stats.getProcessWakeTime(r.info.uid,
15031                                     r.pid, curRealtime);
15032                         }
15033                         long timeUsed = wtime - r.lastWakeTime;
15034                         pw.print(prefix);
15035                         pw.print("    ");
15036                         pw.print("keep awake over ");
15037                         TimeUtils.formatDuration(realtimeSince, pw);
15038                         pw.print(" used ");
15039                         TimeUtils.formatDuration(timeUsed, pw);
15040                         pw.print(" (");
15041                         pw.print((timeUsed*100)/realtimeSince);
15042                         pw.println("%)");
15043                     }
15044                     if (r.lastCpuTime != 0) {
15045                         long timeUsed = r.curCpuTime - r.lastCpuTime;
15046                         pw.print(prefix);
15047                         pw.print("    ");
15048                         pw.print("run cpu over ");
15049                         TimeUtils.formatDuration(uptimeSince, pw);
15050                         pw.print(" used ");
15051                         TimeUtils.formatDuration(timeUsed, pw);
15052                         pw.print(" (");
15053                         pw.print((timeUsed*100)/uptimeSince);
15054                         pw.println("%)");
15055                     }
15056                 }
15057             }
15058         }
15059         return true;
15060     }
15061
15062     ArrayList<ProcessRecord> collectProcesses(PrintWriter pw, int start, boolean allPkgs,
15063             String[] args) {
15064         ArrayList<ProcessRecord> procs;
15065         synchronized (this) {
15066             if (args != null && args.length > start
15067                     && args[start].charAt(0) != '-') {
15068                 procs = new ArrayList<ProcessRecord>();
15069                 int pid = -1;
15070                 try {
15071                     pid = Integer.parseInt(args[start]);
15072                 } catch (NumberFormatException e) {
15073                 }
15074                 for (int i=mLruProcesses.size()-1; i>=0; i--) {
15075                     ProcessRecord proc = mLruProcesses.get(i);
15076                     if (proc.pid == pid) {
15077                         procs.add(proc);
15078                     } else if (allPkgs && proc.pkgList != null
15079                             && proc.pkgList.containsKey(args[start])) {
15080                         procs.add(proc);
15081                     } else if (proc.processName.equals(args[start])) {
15082                         procs.add(proc);
15083                     }
15084                 }
15085                 if (procs.size() <= 0) {
15086                     return null;
15087                 }
15088             } else {
15089                 procs = new ArrayList<ProcessRecord>(mLruProcesses);
15090             }
15091         }
15092         return procs;
15093     }
15094
15095     final void dumpGraphicsHardwareUsage(FileDescriptor fd,
15096             PrintWriter pw, String[] args) {
15097         ArrayList<ProcessRecord> procs = collectProcesses(pw, 0, false, args);
15098         if (procs == null) {
15099             pw.println("No process found for: " + args[0]);
15100             return;
15101         }
15102
15103         long uptime = SystemClock.uptimeMillis();
15104         long realtime = SystemClock.elapsedRealtime();
15105         pw.println("Applications Graphics Acceleration Info:");
15106         pw.println("Uptime: " + uptime + " Realtime: " + realtime);
15107
15108         for (int i = procs.size() - 1 ; i >= 0 ; i--) {
15109             ProcessRecord r = procs.get(i);
15110             if (r.thread != null) {
15111                 pw.println("\n** Graphics info for pid " + r.pid + " [" + r.processName + "] **");
15112                 pw.flush();
15113                 try {
15114                     TransferPipe tp = new TransferPipe();
15115                     try {
15116                         r.thread.dumpGfxInfo(tp.getWriteFd().getFileDescriptor(), args);
15117                         tp.go(fd);
15118                     } finally {
15119                         tp.kill();
15120                     }
15121                 } catch (IOException e) {
15122                     pw.println("Failure while dumping the app: " + r);
15123                     pw.flush();
15124                 } catch (RemoteException e) {
15125                     pw.println("Got a RemoteException while dumping the app " + r);
15126                     pw.flush();
15127                 }
15128             }
15129         }
15130     }
15131
15132     final void dumpDbInfo(FileDescriptor fd, PrintWriter pw, String[] args) {
15133         ArrayList<ProcessRecord> procs = collectProcesses(pw, 0, false, args);
15134         if (procs == null) {
15135             pw.println("No process found for: " + args[0]);
15136             return;
15137         }
15138
15139         pw.println("Applications Database Info:");
15140
15141         for (int i = procs.size() - 1 ; i >= 0 ; i--) {
15142             ProcessRecord r = procs.get(i);
15143             if (r.thread != null) {
15144                 pw.println("\n** Database info for pid " + r.pid + " [" + r.processName + "] **");
15145                 pw.flush();
15146                 try {
15147                     TransferPipe tp = new TransferPipe();
15148                     try {
15149                         r.thread.dumpDbInfo(tp.getWriteFd().getFileDescriptor(), args);
15150                         tp.go(fd);
15151                     } finally {
15152                         tp.kill();
15153                     }
15154                 } catch (IOException e) {
15155                     pw.println("Failure while dumping the app: " + r);
15156                     pw.flush();
15157                 } catch (RemoteException e) {
15158                     pw.println("Got a RemoteException while dumping the app " + r);
15159                     pw.flush();
15160                 }
15161             }
15162         }
15163     }
15164
15165     final static class MemItem {
15166         final boolean isProc;
15167         final String label;
15168         final String shortLabel;
15169         final long pss;
15170         final long swapPss;
15171         final int id;
15172         final boolean hasActivities;
15173         ArrayList<MemItem> subitems;
15174
15175         public MemItem(String _label, String _shortLabel, long _pss, long _swapPss, int _id,
15176                 boolean _hasActivities) {
15177             isProc = true;
15178             label = _label;
15179             shortLabel = _shortLabel;
15180             pss = _pss;
15181             swapPss = _swapPss;
15182             id = _id;
15183             hasActivities = _hasActivities;
15184         }
15185
15186         public MemItem(String _label, String _shortLabel, long _pss, long _swapPss, int _id) {
15187             isProc = false;
15188             label = _label;
15189             shortLabel = _shortLabel;
15190             pss = _pss;
15191             swapPss = _swapPss;
15192             id = _id;
15193             hasActivities = false;
15194         }
15195     }
15196
15197     static final void dumpMemItems(PrintWriter pw, String prefix, String tag,
15198             ArrayList<MemItem> items, boolean sort, boolean isCompact, boolean dumpSwapPss) {
15199         if (sort && !isCompact) {
15200             Collections.sort(items, new Comparator<MemItem>() {
15201                 @Override
15202                 public int compare(MemItem lhs, MemItem rhs) {
15203                     if (lhs.pss < rhs.pss) {
15204                         return 1;
15205                     } else if (lhs.pss > rhs.pss) {
15206                         return -1;
15207                     }
15208                     return 0;
15209                 }
15210             });
15211         }
15212
15213         for (int i=0; i<items.size(); i++) {
15214             MemItem mi = items.get(i);
15215             if (!isCompact) {
15216                 if (dumpSwapPss) {
15217                     pw.printf("%s%s: %-60s (%s in swap)\n", prefix, stringifyKBSize(mi.pss),
15218                             mi.label, stringifyKBSize(mi.swapPss));
15219                 } else {
15220                     pw.printf("%s%s: %s\n", prefix, stringifyKBSize(mi.pss), mi.label);
15221                 }
15222             } else if (mi.isProc) {
15223                 pw.print("proc,"); pw.print(tag); pw.print(","); pw.print(mi.shortLabel);
15224                 pw.print(","); pw.print(mi.id); pw.print(","); pw.print(mi.pss); pw.print(",");
15225                 pw.print(dumpSwapPss ? mi.swapPss : "N/A");
15226                 pw.println(mi.hasActivities ? ",a" : ",e");
15227             } else {
15228                 pw.print(tag); pw.print(","); pw.print(mi.shortLabel); pw.print(",");
15229                 pw.print(mi.pss); pw.print(","); pw.println(dumpSwapPss ? mi.swapPss : "N/A");
15230             }
15231             if (mi.subitems != null) {
15232                 dumpMemItems(pw, prefix + "    ", mi.shortLabel, mi.subitems,
15233                         true, isCompact, dumpSwapPss);
15234             }
15235         }
15236     }
15237
15238     // These are in KB.
15239     static final long[] DUMP_MEM_BUCKETS = new long[] {
15240         5*1024, 7*1024, 10*1024, 15*1024, 20*1024, 30*1024, 40*1024, 80*1024,
15241         120*1024, 160*1024, 200*1024,
15242         250*1024, 300*1024, 350*1024, 400*1024, 500*1024, 600*1024, 800*1024,
15243         1*1024*1024, 2*1024*1024, 5*1024*1024, 10*1024*1024, 20*1024*1024
15244     };
15245
15246     static final void appendMemBucket(StringBuilder out, long memKB, String label,
15247             boolean stackLike) {
15248         int start = label.lastIndexOf('.');
15249         if (start >= 0) start++;
15250         else start = 0;
15251         int end = label.length();
15252         for (int i=0; i<DUMP_MEM_BUCKETS.length; i++) {
15253             if (DUMP_MEM_BUCKETS[i] >= memKB) {
15254                 long bucket = DUMP_MEM_BUCKETS[i]/1024;
15255                 out.append(bucket);
15256                 out.append(stackLike ? "MB." : "MB ");
15257                 out.append(label, start, end);
15258                 return;
15259             }
15260         }
15261         out.append(memKB/1024);
15262         out.append(stackLike ? "MB." : "MB ");
15263         out.append(label, start, end);
15264     }
15265
15266     static final int[] DUMP_MEM_OOM_ADJ = new int[] {
15267             ProcessList.NATIVE_ADJ,
15268             ProcessList.SYSTEM_ADJ, ProcessList.PERSISTENT_PROC_ADJ,
15269             ProcessList.PERSISTENT_SERVICE_ADJ, ProcessList.FOREGROUND_APP_ADJ,
15270             ProcessList.VISIBLE_APP_ADJ, ProcessList.PERCEPTIBLE_APP_ADJ,
15271             ProcessList.BACKUP_APP_ADJ, ProcessList.HEAVY_WEIGHT_APP_ADJ,
15272             ProcessList.SERVICE_ADJ, ProcessList.HOME_APP_ADJ,
15273             ProcessList.PREVIOUS_APP_ADJ, ProcessList.SERVICE_B_ADJ, ProcessList.CACHED_APP_MAX_ADJ
15274     };
15275     static final String[] DUMP_MEM_OOM_LABEL = new String[] {
15276             "Native",
15277             "System", "Persistent", "Persistent Service", "Foreground",
15278             "Visible", "Perceptible",
15279             "Heavy Weight", "Backup",
15280             "A Services", "Home",
15281             "Previous", "B Services", "Cached"
15282     };
15283     static final String[] DUMP_MEM_OOM_COMPACT_LABEL = new String[] {
15284             "native",
15285             "sys", "pers", "persvc", "fore",
15286             "vis", "percept",
15287             "heavy", "backup",
15288             "servicea", "home",
15289             "prev", "serviceb", "cached"
15290     };
15291
15292     private final void dumpApplicationMemoryUsageHeader(PrintWriter pw, long uptime,
15293             long realtime, boolean isCheckinRequest, boolean isCompact) {
15294         if (isCompact) {
15295             pw.print("version,"); pw.println(MEMINFO_COMPACT_VERSION);
15296         }
15297         if (isCheckinRequest || isCompact) {
15298             // short checkin version
15299             pw.print("time,"); pw.print(uptime); pw.print(","); pw.println(realtime);
15300         } else {
15301             pw.println("Applications Memory Usage (in Kilobytes):");
15302             pw.println("Uptime: " + uptime + " Realtime: " + realtime);
15303         }
15304     }
15305
15306     private static final int KSM_SHARED = 0;
15307     private static final int KSM_SHARING = 1;
15308     private static final int KSM_UNSHARED = 2;
15309     private static final int KSM_VOLATILE = 3;
15310
15311     private final long[] getKsmInfo() {
15312         long[] longOut = new long[4];
15313         final int[] SINGLE_LONG_FORMAT = new int[] {
15314             Process.PROC_SPACE_TERM|Process.PROC_OUT_LONG
15315         };
15316         long[] longTmp = new long[1];
15317         Process.readProcFile("/sys/kernel/mm/ksm/pages_shared",
15318                 SINGLE_LONG_FORMAT, null, longTmp, null);
15319         longOut[KSM_SHARED] = longTmp[0] * ProcessList.PAGE_SIZE / 1024;
15320         longTmp[0] = 0;
15321         Process.readProcFile("/sys/kernel/mm/ksm/pages_sharing",
15322                 SINGLE_LONG_FORMAT, null, longTmp, null);
15323         longOut[KSM_SHARING] = longTmp[0] * ProcessList.PAGE_SIZE / 1024;
15324         longTmp[0] = 0;
15325         Process.readProcFile("/sys/kernel/mm/ksm/pages_unshared",
15326                 SINGLE_LONG_FORMAT, null, longTmp, null);
15327         longOut[KSM_UNSHARED] = longTmp[0] * ProcessList.PAGE_SIZE / 1024;
15328         longTmp[0] = 0;
15329         Process.readProcFile("/sys/kernel/mm/ksm/pages_volatile",
15330                 SINGLE_LONG_FORMAT, null, longTmp, null);
15331         longOut[KSM_VOLATILE] = longTmp[0] * ProcessList.PAGE_SIZE / 1024;
15332         return longOut;
15333     }
15334
15335     private static String stringifySize(long size, int order) {
15336         Locale locale = Locale.US;
15337         switch (order) {
15338             case 1:
15339                 return String.format(locale, "%,13d", size);
15340             case 1024:
15341                 return String.format(locale, "%,9dK", size / 1024);
15342             case 1024 * 1024:
15343                 return String.format(locale, "%,5dM", size / 1024 / 1024);
15344             case 1024 * 1024 * 1024:
15345                 return String.format(locale, "%,1dG", size / 1024 / 1024 / 1024);
15346             default:
15347                 throw new IllegalArgumentException("Invalid size order");
15348         }
15349     }
15350
15351     private static String stringifyKBSize(long size) {
15352         return stringifySize(size * 1024, 1024);
15353     }
15354
15355     // Update this version number in case you change the 'compact' format
15356     private static final int MEMINFO_COMPACT_VERSION = 1;
15357
15358     final void dumpApplicationMemoryUsage(FileDescriptor fd,
15359             PrintWriter pw, String prefix, String[] args, boolean brief, PrintWriter categoryPw) {
15360         boolean dumpDetails = false;
15361         boolean dumpFullDetails = false;
15362         boolean dumpDalvik = false;
15363         boolean dumpSummaryOnly = false;
15364         boolean dumpUnreachable = false;
15365         boolean oomOnly = false;
15366         boolean isCompact = false;
15367         boolean localOnly = false;
15368         boolean packages = false;
15369         boolean isCheckinRequest = false;
15370         boolean dumpSwapPss = false;
15371
15372         int opti = 0;
15373         while (opti < args.length) {
15374             String opt = args[opti];
15375             if (opt == null || opt.length() <= 0 || opt.charAt(0) != '-') {
15376                 break;
15377             }
15378             opti++;
15379             if ("-a".equals(opt)) {
15380                 dumpDetails = true;
15381                 dumpFullDetails = true;
15382                 dumpDalvik = true;
15383                 dumpSwapPss = true;
15384             } else if ("-d".equals(opt)) {
15385                 dumpDalvik = true;
15386             } else if ("-c".equals(opt)) {
15387                 isCompact = true;
15388             } else if ("-s".equals(opt)) {
15389                 dumpDetails = true;
15390                 dumpSummaryOnly = true;
15391             } else if ("-S".equals(opt)) {
15392                 dumpSwapPss = true;
15393             } else if ("--unreachable".equals(opt)) {
15394                 dumpUnreachable = true;
15395             } else if ("--oom".equals(opt)) {
15396                 oomOnly = true;
15397             } else if ("--local".equals(opt)) {
15398                 localOnly = true;
15399             } else if ("--package".equals(opt)) {
15400                 packages = true;
15401             } else if ("--checkin".equals(opt)) {
15402                 isCheckinRequest = true;
15403
15404             } else if ("-h".equals(opt)) {
15405                 pw.println("meminfo dump options: [-a] [-d] [-c] [-s] [--oom] [process]");
15406                 pw.println("  -a: include all available information for each process.");
15407                 pw.println("  -d: include dalvik details.");
15408                 pw.println("  -c: dump in a compact machine-parseable representation.");
15409                 pw.println("  -s: dump only summary of application memory usage.");
15410                 pw.println("  -S: dump also SwapPss.");
15411                 pw.println("  --oom: only show processes organized by oom adj.");
15412                 pw.println("  --local: only collect details locally, don't call process.");
15413                 pw.println("  --package: interpret process arg as package, dumping all");
15414                 pw.println("             processes that have loaded that package.");
15415                 pw.println("  --checkin: dump data for a checkin");
15416                 pw.println("If [process] is specified it can be the name or ");
15417                 pw.println("pid of a specific process to dump.");
15418                 return;
15419             } else {
15420                 pw.println("Unknown argument: " + opt + "; use -h for help");
15421             }
15422         }
15423
15424         long uptime = SystemClock.uptimeMillis();
15425         long realtime = SystemClock.elapsedRealtime();
15426         final long[] tmpLong = new long[1];
15427
15428         ArrayList<ProcessRecord> procs = collectProcesses(pw, opti, packages, args);
15429         if (procs == null) {
15430             // No Java processes.  Maybe they want to print a native process.
15431             if (args != null && args.length > opti
15432                     && args[opti].charAt(0) != '-') {
15433                 ArrayList<ProcessCpuTracker.Stats> nativeProcs
15434                         = new ArrayList<ProcessCpuTracker.Stats>();
15435                 updateCpuStatsNow();
15436                 int findPid = -1;
15437                 try {
15438                     findPid = Integer.parseInt(args[opti]);
15439                 } catch (NumberFormatException e) {
15440                 }
15441                 synchronized (mProcessCpuTracker) {
15442                     final int N = mProcessCpuTracker.countStats();
15443                     for (int i=0; i<N; i++) {
15444                         ProcessCpuTracker.Stats st = mProcessCpuTracker.getStats(i);
15445                         if (st.pid == findPid || (st.baseName != null
15446                                 && st.baseName.equals(args[opti]))) {
15447                             nativeProcs.add(st);
15448                         }
15449                     }
15450                 }
15451                 if (nativeProcs.size() > 0) {
15452                     dumpApplicationMemoryUsageHeader(pw, uptime, realtime, isCheckinRequest,
15453                             isCompact);
15454                     Debug.MemoryInfo mi = null;
15455                     for (int i = nativeProcs.size() - 1 ; i >= 0 ; i--) {
15456                         final ProcessCpuTracker.Stats r = nativeProcs.get(i);
15457                         final int pid = r.pid;
15458                         if (!isCheckinRequest && dumpDetails) {
15459                             pw.println("\n** MEMINFO in pid " + pid + " [" + r.baseName + "] **");
15460                         }
15461                         if (mi == null) {
15462                             mi = new Debug.MemoryInfo();
15463                         }
15464                         if (dumpDetails || (!brief && !oomOnly)) {
15465                             Debug.getMemoryInfo(pid, mi);
15466                         } else {
15467                             mi.dalvikPss = (int)Debug.getPss(pid, tmpLong, null);
15468                             mi.dalvikPrivateDirty = (int)tmpLong[0];
15469                         }
15470                         ActivityThread.dumpMemInfoTable(pw, mi, isCheckinRequest, dumpFullDetails,
15471                                 dumpDalvik, dumpSummaryOnly, pid, r.baseName, 0, 0, 0, 0, 0, 0);
15472                         if (isCheckinRequest) {
15473                             pw.println();
15474                         }
15475                     }
15476                     return;
15477                 }
15478             }
15479             pw.println("No process found for: " + args[opti]);
15480             return;
15481         }
15482
15483         if (!brief && !oomOnly && (procs.size() == 1 || isCheckinRequest || packages)) {
15484             dumpDetails = true;
15485         }
15486
15487         dumpApplicationMemoryUsageHeader(pw, uptime, realtime, isCheckinRequest, isCompact);
15488
15489         String[] innerArgs = new String[args.length-opti];
15490         System.arraycopy(args, opti, innerArgs, 0, args.length-opti);
15491
15492         ArrayList<MemItem> procMems = new ArrayList<MemItem>();
15493         final SparseArray<MemItem> procMemsMap = new SparseArray<MemItem>();
15494         long nativePss = 0;
15495         long nativeSwapPss = 0;
15496         long dalvikPss = 0;
15497         long dalvikSwapPss = 0;
15498         long[] dalvikSubitemPss = dumpDalvik ? new long[Debug.MemoryInfo.NUM_DVK_STATS] :
15499                 EmptyArray.LONG;
15500         long[] dalvikSubitemSwapPss = dumpDalvik ? new long[Debug.MemoryInfo.NUM_DVK_STATS] :
15501                 EmptyArray.LONG;
15502         long otherPss = 0;
15503         long otherSwapPss = 0;
15504         long[] miscPss = new long[Debug.MemoryInfo.NUM_OTHER_STATS];
15505         long[] miscSwapPss = new long[Debug.MemoryInfo.NUM_OTHER_STATS];
15506
15507         long oomPss[] = new long[DUMP_MEM_OOM_LABEL.length];
15508         long oomSwapPss[] = new long[DUMP_MEM_OOM_LABEL.length];
15509         ArrayList<MemItem>[] oomProcs = (ArrayList<MemItem>[])
15510                 new ArrayList[DUMP_MEM_OOM_LABEL.length];
15511
15512         long totalPss = 0;
15513         long totalSwapPss = 0;
15514         long cachedPss = 0;
15515         long cachedSwapPss = 0;
15516         boolean hasSwapPss = false;
15517
15518         Debug.MemoryInfo mi = null;
15519         for (int i = procs.size() - 1 ; i >= 0 ; i--) {
15520             final ProcessRecord r = procs.get(i);
15521             final IApplicationThread thread;
15522             final int pid;
15523             final int oomAdj;
15524             final boolean hasActivities;
15525             synchronized (this) {
15526                 thread = r.thread;
15527                 pid = r.pid;
15528                 oomAdj = r.getSetAdjWithServices();
15529                 hasActivities = r.activities.size() > 0;
15530             }
15531             if (thread != null) {
15532                 if (!isCheckinRequest && dumpDetails) {
15533                     pw.println("\n** MEMINFO in pid " + pid + " [" + r.processName + "] **");
15534                 }
15535                 if (mi == null) {
15536                     mi = new Debug.MemoryInfo();
15537                 }
15538                 if (dumpDetails || (!brief && !oomOnly)) {
15539                     Debug.getMemoryInfo(pid, mi);
15540                     hasSwapPss = mi.hasSwappedOutPss;
15541                 } else {
15542                     mi.dalvikPss = (int)Debug.getPss(pid, tmpLong, null);
15543                     mi.dalvikPrivateDirty = (int)tmpLong[0];
15544                 }
15545                 if (dumpDetails) {
15546                     if (localOnly) {
15547                         ActivityThread.dumpMemInfoTable(pw, mi, isCheckinRequest, dumpFullDetails,
15548                                 dumpDalvik, dumpSummaryOnly, pid, r.processName, 0, 0, 0, 0, 0, 0);
15549                         if (isCheckinRequest) {
15550                             pw.println();
15551                         }
15552                     } else {
15553                         try {
15554                             pw.flush();
15555                             thread.dumpMemInfo(fd, mi, isCheckinRequest, dumpFullDetails,
15556                                     dumpDalvik, dumpSummaryOnly, dumpUnreachable, innerArgs);
15557                         } catch (RemoteException e) {
15558                             if (!isCheckinRequest) {
15559                                 pw.println("Got RemoteException!");
15560                                 pw.flush();
15561                             }
15562                         }
15563                     }
15564                 }
15565
15566                 final long myTotalPss = mi.getTotalPss();
15567                 final long myTotalUss = mi.getTotalUss();
15568                 final long myTotalSwapPss = mi.getTotalSwappedOutPss();
15569
15570                 synchronized (this) {
15571                     if (r.thread != null && oomAdj == r.getSetAdjWithServices()) {
15572                         // Record this for posterity if the process has been stable.
15573                         r.baseProcessTracker.addPss(myTotalPss, myTotalUss, true, r.pkgList);
15574                     }
15575                 }
15576
15577                 if (!isCheckinRequest && mi != null) {
15578                     totalPss += myTotalPss;
15579                     totalSwapPss += myTotalSwapPss;
15580                     MemItem pssItem = new MemItem(r.processName + " (pid " + pid +
15581                             (hasActivities ? " / activities)" : ")"), r.processName, myTotalPss,
15582                             myTotalSwapPss, pid, hasActivities);
15583                     procMems.add(pssItem);
15584                     procMemsMap.put(pid, pssItem);
15585
15586                     nativePss += mi.nativePss;
15587                     nativeSwapPss += mi.nativeSwappedOutPss;
15588                     dalvikPss += mi.dalvikPss;
15589                     dalvikSwapPss += mi.dalvikSwappedOutPss;
15590                     for (int j=0; j<dalvikSubitemPss.length; j++) {
15591                         dalvikSubitemPss[j] += mi.getOtherPss(Debug.MemoryInfo.NUM_OTHER_STATS + j);
15592                         dalvikSubitemSwapPss[j] +=
15593                                 mi.getOtherSwappedOutPss(Debug.MemoryInfo.NUM_OTHER_STATS + j);
15594                     }
15595                     otherPss += mi.otherPss;
15596                     otherSwapPss += mi.otherSwappedOutPss;
15597                     for (int j=0; j<Debug.MemoryInfo.NUM_OTHER_STATS; j++) {
15598                         long mem = mi.getOtherPss(j);
15599                         miscPss[j] += mem;
15600                         otherPss -= mem;
15601                         mem = mi.getOtherSwappedOutPss(j);
15602                         miscSwapPss[j] += mem;
15603                         otherSwapPss -= mem;
15604                     }
15605
15606                     if (oomAdj >= ProcessList.CACHED_APP_MIN_ADJ) {
15607                         cachedPss += myTotalPss;
15608                         cachedSwapPss += myTotalSwapPss;
15609                     }
15610
15611                     for (int oomIndex=0; oomIndex<oomPss.length; oomIndex++) {
15612                         if (oomAdj <= DUMP_MEM_OOM_ADJ[oomIndex]
15613                                 || oomIndex == (oomPss.length-1)) {
15614                             oomPss[oomIndex] += myTotalPss;
15615                             oomSwapPss[oomIndex] += myTotalSwapPss;
15616                             if (oomProcs[oomIndex] == null) {
15617                                 oomProcs[oomIndex] = new ArrayList<MemItem>();
15618                             }
15619                             oomProcs[oomIndex].add(pssItem);
15620                             break;
15621                         }
15622                     }
15623                 }
15624             }
15625         }
15626
15627         long nativeProcTotalPss = 0;
15628
15629         if (!isCheckinRequest && procs.size() > 1 && !packages) {
15630             // If we are showing aggregations, also look for native processes to
15631             // include so that our aggregations are more accurate.
15632             updateCpuStatsNow();
15633             mi = null;
15634             synchronized (mProcessCpuTracker) {
15635                 final int N = mProcessCpuTracker.countStats();
15636                 for (int i=0; i<N; i++) {
15637                     ProcessCpuTracker.Stats st = mProcessCpuTracker.getStats(i);
15638                     if (st.vsize > 0 && procMemsMap.indexOfKey(st.pid) < 0) {
15639                         if (mi == null) {
15640                             mi = new Debug.MemoryInfo();
15641                         }
15642                         if (!brief && !oomOnly) {
15643                             Debug.getMemoryInfo(st.pid, mi);
15644                         } else {
15645                             mi.nativePss = (int)Debug.getPss(st.pid, tmpLong, null);
15646                             mi.nativePrivateDirty = (int)tmpLong[0];
15647                         }
15648
15649                         final long myTotalPss = mi.getTotalPss();
15650                         final long myTotalSwapPss = mi.getTotalSwappedOutPss();
15651                         totalPss += myTotalPss;
15652                         nativeProcTotalPss += myTotalPss;
15653
15654                         MemItem pssItem = new MemItem(st.name + " (pid " + st.pid + ")",
15655                                 st.name, myTotalPss, mi.getSummaryTotalSwapPss(), st.pid, false);
15656                         procMems.add(pssItem);
15657
15658                         nativePss += mi.nativePss;
15659                         nativeSwapPss += mi.nativeSwappedOutPss;
15660                         dalvikPss += mi.dalvikPss;
15661                         dalvikSwapPss += mi.dalvikSwappedOutPss;
15662                         for (int j=0; j<dalvikSubitemPss.length; j++) {
15663                             dalvikSubitemPss[j] += mi.getOtherPss(Debug.MemoryInfo.NUM_OTHER_STATS + j);
15664                             dalvikSubitemSwapPss[j] +=
15665                                     mi.getOtherSwappedOutPss(Debug.MemoryInfo.NUM_OTHER_STATS + j);
15666                         }
15667                         otherPss += mi.otherPss;
15668                         otherSwapPss += mi.otherSwappedOutPss;
15669                         for (int j=0; j<Debug.MemoryInfo.NUM_OTHER_STATS; j++) {
15670                             long mem = mi.getOtherPss(j);
15671                             miscPss[j] += mem;
15672                             otherPss -= mem;
15673                             mem = mi.getOtherSwappedOutPss(j);
15674                             miscSwapPss[j] += mem;
15675                             otherSwapPss -= mem;
15676                         }
15677                         oomPss[0] += myTotalPss;
15678                         oomSwapPss[0] += myTotalSwapPss;
15679                         if (oomProcs[0] == null) {
15680                             oomProcs[0] = new ArrayList<MemItem>();
15681                         }
15682                         oomProcs[0].add(pssItem);
15683                     }
15684                 }
15685             }
15686
15687             ArrayList<MemItem> catMems = new ArrayList<MemItem>();
15688
15689             catMems.add(new MemItem("Native", "Native", nativePss, nativeSwapPss, -1));
15690             final MemItem dalvikItem =
15691                     new MemItem("Dalvik", "Dalvik", dalvikPss, dalvikSwapPss, -2);
15692             if (dalvikSubitemPss.length > 0) {
15693                 dalvikItem.subitems = new ArrayList<MemItem>();
15694                 for (int j=0; j<dalvikSubitemPss.length; j++) {
15695                     final String name = Debug.MemoryInfo.getOtherLabel(
15696                             Debug.MemoryInfo.NUM_OTHER_STATS + j);
15697                     dalvikItem.subitems.add(new MemItem(name, name, dalvikSubitemPss[j],
15698                                     dalvikSubitemSwapPss[j], j));
15699                 }
15700             }
15701             catMems.add(dalvikItem);
15702             catMems.add(new MemItem("Unknown", "Unknown", otherPss, otherSwapPss, -3));
15703             for (int j=0; j<Debug.MemoryInfo.NUM_OTHER_STATS; j++) {
15704                 String label = Debug.MemoryInfo.getOtherLabel(j);
15705                 catMems.add(new MemItem(label, label, miscPss[j], miscSwapPss[j], j));
15706             }
15707
15708             ArrayList<MemItem> oomMems = new ArrayList<MemItem>();
15709             for (int j=0; j<oomPss.length; j++) {
15710                 if (oomPss[j] != 0) {
15711                     String label = isCompact ? DUMP_MEM_OOM_COMPACT_LABEL[j]
15712                             : DUMP_MEM_OOM_LABEL[j];
15713                     MemItem item = new MemItem(label, label, oomPss[j], oomSwapPss[j],
15714                             DUMP_MEM_OOM_ADJ[j]);
15715                     item.subitems = oomProcs[j];
15716                     oomMems.add(item);
15717                 }
15718             }
15719
15720             dumpSwapPss = dumpSwapPss && hasSwapPss && totalSwapPss != 0;
15721             if (!brief && !oomOnly && !isCompact) {
15722                 pw.println();
15723                 pw.println("Total PSS by process:");
15724                 dumpMemItems(pw, "  ", "proc", procMems, true, isCompact, dumpSwapPss);
15725                 pw.println();
15726             }
15727             if (!isCompact) {
15728                 pw.println("Total PSS by OOM adjustment:");
15729             }
15730             dumpMemItems(pw, "  ", "oom", oomMems, false, isCompact, dumpSwapPss);
15731             if (!brief && !oomOnly) {
15732                 PrintWriter out = categoryPw != null ? categoryPw : pw;
15733                 if (!isCompact) {
15734                     out.println();
15735                     out.println("Total PSS by category:");
15736                 }
15737                 dumpMemItems(out, "  ", "cat", catMems, true, isCompact, dumpSwapPss);
15738             }
15739             if (!isCompact) {
15740                 pw.println();
15741             }
15742             MemInfoReader memInfo = new MemInfoReader();
15743             memInfo.readMemInfo();
15744             if (nativeProcTotalPss > 0) {
15745                 synchronized (this) {
15746                     final long cachedKb = memInfo.getCachedSizeKb();
15747                     final long freeKb = memInfo.getFreeSizeKb();
15748                     final long zramKb = memInfo.getZramTotalSizeKb();
15749                     final long kernelKb = memInfo.getKernelUsedSizeKb();
15750                     EventLogTags.writeAmMeminfo(cachedKb*1024, freeKb*1024, zramKb*1024,
15751                             kernelKb*1024, nativeProcTotalPss*1024);
15752                     mProcessStats.addSysMemUsageLocked(cachedKb, freeKb, zramKb, kernelKb,
15753                             nativeProcTotalPss);
15754                 }
15755             }
15756             if (!brief) {
15757                 if (!isCompact) {
15758                     pw.print("Total RAM: "); pw.print(stringifyKBSize(memInfo.getTotalSizeKb()));
15759                     pw.print(" (status ");
15760                     switch (mLastMemoryLevel) {
15761                         case ProcessStats.ADJ_MEM_FACTOR_NORMAL:
15762                             pw.println("normal)");
15763                             break;
15764                         case ProcessStats.ADJ_MEM_FACTOR_MODERATE:
15765                             pw.println("moderate)");
15766                             break;
15767                         case ProcessStats.ADJ_MEM_FACTOR_LOW:
15768                             pw.println("low)");
15769                             break;
15770                         case ProcessStats.ADJ_MEM_FACTOR_CRITICAL:
15771                             pw.println("critical)");
15772                             break;
15773                         default:
15774                             pw.print(mLastMemoryLevel);
15775                             pw.println(")");
15776                             break;
15777                     }
15778                     pw.print(" Free RAM: ");
15779                     pw.print(stringifyKBSize(cachedPss + memInfo.getCachedSizeKb()
15780                             + memInfo.getFreeSizeKb()));
15781                     pw.print(" (");
15782                     pw.print(stringifyKBSize(cachedPss));
15783                     pw.print(" cached pss + ");
15784                     pw.print(stringifyKBSize(memInfo.getCachedSizeKb()));
15785                     pw.print(" cached kernel + ");
15786                     pw.print(stringifyKBSize(memInfo.getFreeSizeKb()));
15787                     pw.println(" free)");
15788                 } else {
15789                     pw.print("ram,"); pw.print(memInfo.getTotalSizeKb()); pw.print(",");
15790                     pw.print(cachedPss + memInfo.getCachedSizeKb()
15791                             + memInfo.getFreeSizeKb()); pw.print(",");
15792                     pw.println(totalPss - cachedPss);
15793                 }
15794             }
15795             long lostRAM = memInfo.getTotalSizeKb()
15796                     - totalPss - memInfo.getFreeSizeKb() - memInfo.getCachedSizeKb()
15797                     - memInfo.getKernelUsedSizeKb() - memInfo.getZramTotalSizeKb();
15798             if (!isCompact) {
15799                 pw.print(" Used RAM: "); pw.print(stringifyKBSize(totalPss - cachedPss
15800                         + memInfo.getKernelUsedSizeKb())); pw.print(" (");
15801                 pw.print(stringifyKBSize(totalPss - cachedPss)); pw.print(" used pss + ");
15802                 pw.print(stringifyKBSize(memInfo.getKernelUsedSizeKb())); pw.print(" kernel)\n");
15803                 pw.print(" Lost RAM: "); pw.println(stringifyKBSize(lostRAM));
15804             } else {
15805                 pw.print("lostram,"); pw.println(lostRAM);
15806             }
15807             if (!brief) {
15808                 if (memInfo.getZramTotalSizeKb() != 0) {
15809                     if (!isCompact) {
15810                         pw.print("     ZRAM: ");
15811                         pw.print(stringifyKBSize(memInfo.getZramTotalSizeKb()));
15812                                 pw.print(" physical used for ");
15813                                 pw.print(stringifyKBSize(memInfo.getSwapTotalSizeKb()
15814                                         - memInfo.getSwapFreeSizeKb()));
15815                                 pw.print(" in swap (");
15816                                 pw.print(stringifyKBSize(memInfo.getSwapTotalSizeKb()));
15817                                 pw.println(" total swap)");
15818                     } else {
15819                         pw.print("zram,"); pw.print(memInfo.getZramTotalSizeKb()); pw.print(",");
15820                                 pw.print(memInfo.getSwapTotalSizeKb()); pw.print(",");
15821                                 pw.println(memInfo.getSwapFreeSizeKb());
15822                     }
15823                 }
15824                 final long[] ksm = getKsmInfo();
15825                 if (!isCompact) {
15826                     if (ksm[KSM_SHARING] != 0 || ksm[KSM_SHARED] != 0 || ksm[KSM_UNSHARED] != 0
15827                             || ksm[KSM_VOLATILE] != 0) {
15828                         pw.print("      KSM: "); pw.print(stringifyKBSize(ksm[KSM_SHARING]));
15829                                 pw.print(" saved from shared ");
15830                                 pw.print(stringifyKBSize(ksm[KSM_SHARED]));
15831                         pw.print("           "); pw.print(stringifyKBSize(ksm[KSM_UNSHARED]));
15832                                 pw.print(" unshared; ");
15833                                 pw.print(stringifyKBSize(
15834                                              ksm[KSM_VOLATILE])); pw.println(" volatile");
15835                     }
15836                     pw.print("   Tuning: ");
15837                     pw.print(ActivityManager.staticGetMemoryClass());
15838                     pw.print(" (large ");
15839                     pw.print(ActivityManager.staticGetLargeMemoryClass());
15840                     pw.print("), oom ");
15841                     pw.print(stringifySize(
15842                                 mProcessList.getMemLevel(ProcessList.CACHED_APP_MAX_ADJ), 1024));
15843                     pw.print(", restore limit ");
15844                     pw.print(stringifyKBSize(mProcessList.getCachedRestoreThresholdKb()));
15845                     if (ActivityManager.isLowRamDeviceStatic()) {
15846                         pw.print(" (low-ram)");
15847                     }
15848                     if (ActivityManager.isHighEndGfx()) {
15849                         pw.print(" (high-end-gfx)");
15850                     }
15851                     pw.println();
15852                 } else {
15853                     pw.print("ksm,"); pw.print(ksm[KSM_SHARING]); pw.print(",");
15854                     pw.print(ksm[KSM_SHARED]); pw.print(","); pw.print(ksm[KSM_UNSHARED]);
15855                     pw.print(","); pw.println(ksm[KSM_VOLATILE]);
15856                     pw.print("tuning,");
15857                     pw.print(ActivityManager.staticGetMemoryClass());
15858                     pw.print(',');
15859                     pw.print(ActivityManager.staticGetLargeMemoryClass());
15860                     pw.print(',');
15861                     pw.print(mProcessList.getMemLevel(ProcessList.CACHED_APP_MAX_ADJ)/1024);
15862                     if (ActivityManager.isLowRamDeviceStatic()) {
15863                         pw.print(",low-ram");
15864                     }
15865                     if (ActivityManager.isHighEndGfx()) {
15866                         pw.print(",high-end-gfx");
15867                     }
15868                     pw.println();
15869                 }
15870             }
15871         }
15872     }
15873
15874     private void appendBasicMemEntry(StringBuilder sb, int oomAdj, int procState, long pss,
15875             long memtrack, String name) {
15876         sb.append("  ");
15877         sb.append(ProcessList.makeOomAdjString(oomAdj));
15878         sb.append(' ');
15879         sb.append(ProcessList.makeProcStateString(procState));
15880         sb.append(' ');
15881         ProcessList.appendRamKb(sb, pss);
15882         sb.append(": ");
15883         sb.append(name);
15884         if (memtrack > 0) {
15885             sb.append(" (");
15886             sb.append(stringifyKBSize(memtrack));
15887             sb.append(" memtrack)");
15888         }
15889     }
15890
15891     private void appendMemInfo(StringBuilder sb, ProcessMemInfo mi) {
15892         appendBasicMemEntry(sb, mi.oomAdj, mi.procState, mi.pss, mi.memtrack, mi.name);
15893         sb.append(" (pid ");
15894         sb.append(mi.pid);
15895         sb.append(") ");
15896         sb.append(mi.adjType);
15897         sb.append('\n');
15898         if (mi.adjReason != null) {
15899             sb.append("                      ");
15900             sb.append(mi.adjReason);
15901             sb.append('\n');
15902         }
15903     }
15904
15905     void reportMemUsage(ArrayList<ProcessMemInfo> memInfos) {
15906         final SparseArray<ProcessMemInfo> infoMap = new SparseArray<>(memInfos.size());
15907         for (int i=0, N=memInfos.size(); i<N; i++) {
15908             ProcessMemInfo mi = memInfos.get(i);
15909             infoMap.put(mi.pid, mi);
15910         }
15911         updateCpuStatsNow();
15912         long[] memtrackTmp = new long[1];
15913         synchronized (mProcessCpuTracker) {
15914             final int N = mProcessCpuTracker.countStats();
15915             for (int i=0; i<N; i++) {
15916                 ProcessCpuTracker.Stats st = mProcessCpuTracker.getStats(i);
15917                 if (st.vsize > 0) {
15918                     long pss = Debug.getPss(st.pid, null, memtrackTmp);
15919                     if (pss > 0) {
15920                         if (infoMap.indexOfKey(st.pid) < 0) {
15921                             ProcessMemInfo mi = new ProcessMemInfo(st.name, st.pid,
15922                                     ProcessList.NATIVE_ADJ, -1, "native", null);
15923                             mi.pss = pss;
15924                             mi.memtrack = memtrackTmp[0];
15925                             memInfos.add(mi);
15926                         }
15927                     }
15928                 }
15929             }
15930         }
15931
15932         long totalPss = 0;
15933         long totalMemtrack = 0;
15934         for (int i=0, N=memInfos.size(); i<N; i++) {
15935             ProcessMemInfo mi = memInfos.get(i);
15936             if (mi.pss == 0) {
15937                 mi.pss = Debug.getPss(mi.pid, null, memtrackTmp);
15938                 mi.memtrack = memtrackTmp[0];
15939             }
15940             totalPss += mi.pss;
15941             totalMemtrack += mi.memtrack;
15942         }
15943         Collections.sort(memInfos, new Comparator<ProcessMemInfo>() {
15944             @Override public int compare(ProcessMemInfo lhs, ProcessMemInfo rhs) {
15945                 if (lhs.oomAdj != rhs.oomAdj) {
15946                     return lhs.oomAdj < rhs.oomAdj ? -1 : 1;
15947                 }
15948                 if (lhs.pss != rhs.pss) {
15949                     return lhs.pss < rhs.pss ? 1 : -1;
15950                 }
15951                 return 0;
15952             }
15953         });
15954
15955         StringBuilder tag = new StringBuilder(128);
15956         StringBuilder stack = new StringBuilder(128);
15957         tag.append("Low on memory -- ");
15958         appendMemBucket(tag, totalPss, "total", false);
15959         appendMemBucket(stack, totalPss, "total", true);
15960
15961         StringBuilder fullNativeBuilder = new StringBuilder(1024);
15962         StringBuilder shortNativeBuilder = new StringBuilder(1024);
15963         StringBuilder fullJavaBuilder = new StringBuilder(1024);
15964
15965         boolean firstLine = true;
15966         int lastOomAdj = Integer.MIN_VALUE;
15967         long extraNativeRam = 0;
15968         long extraNativeMemtrack = 0;
15969         long cachedPss = 0;
15970         for (int i=0, N=memInfos.size(); i<N; i++) {
15971             ProcessMemInfo mi = memInfos.get(i);
15972
15973             if (mi.oomAdj >= ProcessList.CACHED_APP_MIN_ADJ) {
15974                 cachedPss += mi.pss;
15975             }
15976
15977             if (mi.oomAdj != ProcessList.NATIVE_ADJ
15978                     && (mi.oomAdj < ProcessList.SERVICE_ADJ
15979                             || mi.oomAdj == ProcessList.HOME_APP_ADJ
15980                             || mi.oomAdj == ProcessList.PREVIOUS_APP_ADJ)) {
15981                 if (lastOomAdj != mi.oomAdj) {
15982                     lastOomAdj = mi.oomAdj;
15983                     if (mi.oomAdj <= ProcessList.FOREGROUND_APP_ADJ) {
15984                         tag.append(" / ");
15985                     }
15986                     if (mi.oomAdj >= ProcessList.FOREGROUND_APP_ADJ) {
15987                         if (firstLine) {
15988                             stack.append(":");
15989                             firstLine = false;
15990                         }
15991                         stack.append("\n\t at ");
15992                     } else {
15993                         stack.append("$");
15994                     }
15995                 } else {
15996                     tag.append(" ");
15997                     stack.append("$");
15998                 }
15999                 if (mi.oomAdj <= ProcessList.FOREGROUND_APP_ADJ) {
16000                     appendMemBucket(tag, mi.pss, mi.name, false);
16001                 }
16002                 appendMemBucket(stack, mi.pss, mi.name, true);
16003                 if (mi.oomAdj >= ProcessList.FOREGROUND_APP_ADJ
16004                         && ((i+1) >= N || memInfos.get(i+1).oomAdj != lastOomAdj)) {
16005                     stack.append("(");
16006                     for (int k=0; k<DUMP_MEM_OOM_ADJ.length; k++) {
16007                         if (DUMP_MEM_OOM_ADJ[k] == mi.oomAdj) {
16008                             stack.append(DUMP_MEM_OOM_LABEL[k]);
16009                             stack.append(":");
16010                             stack.append(DUMP_MEM_OOM_ADJ[k]);
16011                         }
16012                     }
16013                     stack.append(")");
16014                 }
16015             }
16016
16017             appendMemInfo(fullNativeBuilder, mi);
16018             if (mi.oomAdj == ProcessList.NATIVE_ADJ) {
16019                 // The short form only has native processes that are >= 512K.
16020                 if (mi.pss >= 512) {
16021                     appendMemInfo(shortNativeBuilder, mi);
16022                 } else {
16023                     extraNativeRam += mi.pss;
16024                     extraNativeMemtrack += mi.memtrack;
16025                 }
16026             } else {
16027                 // Short form has all other details, but if we have collected RAM
16028                 // from smaller native processes let's dump a summary of that.
16029                 if (extraNativeRam > 0) {
16030                     appendBasicMemEntry(shortNativeBuilder, ProcessList.NATIVE_ADJ,
16031                             -1, extraNativeRam, extraNativeMemtrack, "(Other native)");
16032                     shortNativeBuilder.append('\n');
16033                     extraNativeRam = 0;
16034                 }
16035                 appendMemInfo(fullJavaBuilder, mi);
16036             }
16037         }
16038
16039         fullJavaBuilder.append("           ");
16040         ProcessList.appendRamKb(fullJavaBuilder, totalPss);
16041         fullJavaBuilder.append(": TOTAL");
16042         if (totalMemtrack > 0) {
16043             fullJavaBuilder.append(" (");
16044             fullJavaBuilder.append(stringifyKBSize(totalMemtrack));
16045             fullJavaBuilder.append(" memtrack)");
16046         } else {
16047         }
16048         fullJavaBuilder.append("\n");
16049
16050         MemInfoReader memInfo = new MemInfoReader();
16051         memInfo.readMemInfo();
16052         final long[] infos = memInfo.getRawInfo();
16053
16054         StringBuilder memInfoBuilder = new StringBuilder(1024);
16055         Debug.getMemInfo(infos);
16056         memInfoBuilder.append("  MemInfo: ");
16057         memInfoBuilder.append(stringifyKBSize(infos[Debug.MEMINFO_SLAB])).append(" slab, ");
16058         memInfoBuilder.append(stringifyKBSize(infos[Debug.MEMINFO_SHMEM])).append(" shmem, ");
16059         memInfoBuilder.append(stringifyKBSize(
16060                                   infos[Debug.MEMINFO_VM_ALLOC_USED])).append(" vm alloc, ");
16061         memInfoBuilder.append(stringifyKBSize(
16062                                   infos[Debug.MEMINFO_PAGE_TABLES])).append(" page tables ");
16063         memInfoBuilder.append(stringifyKBSize(
16064                                   infos[Debug.MEMINFO_KERNEL_STACK])).append(" kernel stack\n");
16065         memInfoBuilder.append("           ");
16066         memInfoBuilder.append(stringifyKBSize(infos[Debug.MEMINFO_BUFFERS])).append(" buffers, ");
16067         memInfoBuilder.append(stringifyKBSize(infos[Debug.MEMINFO_CACHED])).append(" cached, ");
16068         memInfoBuilder.append(stringifyKBSize(infos[Debug.MEMINFO_MAPPED])).append(" mapped, ");
16069         memInfoBuilder.append(stringifyKBSize(infos[Debug.MEMINFO_FREE])).append(" free\n");
16070         if (infos[Debug.MEMINFO_ZRAM_TOTAL] != 0) {
16071             memInfoBuilder.append("  ZRAM: ");
16072             memInfoBuilder.append(stringifyKBSize(infos[Debug.MEMINFO_ZRAM_TOTAL]));
16073             memInfoBuilder.append(" RAM, ");
16074             memInfoBuilder.append(stringifyKBSize(infos[Debug.MEMINFO_SWAP_TOTAL]));
16075             memInfoBuilder.append(" swap total, ");
16076             memInfoBuilder.append(stringifyKBSize(infos[Debug.MEMINFO_SWAP_FREE]));
16077             memInfoBuilder.append(" swap free\n");
16078         }
16079         final long[] ksm = getKsmInfo();
16080         if (ksm[KSM_SHARING] != 0 || ksm[KSM_SHARED] != 0 || ksm[KSM_UNSHARED] != 0
16081                 || ksm[KSM_VOLATILE] != 0) {
16082             memInfoBuilder.append("  KSM: ");
16083             memInfoBuilder.append(stringifyKBSize(ksm[KSM_SHARING]));
16084             memInfoBuilder.append(" saved from shared ");
16085             memInfoBuilder.append(stringifyKBSize(ksm[KSM_SHARED]));
16086             memInfoBuilder.append("\n       ");
16087             memInfoBuilder.append(stringifyKBSize(ksm[KSM_UNSHARED]));
16088             memInfoBuilder.append(" unshared; ");
16089             memInfoBuilder.append(stringifyKBSize(ksm[KSM_VOLATILE]));
16090             memInfoBuilder.append(" volatile\n");
16091         }
16092         memInfoBuilder.append("  Free RAM: ");
16093         memInfoBuilder.append(stringifyKBSize(cachedPss + memInfo.getCachedSizeKb()
16094                 + memInfo.getFreeSizeKb()));
16095         memInfoBuilder.append("\n");
16096         memInfoBuilder.append("  Used RAM: ");
16097         memInfoBuilder.append(stringifyKBSize(
16098                                   totalPss - cachedPss + memInfo.getKernelUsedSizeKb()));
16099         memInfoBuilder.append("\n");
16100         memInfoBuilder.append("  Lost RAM: ");
16101         memInfoBuilder.append(stringifyKBSize(memInfo.getTotalSizeKb()
16102                 - totalPss - memInfo.getFreeSizeKb() - memInfo.getCachedSizeKb()
16103                 - memInfo.getKernelUsedSizeKb() - memInfo.getZramTotalSizeKb()));
16104         memInfoBuilder.append("\n");
16105         Slog.i(TAG, "Low on memory:");
16106         Slog.i(TAG, shortNativeBuilder.toString());
16107         Slog.i(TAG, fullJavaBuilder.toString());
16108         Slog.i(TAG, memInfoBuilder.toString());
16109
16110         StringBuilder dropBuilder = new StringBuilder(1024);
16111         /*
16112         StringWriter oomSw = new StringWriter();
16113         PrintWriter oomPw = new FastPrintWriter(oomSw, false, 256);
16114         StringWriter catSw = new StringWriter();
16115         PrintWriter catPw = new FastPrintWriter(catSw, false, 256);
16116         String[] emptyArgs = new String[] { };
16117         dumpApplicationMemoryUsage(null, oomPw, "  ", emptyArgs, true, catPw);
16118         oomPw.flush();
16119         String oomString = oomSw.toString();
16120         */
16121         dropBuilder.append("Low on memory:");
16122         dropBuilder.append(stack);
16123         dropBuilder.append('\n');
16124         dropBuilder.append(fullNativeBuilder);
16125         dropBuilder.append(fullJavaBuilder);
16126         dropBuilder.append('\n');
16127         dropBuilder.append(memInfoBuilder);
16128         dropBuilder.append('\n');
16129         /*
16130         dropBuilder.append(oomString);
16131         dropBuilder.append('\n');
16132         */
16133         StringWriter catSw = new StringWriter();
16134         synchronized (ActivityManagerService.this) {
16135             PrintWriter catPw = new FastPrintWriter(catSw, false, 256);
16136             String[] emptyArgs = new String[] { };
16137             catPw.println();
16138             dumpProcessesLocked(null, catPw, emptyArgs, 0, false, null);
16139             catPw.println();
16140             mServices.dumpServicesLocked(null, catPw, emptyArgs, 0,
16141                     false, false, null);
16142             catPw.println();
16143             dumpActivitiesLocked(null, catPw, emptyArgs, 0, false, false, null);
16144             catPw.flush();
16145         }
16146         dropBuilder.append(catSw.toString());
16147         addErrorToDropBox("lowmem", null, "system_server", null,
16148                 null, tag.toString(), dropBuilder.toString(), null, null);
16149         //Slog.i(TAG, "Sent to dropbox:");
16150         //Slog.i(TAG, dropBuilder.toString());
16151         synchronized (ActivityManagerService.this) {
16152             long now = SystemClock.uptimeMillis();
16153             if (mLastMemUsageReportTime < now) {
16154                 mLastMemUsageReportTime = now;
16155             }
16156         }
16157     }
16158
16159     /**
16160      * Searches array of arguments for the specified string
16161      * @param args array of argument strings
16162      * @param value value to search for
16163      * @return true if the value is contained in the array
16164      */
16165     private static boolean scanArgs(String[] args, String value) {
16166         if (args != null) {
16167             for (String arg : args) {
16168                 if (value.equals(arg)) {
16169                     return true;
16170                 }
16171             }
16172         }
16173         return false;
16174     }
16175
16176     private final boolean removeDyingProviderLocked(ProcessRecord proc,
16177             ContentProviderRecord cpr, boolean always) {
16178         final boolean inLaunching = mLaunchingProviders.contains(cpr);
16179
16180         if (!inLaunching || always) {
16181             synchronized (cpr) {
16182                 cpr.launchingApp = null;
16183                 cpr.notifyAll();
16184             }
16185             mProviderMap.removeProviderByClass(cpr.name, UserHandle.getUserId(cpr.uid));
16186             String names[] = cpr.info.authority.split(";");
16187             for (int j = 0; j < names.length; j++) {
16188                 mProviderMap.removeProviderByName(names[j], UserHandle.getUserId(cpr.uid));
16189             }
16190         }
16191
16192         for (int i = cpr.connections.size() - 1; i >= 0; i--) {
16193             ContentProviderConnection conn = cpr.connections.get(i);
16194             if (conn.waiting) {
16195                 // If this connection is waiting for the provider, then we don't
16196                 // need to mess with its process unless we are always removing
16197                 // or for some reason the provider is not currently launching.
16198                 if (inLaunching && !always) {
16199                     continue;
16200                 }
16201             }
16202             ProcessRecord capp = conn.client;
16203             conn.dead = true;
16204             if (conn.stableCount > 0) {
16205                 if (!capp.persistent && capp.thread != null
16206                         && capp.pid != 0
16207                         && capp.pid != MY_PID) {
16208                     capp.kill("depends on provider "
16209                             + cpr.name.flattenToShortString()
16210                             + " in dying proc " + (proc != null ? proc.processName : "??"), true);
16211                 }
16212             } else if (capp.thread != null && conn.provider.provider != null) {
16213                 try {
16214                     capp.thread.unstableProviderDied(conn.provider.provider.asBinder());
16215                 } catch (RemoteException e) {
16216                 }
16217                 // In the protocol here, we don't expect the client to correctly
16218                 // clean up this connection, we'll just remove it.
16219                 cpr.connections.remove(i);
16220                 if (conn.client.conProviders.remove(conn)) {
16221                     stopAssociationLocked(capp.uid, capp.processName, cpr.uid, cpr.name);
16222                 }
16223             }
16224         }
16225
16226         if (inLaunching && always) {
16227             mLaunchingProviders.remove(cpr);
16228         }
16229         return inLaunching;
16230     }
16231
16232     /**
16233      * Main code for cleaning up a process when it has gone away.  This is
16234      * called both as a result of the process dying, or directly when stopping
16235      * a process when running in single process mode.
16236      *
16237      * @return Returns true if the given process has been restarted, so the
16238      * app that was passed in must remain on the process lists.
16239      */
16240     private final boolean cleanUpApplicationRecordLocked(ProcessRecord app,
16241             boolean restarting, boolean allowRestart, int index) {
16242         if (index >= 0) {
16243             removeLruProcessLocked(app);
16244             ProcessList.remove(app.pid);
16245         }
16246
16247         mProcessesToGc.remove(app);
16248         mPendingPssProcesses.remove(app);
16249
16250         // Dismiss any open dialogs.
16251         if (app.crashDialog != null && !app.forceCrashReport) {
16252             app.crashDialog.dismiss();
16253             app.crashDialog = null;
16254         }
16255         if (app.anrDialog != null) {
16256             app.anrDialog.dismiss();
16257             app.anrDialog = null;
16258         }
16259         if (app.waitDialog != null) {
16260             app.waitDialog.dismiss();
16261             app.waitDialog = null;
16262         }
16263
16264         app.crashing = false;
16265         app.notResponding = false;
16266
16267         app.resetPackageList(mProcessStats);
16268         app.unlinkDeathRecipient();
16269         app.makeInactive(mProcessStats);
16270         app.waitingToKill = null;
16271         app.forcingToForeground = null;
16272         updateProcessForegroundLocked(app, false, false);
16273         app.foregroundActivities = false;
16274         app.hasShownUi = false;
16275         app.treatLikeActivity = false;
16276         app.hasAboveClient = false;
16277         app.hasClientActivities = false;
16278
16279         mServices.killServicesLocked(app, allowRestart);
16280
16281         boolean restart = false;
16282
16283         // Remove published content providers.
16284         for (int i = app.pubProviders.size() - 1; i >= 0; i--) {
16285             ContentProviderRecord cpr = app.pubProviders.valueAt(i);
16286             final boolean always = app.bad || !allowRestart;
16287             boolean inLaunching = removeDyingProviderLocked(app, cpr, always);
16288             if ((inLaunching || always) && cpr.hasConnectionOrHandle()) {
16289                 // We left the provider in the launching list, need to
16290                 // restart it.
16291                 restart = true;
16292             }
16293
16294             cpr.provider = null;
16295             cpr.proc = null;
16296         }
16297         app.pubProviders.clear();
16298
16299         // Take care of any launching providers waiting for this process.
16300         if (cleanupAppInLaunchingProvidersLocked(app, false)) {
16301             restart = true;
16302         }
16303
16304         // Unregister from connected content providers.
16305         if (!app.conProviders.isEmpty()) {
16306             for (int i = app.conProviders.size() - 1; i >= 0; i--) {
16307                 ContentProviderConnection conn = app.conProviders.get(i);
16308                 conn.provider.connections.remove(conn);
16309                 stopAssociationLocked(app.uid, app.processName, conn.provider.uid,
16310                         conn.provider.name);
16311             }
16312             app.conProviders.clear();
16313         }
16314
16315         // At this point there may be remaining entries in mLaunchingProviders
16316         // where we were the only one waiting, so they are no longer of use.
16317         // Look for these and clean up if found.
16318         // XXX Commented out for now.  Trying to figure out a way to reproduce
16319         // the actual situation to identify what is actually going on.
16320         if (false) {
16321             for (int i = mLaunchingProviders.size() - 1; i >= 0; i--) {
16322                 ContentProviderRecord cpr = mLaunchingProviders.get(i);
16323                 if (cpr.connections.size() <= 0 && !cpr.hasExternalProcessHandles()) {
16324                     synchronized (cpr) {
16325                         cpr.launchingApp = null;
16326                         cpr.notifyAll();
16327                     }
16328                 }
16329             }
16330         }
16331
16332         skipCurrentReceiverLocked(app);
16333
16334         // Unregister any receivers.
16335         for (int i = app.receivers.size() - 1; i >= 0; i--) {
16336             removeReceiverLocked(app.receivers.valueAt(i));
16337         }
16338         app.receivers.clear();
16339
16340         // If the app is undergoing backup, tell the backup manager about it
16341         if (mBackupTarget != null && app.pid == mBackupTarget.app.pid) {
16342             if (DEBUG_BACKUP || DEBUG_CLEANUP) Slog.d(TAG_CLEANUP, "App "
16343                     + mBackupTarget.appInfo + " died during backup");
16344             try {
16345                 IBackupManager bm = IBackupManager.Stub.asInterface(
16346                         ServiceManager.getService(Context.BACKUP_SERVICE));
16347                 bm.agentDisconnected(app.info.packageName);
16348             } catch (RemoteException e) {
16349                 // can't happen; backup manager is local
16350             }
16351         }
16352
16353         for (int i = mPendingProcessChanges.size() - 1; i >= 0; i--) {
16354             ProcessChangeItem item = mPendingProcessChanges.get(i);
16355             if (item.pid == app.pid) {
16356                 mPendingProcessChanges.remove(i);
16357                 mAvailProcessChanges.add(item);
16358             }
16359         }
16360         mUiHandler.obtainMessage(DISPATCH_PROCESS_DIED_UI_MSG, app.pid, app.info.uid,
16361                 null).sendToTarget();
16362
16363         // If the caller is restarting this app, then leave it in its
16364         // current lists and let the caller take care of it.
16365         if (restarting) {
16366             return false;
16367         }
16368
16369         if (!app.persistent || app.isolated) {
16370             if (DEBUG_PROCESSES || DEBUG_CLEANUP) Slog.v(TAG_CLEANUP,
16371                     "Removing non-persistent process during cleanup: " + app);
16372             removeProcessNameLocked(app.processName, app.uid);
16373             if (mHeavyWeightProcess == app) {
16374                 mHandler.sendMessage(mHandler.obtainMessage(CANCEL_HEAVY_NOTIFICATION_MSG,
16375                         mHeavyWeightProcess.userId, 0));
16376                 mHeavyWeightProcess = null;
16377             }
16378         } else if (!app.removed) {
16379             // This app is persistent, so we need to keep its record around.
16380             // If it is not already on the pending app list, add it there
16381             // and start a new process for it.
16382             if (mPersistentStartingProcesses.indexOf(app) < 0) {
16383                 mPersistentStartingProcesses.add(app);
16384                 restart = true;
16385             }
16386         }
16387         if ((DEBUG_PROCESSES || DEBUG_CLEANUP) && mProcessesOnHold.contains(app)) Slog.v(
16388                 TAG_CLEANUP, "Clean-up removing on hold: " + app);
16389         mProcessesOnHold.remove(app);
16390
16391         if (app == mHomeProcess) {
16392             mHomeProcess = null;
16393         }
16394         if (app == mPreviousProcess) {
16395             mPreviousProcess = null;
16396         }
16397
16398         if (restart && !app.isolated) {
16399             // We have components that still need to be running in the
16400             // process, so re-launch it.
16401             if (index < 0) {
16402                 ProcessList.remove(app.pid);
16403             }
16404             addProcessNameLocked(app);
16405             startProcessLocked(app, "restart", app.processName);
16406             return true;
16407         } else if (app.pid > 0 && app.pid != MY_PID) {
16408             // Goodbye!
16409             boolean removed;
16410             synchronized (mPidsSelfLocked) {
16411                 mPidsSelfLocked.remove(app.pid);
16412                 mHandler.removeMessages(PROC_START_TIMEOUT_MSG, app);
16413             }
16414             mBatteryStatsService.noteProcessFinish(app.processName, app.info.uid);
16415             if (app.isolated) {
16416                 mBatteryStatsService.removeIsolatedUid(app.uid, app.info.uid);
16417             }
16418             app.setPid(0);
16419         }
16420         return false;
16421     }
16422
16423     boolean checkAppInLaunchingProvidersLocked(ProcessRecord app) {
16424         for (int i = mLaunchingProviders.size() - 1; i >= 0; i--) {
16425             ContentProviderRecord cpr = mLaunchingProviders.get(i);
16426             if (cpr.launchingApp == app) {
16427                 return true;
16428             }
16429         }
16430         return false;
16431     }
16432
16433     boolean cleanupAppInLaunchingProvidersLocked(ProcessRecord app, boolean alwaysBad) {
16434         // Look through the content providers we are waiting to have launched,
16435         // and if any run in this process then either schedule a restart of
16436         // the process or kill the client waiting for it if this process has
16437         // gone bad.
16438         boolean restart = false;
16439         for (int i = mLaunchingProviders.size() - 1; i >= 0; i--) {
16440             ContentProviderRecord cpr = mLaunchingProviders.get(i);
16441             if (cpr.launchingApp == app) {
16442                 if (!alwaysBad && !app.bad && cpr.hasConnectionOrHandle()) {
16443                     restart = true;
16444                 } else {
16445                     removeDyingProviderLocked(app, cpr, true);
16446                 }
16447             }
16448         }
16449         return restart;
16450     }
16451
16452     // =========================================================
16453     // SERVICES
16454     // =========================================================
16455
16456     @Override
16457     public List<ActivityManager.RunningServiceInfo> getServices(int maxNum,
16458             int flags) {
16459         enforceNotIsolatedCaller("getServices");
16460         synchronized (this) {
16461             return mServices.getRunningServiceInfoLocked(maxNum, flags);
16462         }
16463     }
16464
16465     @Override
16466     public PendingIntent getRunningServiceControlPanel(ComponentName name) {
16467         enforceNotIsolatedCaller("getRunningServiceControlPanel");
16468         synchronized (this) {
16469             return mServices.getRunningServiceControlPanelLocked(name);
16470         }
16471     }
16472
16473     @Override
16474     public ComponentName startService(IApplicationThread caller, Intent service,
16475             String resolvedType, String callingPackage, int userId)
16476             throws TransactionTooLargeException {
16477         enforceNotIsolatedCaller("startService");
16478         // Refuse possible leaked file descriptors
16479         if (service != null && service.hasFileDescriptors() == true) {
16480             throw new IllegalArgumentException("File descriptors passed in Intent");
16481         }
16482
16483         if (callingPackage == null) {
16484             throw new IllegalArgumentException("callingPackage cannot be null");
16485         }
16486
16487         if (DEBUG_SERVICE) Slog.v(TAG_SERVICE,
16488                 "startService: " + service + " type=" + resolvedType);
16489         synchronized(this) {
16490             final int callingPid = Binder.getCallingPid();
16491             final int callingUid = Binder.getCallingUid();
16492             final long origId = Binder.clearCallingIdentity();
16493             ComponentName res = mServices.startServiceLocked(caller, service,
16494                     resolvedType, callingPid, callingUid, callingPackage, userId);
16495             Binder.restoreCallingIdentity(origId);
16496             return res;
16497         }
16498     }
16499
16500     ComponentName startServiceInPackage(int uid, Intent service, String resolvedType,
16501             String callingPackage, int userId)
16502             throws TransactionTooLargeException {
16503         synchronized(this) {
16504             if (DEBUG_SERVICE) Slog.v(TAG_SERVICE,
16505                     "startServiceInPackage: " + service + " type=" + resolvedType);
16506             final long origId = Binder.clearCallingIdentity();
16507             ComponentName res = mServices.startServiceLocked(null, service,
16508                     resolvedType, -1, uid, callingPackage, userId);
16509             Binder.restoreCallingIdentity(origId);
16510             return res;
16511         }
16512     }
16513
16514     @Override
16515     public int stopService(IApplicationThread caller, Intent service,
16516             String resolvedType, int userId) {
16517         enforceNotIsolatedCaller("stopService");
16518         // Refuse possible leaked file descriptors
16519         if (service != null && service.hasFileDescriptors() == true) {
16520             throw new IllegalArgumentException("File descriptors passed in Intent");
16521         }
16522
16523         synchronized(this) {
16524             return mServices.stopServiceLocked(caller, service, resolvedType, userId);
16525         }
16526     }
16527
16528     @Override
16529     public IBinder peekService(Intent service, String resolvedType, String callingPackage) {
16530         enforceNotIsolatedCaller("peekService");
16531         // Refuse possible leaked file descriptors
16532         if (service != null && service.hasFileDescriptors() == true) {
16533             throw new IllegalArgumentException("File descriptors passed in Intent");
16534         }
16535
16536         if (callingPackage == null) {
16537             throw new IllegalArgumentException("callingPackage cannot be null");
16538         }
16539
16540         synchronized(this) {
16541             return mServices.peekServiceLocked(service, resolvedType, callingPackage);
16542         }
16543     }
16544
16545     @Override
16546     public boolean stopServiceToken(ComponentName className, IBinder token,
16547             int startId) {
16548         synchronized(this) {
16549             return mServices.stopServiceTokenLocked(className, token, startId);
16550         }
16551     }
16552
16553     @Override
16554     public void setServiceForeground(ComponentName className, IBinder token,
16555             int id, Notification notification, boolean removeNotification) {
16556         synchronized(this) {
16557             mServices.setServiceForegroundLocked(className, token, id, notification,
16558                     removeNotification);
16559         }
16560     }
16561
16562     @Override
16563     public int handleIncomingUser(int callingPid, int callingUid, int userId, boolean allowAll,
16564             boolean requireFull, String name, String callerPackage) {
16565         return mUserController.handleIncomingUser(callingPid, callingUid, userId, allowAll,
16566                 requireFull ? ALLOW_FULL_ONLY : ALLOW_NON_FULL, name, callerPackage);
16567     }
16568
16569     boolean isSingleton(String componentProcessName, ApplicationInfo aInfo,
16570             String className, int flags) {
16571         boolean result = false;
16572         // For apps that don't have pre-defined UIDs, check for permission
16573         if (UserHandle.getAppId(aInfo.uid) >= Process.FIRST_APPLICATION_UID) {
16574             if ((flags & ServiceInfo.FLAG_SINGLE_USER) != 0) {
16575                 if (ActivityManager.checkUidPermission(
16576                         INTERACT_ACROSS_USERS,
16577                         aInfo.uid) != PackageManager.PERMISSION_GRANTED) {
16578                     ComponentName comp = new ComponentName(aInfo.packageName, className);
16579                     String msg = "Permission Denial: Component " + comp.flattenToShortString()
16580                             + " requests FLAG_SINGLE_USER, but app does not hold "
16581                             + INTERACT_ACROSS_USERS;
16582                     Slog.w(TAG, msg);
16583                     throw new SecurityException(msg);
16584                 }
16585                 // Permission passed
16586                 result = true;
16587             }
16588         } else if ("system".equals(componentProcessName)) {
16589             result = true;
16590         } else if ((flags & ServiceInfo.FLAG_SINGLE_USER) != 0) {
16591             // Phone app and persistent apps are allowed to export singleuser providers.
16592             result = UserHandle.isSameApp(aInfo.uid, Process.PHONE_UID)
16593                     || (aInfo.flags & ApplicationInfo.FLAG_PERSISTENT) != 0;
16594         }
16595         if (DEBUG_MU) Slog.v(TAG_MU,
16596                 "isSingleton(" + componentProcessName + ", " + aInfo + ", " + className + ", 0x"
16597                 + Integer.toHexString(flags) + ") = " + result);
16598         return result;
16599     }
16600
16601     /**
16602      * Checks to see if the caller is in the same app as the singleton
16603      * component, or the component is in a special app. It allows special apps
16604      * to export singleton components but prevents exporting singleton
16605      * components for regular apps.
16606      */
16607     boolean isValidSingletonCall(int callingUid, int componentUid) {
16608         int componentAppId = UserHandle.getAppId(componentUid);
16609         return UserHandle.isSameApp(callingUid, componentUid)
16610                 || componentAppId == Process.SYSTEM_UID
16611                 || componentAppId == Process.PHONE_UID
16612                 || ActivityManager.checkUidPermission(INTERACT_ACROSS_USERS_FULL, componentUid)
16613                         == PackageManager.PERMISSION_GRANTED;
16614     }
16615
16616     public int bindService(IApplicationThread caller, IBinder token, Intent service,
16617             String resolvedType, IServiceConnection connection, int flags, String callingPackage,
16618             int userId) throws TransactionTooLargeException {
16619         enforceNotIsolatedCaller("bindService");
16620
16621         // Refuse possible leaked file descriptors
16622         if (service != null && service.hasFileDescriptors() == true) {
16623             throw new IllegalArgumentException("File descriptors passed in Intent");
16624         }
16625
16626         if (callingPackage == null) {
16627             throw new IllegalArgumentException("callingPackage cannot be null");
16628         }
16629
16630         synchronized(this) {
16631             return mServices.bindServiceLocked(caller, token, service,
16632                     resolvedType, connection, flags, callingPackage, userId);
16633         }
16634     }
16635
16636     public boolean unbindService(IServiceConnection connection) {
16637         synchronized (this) {
16638             return mServices.unbindServiceLocked(connection);
16639         }
16640     }
16641
16642     public void publishService(IBinder token, Intent intent, IBinder service) {
16643         // Refuse possible leaked file descriptors
16644         if (intent != null && intent.hasFileDescriptors() == true) {
16645             throw new IllegalArgumentException("File descriptors passed in Intent");
16646         }
16647
16648         synchronized(this) {
16649             if (!(token instanceof ServiceRecord)) {
16650                 throw new IllegalArgumentException("Invalid service token");
16651             }
16652             mServices.publishServiceLocked((ServiceRecord)token, intent, service);
16653         }
16654     }
16655
16656     public void unbindFinished(IBinder token, Intent intent, boolean doRebind) {
16657         // Refuse possible leaked file descriptors
16658         if (intent != null && intent.hasFileDescriptors() == true) {
16659             throw new IllegalArgumentException("File descriptors passed in Intent");
16660         }
16661
16662         synchronized(this) {
16663             mServices.unbindFinishedLocked((ServiceRecord)token, intent, doRebind);
16664         }
16665     }
16666
16667     public void serviceDoneExecuting(IBinder token, int type, int startId, int res) {
16668         synchronized(this) {
16669             if (!(token instanceof ServiceRecord)) {
16670                 Slog.e(TAG, "serviceDoneExecuting: Invalid service token=" + token);
16671                 throw new IllegalArgumentException("Invalid service token");
16672             }
16673             mServices.serviceDoneExecutingLocked((ServiceRecord)token, type, startId, res);
16674         }
16675     }
16676
16677     // =========================================================
16678     // BACKUP AND RESTORE
16679     // =========================================================
16680
16681     // Cause the target app to be launched if necessary and its backup agent
16682     // instantiated.  The backup agent will invoke backupAgentCreated() on the
16683     // activity manager to announce its creation.
16684     public boolean bindBackupAgent(ApplicationInfo app, int backupMode) {
16685         if (DEBUG_BACKUP) Slog.v(TAG_BACKUP,
16686                 "bindBackupAgent: app=" + app + " mode=" + backupMode);
16687         enforceCallingPermission("android.permission.CONFIRM_FULL_BACKUP", "bindBackupAgent");
16688
16689         synchronized(this) {
16690             // !!! TODO: currently no check here that we're already bound
16691             BatteryStatsImpl.Uid.Pkg.Serv ss = null;
16692             BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
16693             synchronized (stats) {
16694                 ss = stats.getServiceStatsLocked(app.uid, app.packageName, app.name);
16695             }
16696
16697             // Backup agent is now in use, its package can't be stopped.
16698             try {
16699                 AppGlobals.getPackageManager().setPackageStoppedState(
16700                         app.packageName, false, UserHandle.getUserId(app.uid));
16701             } catch (RemoteException e) {
16702             } catch (IllegalArgumentException e) {
16703                 Slog.w(TAG, "Failed trying to unstop package "
16704                         + app.packageName + ": " + e);
16705             }
16706
16707             BackupRecord r = new BackupRecord(ss, app, backupMode);
16708             ComponentName hostingName = (backupMode == IApplicationThread.BACKUP_MODE_INCREMENTAL)
16709                     ? new ComponentName(app.packageName, app.backupAgentName)
16710                     : new ComponentName("android", "FullBackupAgent");
16711             // startProcessLocked() returns existing proc's record if it's already running
16712             ProcessRecord proc = startProcessLocked(app.processName, app,
16713                     false, 0, "backup", hostingName, false, false, false);
16714             if (proc == null) {
16715                 Slog.e(TAG, "Unable to start backup agent process " + r);
16716                 return false;
16717             }
16718
16719             r.app = proc;
16720             mBackupTarget = r;
16721             mBackupAppName = app.packageName;
16722
16723             // Try not to kill the process during backup
16724             updateOomAdjLocked(proc);
16725
16726             // If the process is already attached, schedule the creation of the backup agent now.
16727             // If it is not yet live, this will be done when it attaches to the framework.
16728             if (proc.thread != null) {
16729                 if (DEBUG_BACKUP) Slog.v(TAG_BACKUP, "Agent proc already running: " + proc);
16730                 try {
16731                     proc.thread.scheduleCreateBackupAgent(app,
16732                             compatibilityInfoForPackageLocked(app), backupMode);
16733                 } catch (RemoteException e) {
16734                     // Will time out on the backup manager side
16735                 }
16736             } else {
16737                 if (DEBUG_BACKUP) Slog.v(TAG_BACKUP, "Agent proc not running, waiting for attach");
16738             }
16739             // Invariants: at this point, the target app process exists and the application
16740             // is either already running or in the process of coming up.  mBackupTarget and
16741             // mBackupAppName describe the app, so that when it binds back to the AM we
16742             // know that it's scheduled for a backup-agent operation.
16743         }
16744
16745         return true;
16746     }
16747
16748     @Override
16749     public void clearPendingBackup() {
16750         if (DEBUG_BACKUP) Slog.v(TAG_BACKUP, "clearPendingBackup");
16751         enforceCallingPermission("android.permission.BACKUP", "clearPendingBackup");
16752
16753         synchronized (this) {
16754             mBackupTarget = null;
16755             mBackupAppName = null;
16756         }
16757     }
16758
16759     // A backup agent has just come up
16760     public void backupAgentCreated(String agentPackageName, IBinder agent) {
16761         if (DEBUG_BACKUP) Slog.v(TAG_BACKUP, "backupAgentCreated: " + agentPackageName
16762                 + " = " + agent);
16763
16764         synchronized(this) {
16765             if (!agentPackageName.equals(mBackupAppName)) {
16766                 Slog.e(TAG, "Backup agent created for " + agentPackageName + " but not requested!");
16767                 return;
16768             }
16769         }
16770
16771         long oldIdent = Binder.clearCallingIdentity();
16772         try {
16773             IBackupManager bm = IBackupManager.Stub.asInterface(
16774                     ServiceManager.getService(Context.BACKUP_SERVICE));
16775             bm.agentConnected(agentPackageName, agent);
16776         } catch (RemoteException e) {
16777             // can't happen; the backup manager service is local
16778         } catch (Exception e) {
16779             Slog.w(TAG, "Exception trying to deliver BackupAgent binding: ");
16780             e.printStackTrace();
16781         } finally {
16782             Binder.restoreCallingIdentity(oldIdent);
16783         }
16784     }
16785
16786     // done with this agent
16787     public void unbindBackupAgent(ApplicationInfo appInfo) {
16788         if (DEBUG_BACKUP) Slog.v(TAG_BACKUP, "unbindBackupAgent: " + appInfo);
16789         if (appInfo == null) {
16790             Slog.w(TAG, "unbind backup agent for null app");
16791             return;
16792         }
16793
16794         synchronized(this) {
16795             try {
16796                 if (mBackupAppName == null) {
16797                     Slog.w(TAG, "Unbinding backup agent with no active backup");
16798                     return;
16799                 }
16800
16801                 if (!mBackupAppName.equals(appInfo.packageName)) {
16802                     Slog.e(TAG, "Unbind of " + appInfo + " but is not the current backup target");
16803                     return;
16804                 }
16805
16806                 // Not backing this app up any more; reset its OOM adjustment
16807                 final ProcessRecord proc = mBackupTarget.app;
16808                 updateOomAdjLocked(proc);
16809
16810                 // If the app crashed during backup, 'thread' will be null here
16811                 if (proc.thread != null) {
16812                     try {
16813                         proc.thread.scheduleDestroyBackupAgent(appInfo,
16814                                 compatibilityInfoForPackageLocked(appInfo));
16815                     } catch (Exception e) {
16816                         Slog.e(TAG, "Exception when unbinding backup agent:");
16817                         e.printStackTrace();
16818                     }
16819                 }
16820             } finally {
16821                 mBackupTarget = null;
16822                 mBackupAppName = null;
16823             }
16824         }
16825     }
16826     // =========================================================
16827     // BROADCASTS
16828     // =========================================================
16829
16830     boolean isPendingBroadcastProcessLocked(int pid) {
16831         return mFgBroadcastQueue.isPendingBroadcastProcessLocked(pid)
16832                 || mBgBroadcastQueue.isPendingBroadcastProcessLocked(pid);
16833     }
16834
16835     void skipPendingBroadcastLocked(int pid) {
16836             Slog.w(TAG, "Unattached app died before broadcast acknowledged, skipping");
16837             for (BroadcastQueue queue : mBroadcastQueues) {
16838                 queue.skipPendingBroadcastLocked(pid);
16839             }
16840     }
16841
16842     // The app just attached; send any pending broadcasts that it should receive
16843     boolean sendPendingBroadcastsLocked(ProcessRecord app) {
16844         boolean didSomething = false;
16845         for (BroadcastQueue queue : mBroadcastQueues) {
16846             didSomething |= queue.sendPendingBroadcastsLocked(app);
16847         }
16848         return didSomething;
16849     }
16850
16851     public Intent registerReceiver(IApplicationThread caller, String callerPackage,
16852             IIntentReceiver receiver, IntentFilter filter, String permission, int userId) {
16853         enforceNotIsolatedCaller("registerReceiver");
16854         ArrayList<Intent> stickyIntents = null;
16855         ProcessRecord callerApp = null;
16856         int callingUid;
16857         int callingPid;
16858         synchronized(this) {
16859             if (caller != null) {
16860                 callerApp = getRecordForAppLocked(caller);
16861                 if (callerApp == null) {
16862                     throw new SecurityException(
16863                             "Unable to find app for caller " + caller
16864                             + " (pid=" + Binder.getCallingPid()
16865                             + ") when registering receiver " + receiver);
16866                 }
16867                 if (callerApp.info.uid != Process.SYSTEM_UID &&
16868                         !callerApp.pkgList.containsKey(callerPackage) &&
16869                         !"android".equals(callerPackage)) {
16870                     throw new SecurityException("Given caller package " + callerPackage
16871                             + " is not running in process " + callerApp);
16872                 }
16873                 callingUid = callerApp.info.uid;
16874                 callingPid = callerApp.pid;
16875             } else {
16876                 callerPackage = null;
16877                 callingUid = Binder.getCallingUid();
16878                 callingPid = Binder.getCallingPid();
16879             }
16880
16881             userId = mUserController.handleIncomingUser(callingPid, callingUid, userId, true,
16882                     ALLOW_FULL_ONLY, "registerReceiver", callerPackage);
16883
16884             Iterator<String> actions = filter.actionsIterator();
16885             if (actions == null) {
16886                 ArrayList<String> noAction = new ArrayList<String>(1);
16887                 noAction.add(null);
16888                 actions = noAction.iterator();
16889             }
16890
16891             // Collect stickies of users
16892             int[] userIds = { UserHandle.USER_ALL, UserHandle.getUserId(callingUid) };
16893             while (actions.hasNext()) {
16894                 String action = actions.next();
16895                 for (int id : userIds) {
16896                     ArrayMap<String, ArrayList<Intent>> stickies = mStickyBroadcasts.get(id);
16897                     if (stickies != null) {
16898                         ArrayList<Intent> intents = stickies.get(action);
16899                         if (intents != null) {
16900                             if (stickyIntents == null) {
16901                                 stickyIntents = new ArrayList<Intent>();
16902                             }
16903                             stickyIntents.addAll(intents);
16904                         }
16905                     }
16906                 }
16907             }
16908         }
16909
16910         ArrayList<Intent> allSticky = null;
16911         if (stickyIntents != null) {
16912             final ContentResolver resolver = mContext.getContentResolver();
16913             // Look for any matching sticky broadcasts...
16914             for (int i = 0, N = stickyIntents.size(); i < N; i++) {
16915                 Intent intent = stickyIntents.get(i);
16916                 // If intent has scheme "content", it will need to acccess
16917                 // provider that needs to lock mProviderMap in ActivityThread
16918                 // and also it may need to wait application response, so we
16919                 // cannot lock ActivityManagerService here.
16920                 if (filter.match(resolver, intent, true, TAG) >= 0) {
16921                     if (allSticky == null) {
16922                         allSticky = new ArrayList<Intent>();
16923                     }
16924                     allSticky.add(intent);
16925                 }
16926             }
16927         }
16928
16929         // The first sticky in the list is returned directly back to the client.
16930         Intent sticky = allSticky != null ? allSticky.get(0) : null;
16931         if (DEBUG_BROADCAST) Slog.v(TAG_BROADCAST, "Register receiver " + filter + ": " + sticky);
16932         if (receiver == null) {
16933             return sticky;
16934         }
16935
16936         synchronized (this) {
16937             if (callerApp != null && (callerApp.thread == null
16938                     || callerApp.thread.asBinder() != caller.asBinder())) {
16939                 // Original caller already died
16940                 return null;
16941             }
16942             ReceiverList rl = mRegisteredReceivers.get(receiver.asBinder());
16943             if (rl == null) {
16944                 rl = new ReceiverList(this, callerApp, callingPid, callingUid,
16945                         userId, receiver);
16946                 if (rl.app != null) {
16947                     rl.app.receivers.add(rl);
16948                 } else {
16949                     try {
16950                         receiver.asBinder().linkToDeath(rl, 0);
16951                     } catch (RemoteException e) {
16952                         return sticky;
16953                     }
16954                     rl.linkedToDeath = true;
16955                 }
16956                 mRegisteredReceivers.put(receiver.asBinder(), rl);
16957             } else if (rl.uid != callingUid) {
16958                 throw new IllegalArgumentException(
16959                         "Receiver requested to register for uid " + callingUid
16960                         + " was previously registered for uid " + rl.uid);
16961             } else if (rl.pid != callingPid) {
16962                 throw new IllegalArgumentException(
16963                         "Receiver requested to register for pid " + callingPid
16964                         + " was previously registered for pid " + rl.pid);
16965             } else if (rl.userId != userId) {
16966                 throw new IllegalArgumentException(
16967                         "Receiver requested to register for user " + userId
16968                         + " was previously registered for user " + rl.userId);
16969             }
16970             BroadcastFilter bf = new BroadcastFilter(filter, rl, callerPackage,
16971                     permission, callingUid, userId);
16972             rl.add(bf);
16973             if (!bf.debugCheck()) {
16974                 Slog.w(TAG, "==> For Dynamic broadcast");
16975             }
16976             mReceiverResolver.addFilter(bf);
16977
16978             // Enqueue broadcasts for all existing stickies that match
16979             // this filter.
16980             if (allSticky != null) {
16981                 ArrayList receivers = new ArrayList();
16982                 receivers.add(bf);
16983
16984                 final int stickyCount = allSticky.size();
16985                 for (int i = 0; i < stickyCount; i++) {
16986                     Intent intent = allSticky.get(i);
16987                     BroadcastQueue queue = broadcastQueueForIntent(intent);
16988                     BroadcastRecord r = new BroadcastRecord(queue, intent, null,
16989                             null, -1, -1, null, null, AppOpsManager.OP_NONE, null, receivers,
16990                             null, 0, null, null, false, true, true, -1);
16991                     queue.enqueueParallelBroadcastLocked(r);
16992                     queue.scheduleBroadcastsLocked();
16993                 }
16994             }
16995
16996             return sticky;
16997         }
16998     }
16999
17000     public void unregisterReceiver(IIntentReceiver receiver) {
17001         if (DEBUG_BROADCAST) Slog.v(TAG_BROADCAST, "Unregister receiver: " + receiver);
17002
17003         final long origId = Binder.clearCallingIdentity();
17004         try {
17005             boolean doTrim = false;
17006
17007             synchronized(this) {
17008                 ReceiverList rl = mRegisteredReceivers.get(receiver.asBinder());
17009                 if (rl != null) {
17010                     final BroadcastRecord r = rl.curBroadcast;
17011                     if (r != null && r == r.queue.getMatchingOrderedReceiver(r)) {
17012                         final boolean doNext = r.queue.finishReceiverLocked(
17013                                 r, r.resultCode, r.resultData, r.resultExtras,
17014                                 r.resultAbort, false);
17015                         if (doNext) {
17016                             doTrim = true;
17017                             r.queue.processNextBroadcast(false);
17018                         }
17019                     }
17020
17021                     if (rl.app != null) {
17022                         rl.app.receivers.remove(rl);
17023                     }
17024                     removeReceiverLocked(rl);
17025                     if (rl.linkedToDeath) {
17026                         rl.linkedToDeath = false;
17027                         rl.receiver.asBinder().unlinkToDeath(rl, 0);
17028                     }
17029                 }
17030             }
17031
17032             // If we actually concluded any broadcasts, we might now be able
17033             // to trim the recipients' apps from our working set
17034             if (doTrim) {
17035                 trimApplications();
17036                 return;
17037             }
17038
17039         } finally {
17040             Binder.restoreCallingIdentity(origId);
17041         }
17042     }
17043
17044     void removeReceiverLocked(ReceiverList rl) {
17045         mRegisteredReceivers.remove(rl.receiver.asBinder());
17046         for (int i = rl.size() - 1; i >= 0; i--) {
17047             mReceiverResolver.removeFilter(rl.get(i));
17048         }
17049     }
17050
17051     private final void sendPackageBroadcastLocked(int cmd, String[] packages, int userId) {
17052         for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) {
17053             ProcessRecord r = mLruProcesses.get(i);
17054             if (r.thread != null && (userId == UserHandle.USER_ALL || r.userId == userId)) {
17055                 try {
17056                     r.thread.dispatchPackageBroadcast(cmd, packages);
17057                 } catch (RemoteException ex) {
17058                 }
17059             }
17060         }
17061     }
17062
17063     private List<ResolveInfo> collectReceiverComponents(Intent intent, String resolvedType,
17064             int callingUid, int[] users) {
17065         // TODO: come back and remove this assumption to triage all broadcasts
17066         int pmFlags = STOCK_PM_FLAGS | MATCH_DEBUG_TRIAGED_MISSING;
17067
17068         List<ResolveInfo> receivers = null;
17069         try {
17070             HashSet<ComponentName> singleUserReceivers = null;
17071             boolean scannedFirstReceivers = false;
17072             for (int user : users) {
17073                 // Skip users that have Shell restrictions, with exception of always permitted
17074                 // Shell broadcasts
17075                 if (callingUid == Process.SHELL_UID
17076                         && mUserController.hasUserRestriction(
17077                                 UserManager.DISALLOW_DEBUGGING_FEATURES, user)
17078                         && !isPermittedShellBroadcast(intent)) {
17079                     continue;
17080                 }
17081                 List<ResolveInfo> newReceivers = AppGlobals.getPackageManager()
17082                         .queryIntentReceivers(intent, resolvedType, pmFlags, user).getList();
17083                 if (user != UserHandle.USER_SYSTEM && newReceivers != null) {
17084                     // If this is not the system user, we need to check for
17085                     // any receivers that should be filtered out.
17086                     for (int i=0; i<newReceivers.size(); i++) {
17087                         ResolveInfo ri = newReceivers.get(i);
17088                         if ((ri.activityInfo.flags&ActivityInfo.FLAG_SYSTEM_USER_ONLY) != 0) {
17089                             newReceivers.remove(i);
17090                             i--;
17091                         }
17092                     }
17093                 }
17094                 if (newReceivers != null && newReceivers.size() == 0) {
17095                     newReceivers = null;
17096                 }
17097                 if (receivers == null) {
17098                     receivers = newReceivers;
17099                 } else if (newReceivers != null) {
17100                     // We need to concatenate the additional receivers
17101                     // found with what we have do far.  This would be easy,
17102                     // but we also need to de-dup any receivers that are
17103                     // singleUser.
17104                     if (!scannedFirstReceivers) {
17105                         // Collect any single user receivers we had already retrieved.
17106                         scannedFirstReceivers = true;
17107                         for (int i=0; i<receivers.size(); i++) {
17108                             ResolveInfo ri = receivers.get(i);
17109                             if ((ri.activityInfo.flags&ActivityInfo.FLAG_SINGLE_USER) != 0) {
17110                                 ComponentName cn = new ComponentName(
17111                                         ri.activityInfo.packageName, ri.activityInfo.name);
17112                                 if (singleUserReceivers == null) {
17113                                     singleUserReceivers = new HashSet<ComponentName>();
17114                                 }
17115                                 singleUserReceivers.add(cn);
17116                             }
17117                         }
17118                     }
17119                     // Add the new results to the existing results, tracking
17120                     // and de-dupping single user receivers.
17121                     for (int i=0; i<newReceivers.size(); i++) {
17122                         ResolveInfo ri = newReceivers.get(i);
17123                         if ((ri.activityInfo.flags&ActivityInfo.FLAG_SINGLE_USER) != 0) {
17124                             ComponentName cn = new ComponentName(
17125                                     ri.activityInfo.packageName, ri.activityInfo.name);
17126                             if (singleUserReceivers == null) {
17127                                 singleUserReceivers = new HashSet<ComponentName>();
17128                             }
17129                             if (!singleUserReceivers.contains(cn)) {
17130                                 singleUserReceivers.add(cn);
17131                                 receivers.add(ri);
17132                             }
17133                         } else {
17134                             receivers.add(ri);
17135                         }
17136                     }
17137                 }
17138             }
17139         } catch (RemoteException ex) {
17140             // pm is in same process, this will never happen.
17141         }
17142         return receivers;
17143     }
17144
17145     private boolean isPermittedShellBroadcast(Intent intent) {
17146         // remote bugreport should always be allowed to be taken
17147         return INTENT_REMOTE_BUGREPORT_FINISHED.equals(intent.getAction());
17148     }
17149
17150     final int broadcastIntentLocked(ProcessRecord callerApp,
17151             String callerPackage, Intent intent, String resolvedType,
17152             IIntentReceiver resultTo, int resultCode, String resultData,
17153             Bundle resultExtras, String[] requiredPermissions, int appOp, Bundle bOptions,
17154             boolean ordered, boolean sticky, int callingPid, int callingUid, int userId) {
17155         intent = new Intent(intent);
17156
17157         // By default broadcasts do not go to stopped apps.
17158         intent.addFlags(Intent.FLAG_EXCLUDE_STOPPED_PACKAGES);
17159
17160         // If we have not finished booting, don't allow this to launch new processes.
17161         if (!mProcessesReady && (intent.getFlags()&Intent.FLAG_RECEIVER_BOOT_UPGRADE) == 0) {
17162             intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY);
17163         }
17164
17165         if (DEBUG_BROADCAST_LIGHT) Slog.v(TAG_BROADCAST,
17166                 (sticky ? "Broadcast sticky: ": "Broadcast: ") + intent
17167                 + " ordered=" + ordered + " userid=" + userId);
17168         if ((resultTo != null) && !ordered) {
17169             Slog.w(TAG, "Broadcast " + intent + " not ordered but result callback requested!");
17170         }
17171
17172         userId = mUserController.handleIncomingUser(callingPid, callingUid, userId, true,
17173                 ALLOW_NON_FULL, "broadcast", callerPackage);
17174
17175         // Make sure that the user who is receiving this broadcast is running.
17176         // If not, we will just skip it. Make an exception for shutdown broadcasts
17177         // and upgrade steps.
17178
17179         if (userId != UserHandle.USER_ALL && !mUserController.isUserRunningLocked(userId, 0)) {
17180             if ((callingUid != Process.SYSTEM_UID
17181                     || (intent.getFlags() & Intent.FLAG_RECEIVER_BOOT_UPGRADE) == 0)
17182                     && !Intent.ACTION_SHUTDOWN.equals(intent.getAction())) {
17183                 Slog.w(TAG, "Skipping broadcast of " + intent
17184                         + ": user " + userId + " is stopped");
17185                 return ActivityManager.BROADCAST_FAILED_USER_STOPPED;
17186             }
17187         }
17188
17189         BroadcastOptions brOptions = null;
17190         if (bOptions != null) {
17191             brOptions = new BroadcastOptions(bOptions);
17192             if (brOptions.getTemporaryAppWhitelistDuration() > 0) {
17193                 // See if the caller is allowed to do this.  Note we are checking against
17194                 // the actual real caller (not whoever provided the operation as say a
17195                 // PendingIntent), because that who is actually supplied the arguments.
17196                 if (checkComponentPermission(
17197                         android.Manifest.permission.CHANGE_DEVICE_IDLE_TEMP_WHITELIST,
17198                         Binder.getCallingPid(), Binder.getCallingUid(), -1, true)
17199                         != PackageManager.PERMISSION_GRANTED) {
17200                     String msg = "Permission Denial: " + intent.getAction()
17201                             + " broadcast from " + callerPackage + " (pid=" + callingPid
17202                             + ", uid=" + callingUid + ")"
17203                             + " requires "
17204                             + android.Manifest.permission.CHANGE_DEVICE_IDLE_TEMP_WHITELIST;
17205                     Slog.w(TAG, msg);
17206                     throw new SecurityException(msg);
17207                 }
17208             }
17209         }
17210
17211         // Verify that protected broadcasts are only being sent by system code,
17212         // and that system code is only sending protected broadcasts.
17213         final String action = intent.getAction();
17214         final boolean isProtectedBroadcast;
17215         try {
17216             isProtectedBroadcast = AppGlobals.getPackageManager().isProtectedBroadcast(action);
17217         } catch (RemoteException e) {
17218             Slog.w(TAG, "Remote exception", e);
17219             return ActivityManager.BROADCAST_SUCCESS;
17220         }
17221
17222         final boolean isCallerSystem;
17223         switch (UserHandle.getAppId(callingUid)) {
17224             case Process.ROOT_UID:
17225             case Process.SYSTEM_UID:
17226             case Process.PHONE_UID:
17227             case Process.BLUETOOTH_UID:
17228             case Process.NFC_UID:
17229                 isCallerSystem = true;
17230                 break;
17231             default:
17232                 isCallerSystem = (callerApp != null) && callerApp.persistent;
17233                 break;
17234         }
17235
17236         if (isCallerSystem) {
17237             if (isProtectedBroadcast
17238                     || Intent.ACTION_CLOSE_SYSTEM_DIALOGS.equals(action)
17239                     || Intent.ACTION_MEDIA_SCANNER_SCAN_FILE.equals(action)
17240                     || Intent.ACTION_GET_PERMISSIONS_COUNT.equals(action)
17241                     || Intent.ACTION_GET_PERMISSIONS_PACKAGES.equals(action)
17242                     || AppWidgetManager.ACTION_APPWIDGET_CONFIGURE.equals(action)
17243                     || AppWidgetManager.ACTION_APPWIDGET_UPDATE.equals(action)
17244                     || LocationManager.HIGH_POWER_REQUEST_CHANGE_ACTION.equals(action)) {
17245                 // Broadcast is either protected, or it's a public action that
17246                 // we've relaxed, so it's fine for system internals to send.
17247             } else {
17248                 // The vast majority of broadcasts sent from system internals
17249                 // should be protected to avoid security holes, so yell loudly
17250                 // to ensure we examine these cases.
17251                 Log.wtf(TAG, "Sending non-protected broadcast " + action
17252                         + " from system", new Throwable());
17253             }
17254
17255         } else {
17256             if (isProtectedBroadcast) {
17257                 String msg = "Permission Denial: not allowed to send broadcast "
17258                         + action + " from pid="
17259                         + callingPid + ", uid=" + callingUid;
17260                 Slog.w(TAG, msg);
17261                 throw new SecurityException(msg);
17262
17263             } else if (AppWidgetManager.ACTION_APPWIDGET_CONFIGURE.equals(action)
17264                     || AppWidgetManager.ACTION_APPWIDGET_UPDATE.equals(action)) {
17265                 // Special case for compatibility: we don't want apps to send this,
17266                 // but historically it has not been protected and apps may be using it
17267                 // to poke their own app widget.  So, instead of making it protected,
17268                 // just limit it to the caller.
17269                 if (callerApp == null) {
17270                     String msg = "Permission Denial: not allowed to send broadcast "
17271                             + action + " from unknown caller.";
17272                     Slog.w(TAG, msg);
17273                     throw new SecurityException(msg);
17274                 } else if (intent.getComponent() != null) {
17275                     // They are good enough to send to an explicit component...  verify
17276                     // it is being sent to the calling app.
17277                     if (!intent.getComponent().getPackageName().equals(
17278                             callerApp.info.packageName)) {
17279                         String msg = "Permission Denial: not allowed to send broadcast "
17280                                 + action + " to "
17281                                 + intent.getComponent().getPackageName() + " from "
17282                                 + callerApp.info.packageName;
17283                         Slog.w(TAG, msg);
17284                         throw new SecurityException(msg);
17285                     }
17286                 } else {
17287                     // Limit broadcast to their own package.
17288                     intent.setPackage(callerApp.info.packageName);
17289                 }
17290             }
17291         }
17292
17293         if (action != null) {
17294             switch (action) {
17295                 case Intent.ACTION_UID_REMOVED:
17296                 case Intent.ACTION_PACKAGE_REMOVED:
17297                 case Intent.ACTION_PACKAGE_CHANGED:
17298                 case Intent.ACTION_EXTERNAL_APPLICATIONS_UNAVAILABLE:
17299                 case Intent.ACTION_EXTERNAL_APPLICATIONS_AVAILABLE:
17300                 case Intent.ACTION_PACKAGES_SUSPENDED:
17301                 case Intent.ACTION_PACKAGES_UNSUSPENDED:
17302                     // Handle special intents: if this broadcast is from the package
17303                     // manager about a package being removed, we need to remove all of
17304                     // its activities from the history stack.
17305                     if (checkComponentPermission(
17306                             android.Manifest.permission.BROADCAST_PACKAGE_REMOVED,
17307                             callingPid, callingUid, -1, true)
17308                             != PackageManager.PERMISSION_GRANTED) {
17309                         String msg = "Permission Denial: " + intent.getAction()
17310                                 + " broadcast from " + callerPackage + " (pid=" + callingPid
17311                                 + ", uid=" + callingUid + ")"
17312                                 + " requires "
17313                                 + android.Manifest.permission.BROADCAST_PACKAGE_REMOVED;
17314                         Slog.w(TAG, msg);
17315                         throw new SecurityException(msg);
17316                     }
17317                     switch (action) {
17318                         case Intent.ACTION_UID_REMOVED:
17319                             final Bundle intentExtras = intent.getExtras();
17320                             final int uid = intentExtras != null
17321                                     ? intentExtras.getInt(Intent.EXTRA_UID) : -1;
17322                             if (uid >= 0) {
17323                                 mBatteryStatsService.removeUid(uid);
17324                                 mAppOpsService.uidRemoved(uid);
17325                             }
17326                             break;
17327                         case Intent.ACTION_EXTERNAL_APPLICATIONS_UNAVAILABLE:
17328                             // If resources are unavailable just force stop all those packages
17329                             // and flush the attribute cache as well.
17330                             String list[] =
17331                                     intent.getStringArrayExtra(Intent.EXTRA_CHANGED_PACKAGE_LIST);
17332                             if (list != null && list.length > 0) {
17333                                 for (int i = 0; i < list.length; i++) {
17334                                     forceStopPackageLocked(list[i], -1, false, true, true,
17335                                             false, false, userId, "storage unmount");
17336                                 }
17337                                 mRecentTasks.cleanupLocked(UserHandle.USER_ALL);
17338                                 sendPackageBroadcastLocked(
17339                                         IApplicationThread.EXTERNAL_STORAGE_UNAVAILABLE, list,
17340                                         userId);
17341                             }
17342                             break;
17343                         case Intent.ACTION_EXTERNAL_APPLICATIONS_AVAILABLE:
17344                             mRecentTasks.cleanupLocked(UserHandle.USER_ALL);
17345                             break;
17346                         case Intent.ACTION_PACKAGE_REMOVED:
17347                         case Intent.ACTION_PACKAGE_CHANGED:
17348                             Uri data = intent.getData();
17349                             String ssp;
17350                             if (data != null && (ssp=data.getSchemeSpecificPart()) != null) {
17351                                 boolean removed = Intent.ACTION_PACKAGE_REMOVED.equals(action);
17352                                 final boolean replacing =
17353                                         intent.getBooleanExtra(Intent.EXTRA_REPLACING, false);
17354                                 final boolean killProcess =
17355                                         !intent.getBooleanExtra(Intent.EXTRA_DONT_KILL_APP, false);
17356                                 final boolean fullUninstall = removed && !replacing;
17357                                 if (killProcess) {
17358                                     forceStopPackageLocked(ssp, UserHandle.getAppId(
17359                                             intent.getIntExtra(Intent.EXTRA_UID, -1)),
17360                                             false, true, true, false, fullUninstall, userId,
17361                                             removed ? "pkg removed" : "pkg changed");
17362                                 }
17363                                 if (removed) {
17364                                     final int cmd = killProcess
17365                                             ? IApplicationThread.PACKAGE_REMOVED
17366                                             : IApplicationThread.PACKAGE_REMOVED_DONT_KILL;
17367                                     sendPackageBroadcastLocked(cmd,
17368                                             new String[] {ssp}, userId);
17369                                     if (fullUninstall) {
17370                                         mAppOpsService.packageRemoved(
17371                                                 intent.getIntExtra(Intent.EXTRA_UID, -1), ssp);
17372
17373                                         // Remove all permissions granted from/to this package
17374                                         removeUriPermissionsForPackageLocked(ssp, userId, true);
17375
17376                                         removeTasksByPackageNameLocked(ssp, userId);
17377                                         mBatteryStatsService.notePackageUninstalled(ssp);
17378                                     }
17379                                 } else {
17380                                     cleanupDisabledPackageComponentsLocked(ssp, userId, killProcess,
17381                                             intent.getStringArrayExtra(
17382                                                     Intent.EXTRA_CHANGED_COMPONENT_NAME_LIST));
17383                                 }
17384                             }
17385                             break;
17386                         case Intent.ACTION_PACKAGES_SUSPENDED:
17387                         case Intent.ACTION_PACKAGES_UNSUSPENDED:
17388                             final boolean suspended = Intent.ACTION_PACKAGES_SUSPENDED.equals(
17389                                     intent.getAction());
17390                             final String[] packageNames = intent.getStringArrayExtra(
17391                                     Intent.EXTRA_CHANGED_PACKAGE_LIST);
17392                             final int userHandle = intent.getIntExtra(
17393                                     Intent.EXTRA_USER_HANDLE, UserHandle.USER_NULL);
17394
17395                             synchronized(ActivityManagerService.this) {
17396                                 mRecentTasks.onPackagesSuspendedChanged(
17397                                         packageNames, suspended, userHandle);
17398                             }
17399                             break;
17400                     }
17401                     break;
17402                 case Intent.ACTION_PACKAGE_REPLACED:
17403                 {
17404                     final Uri data = intent.getData();
17405                     final String ssp;
17406                     if (data != null && (ssp = data.getSchemeSpecificPart()) != null) {
17407                         final ApplicationInfo aInfo =
17408                                 getPackageManagerInternalLocked().getApplicationInfo(
17409                                         ssp,
17410                                         userId);
17411                         mStackSupervisor.updateActivityApplicationInfoLocked(aInfo);
17412                         sendPackageBroadcastLocked(IApplicationThread.PACKAGE_REPLACED,
17413                                 new String[] {ssp}, userId);
17414                     }
17415                     break;
17416                 }
17417                 case Intent.ACTION_PACKAGE_ADDED:
17418                 {
17419                     // Special case for adding a package: by default turn on compatibility mode.
17420                     Uri data = intent.getData();
17421                     String ssp;
17422                     if (data != null && (ssp = data.getSchemeSpecificPart()) != null) {
17423                         final boolean replacing =
17424                                 intent.getBooleanExtra(Intent.EXTRA_REPLACING, false);
17425                         mCompatModePackages.handlePackageAddedLocked(ssp, replacing);
17426
17427                         try {
17428                             ApplicationInfo ai = AppGlobals.getPackageManager().
17429                                     getApplicationInfo(ssp, 0, 0);
17430                             mBatteryStatsService.notePackageInstalled(ssp,
17431                                     ai != null ? ai.versionCode : 0);
17432                         } catch (RemoteException e) {
17433                         }
17434                     }
17435                     break;
17436                 }
17437                 case Intent.ACTION_TIMEZONE_CHANGED:
17438                     // If this is the time zone changed action, queue up a message that will reset
17439                     // the timezone of all currently running processes. This message will get
17440                     // queued up before the broadcast happens.
17441                     mHandler.sendEmptyMessage(UPDATE_TIME_ZONE);
17442                     break;
17443                 case Intent.ACTION_TIME_CHANGED:
17444                     // If the user set the time, let all running processes know.
17445                     final int is24Hour =
17446                             intent.getBooleanExtra(Intent.EXTRA_TIME_PREF_24_HOUR_FORMAT, false) ? 1
17447                                     : 0;
17448                     mHandler.sendMessage(mHandler.obtainMessage(UPDATE_TIME, is24Hour, 0));
17449                     BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
17450                     synchronized (stats) {
17451                         stats.noteCurrentTimeChangedLocked();
17452                     }
17453                     break;
17454                 case Intent.ACTION_CLEAR_DNS_CACHE:
17455                     mHandler.sendEmptyMessage(CLEAR_DNS_CACHE_MSG);
17456                     break;
17457                 case Proxy.PROXY_CHANGE_ACTION:
17458                     ProxyInfo proxy = intent.getParcelableExtra(Proxy.EXTRA_PROXY_INFO);
17459                     mHandler.sendMessage(mHandler.obtainMessage(UPDATE_HTTP_PROXY_MSG, proxy));
17460                     break;
17461                 case android.hardware.Camera.ACTION_NEW_PICTURE:
17462                 case android.hardware.Camera.ACTION_NEW_VIDEO:
17463                     // These broadcasts are no longer allowed by the system, since they can
17464                     // cause significant thrashing at a crictical point (using the camera).
17465                     // Apps should use JobScehduler to monitor for media provider changes.
17466                     Slog.w(TAG, action + " no longer allowed; dropping from "
17467                             + UserHandle.formatUid(callingUid));
17468                     // Lie; we don't want to crash the app.
17469                     return ActivityManager.BROADCAST_SUCCESS;
17470             }
17471         }
17472
17473         // Add to the sticky list if requested.
17474         if (sticky) {
17475             if (checkPermission(android.Manifest.permission.BROADCAST_STICKY,
17476                     callingPid, callingUid)
17477                     != PackageManager.PERMISSION_GRANTED) {
17478                 String msg = "Permission Denial: broadcastIntent() requesting a sticky broadcast from pid="
17479                         + callingPid + ", uid=" + callingUid
17480                         + " requires " + android.Manifest.permission.BROADCAST_STICKY;
17481                 Slog.w(TAG, msg);
17482                 throw new SecurityException(msg);
17483             }
17484             if (requiredPermissions != null && requiredPermissions.length > 0) {
17485                 Slog.w(TAG, "Can't broadcast sticky intent " + intent
17486                         + " and enforce permissions " + Arrays.toString(requiredPermissions));
17487                 return ActivityManager.BROADCAST_STICKY_CANT_HAVE_PERMISSION;
17488             }
17489             if (intent.getComponent() != null) {
17490                 throw new SecurityException(
17491                         "Sticky broadcasts can't target a specific component");
17492             }
17493             // We use userId directly here, since the "all" target is maintained
17494             // as a separate set of sticky broadcasts.
17495             if (userId != UserHandle.USER_ALL) {
17496                 // But first, if this is not a broadcast to all users, then
17497                 // make sure it doesn't conflict with an existing broadcast to
17498                 // all users.
17499                 ArrayMap<String, ArrayList<Intent>> stickies = mStickyBroadcasts.get(
17500                         UserHandle.USER_ALL);
17501                 if (stickies != null) {
17502                     ArrayList<Intent> list = stickies.get(intent.getAction());
17503                     if (list != null) {
17504                         int N = list.size();
17505                         int i;
17506                         for (i=0; i<N; i++) {
17507                             if (intent.filterEquals(list.get(i))) {
17508                                 throw new IllegalArgumentException(
17509                                         "Sticky broadcast " + intent + " for user "
17510                                         + userId + " conflicts with existing global broadcast");
17511                             }
17512                         }
17513                     }
17514                 }
17515             }
17516             ArrayMap<String, ArrayList<Intent>> stickies = mStickyBroadcasts.get(userId);
17517             if (stickies == null) {
17518                 stickies = new ArrayMap<>();
17519                 mStickyBroadcasts.put(userId, stickies);
17520             }
17521             ArrayList<Intent> list = stickies.get(intent.getAction());
17522             if (list == null) {
17523                 list = new ArrayList<>();
17524                 stickies.put(intent.getAction(), list);
17525             }
17526             final int stickiesCount = list.size();
17527             int i;
17528             for (i = 0; i < stickiesCount; i++) {
17529                 if (intent.filterEquals(list.get(i))) {
17530                     // This sticky already exists, replace it.
17531                     list.set(i, new Intent(intent));
17532                     break;
17533                 }
17534             }
17535             if (i >= stickiesCount) {
17536                 list.add(new Intent(intent));
17537             }
17538         }
17539
17540         int[] users;
17541         if (userId == UserHandle.USER_ALL) {
17542             // Caller wants broadcast to go to all started users.
17543             users = mUserController.getStartedUserArrayLocked();
17544         } else {
17545             // Caller wants broadcast to go to one specific user.
17546             users = new int[] {userId};
17547         }
17548
17549         // Figure out who all will receive this broadcast.
17550         List receivers = null;
17551         List<BroadcastFilter> registeredReceivers = null;
17552         // Need to resolve the intent to interested receivers...
17553         if ((intent.getFlags()&Intent.FLAG_RECEIVER_REGISTERED_ONLY)
17554                  == 0) {
17555             receivers = collectReceiverComponents(intent, resolvedType, callingUid, users);
17556         }
17557         if (intent.getComponent() == null) {
17558             if (userId == UserHandle.USER_ALL && callingUid == Process.SHELL_UID) {
17559                 // Query one target user at a time, excluding shell-restricted users
17560                 for (int i = 0; i < users.length; i++) {
17561                     if (mUserController.hasUserRestriction(
17562                             UserManager.DISALLOW_DEBUGGING_FEATURES, users[i])) {
17563                         continue;
17564                     }
17565                     List<BroadcastFilter> registeredReceiversForUser =
17566                             mReceiverResolver.queryIntent(intent,
17567                                     resolvedType, false, users[i]);
17568                     if (registeredReceivers == null) {
17569                         registeredReceivers = registeredReceiversForUser;
17570                     } else if (registeredReceiversForUser != null) {
17571                         registeredReceivers.addAll(registeredReceiversForUser);
17572                     }
17573                 }
17574             } else {
17575                 registeredReceivers = mReceiverResolver.queryIntent(intent,
17576                         resolvedType, false, userId);
17577             }
17578         }
17579
17580         final boolean replacePending =
17581                 (intent.getFlags()&Intent.FLAG_RECEIVER_REPLACE_PENDING) != 0;
17582
17583         if (DEBUG_BROADCAST) Slog.v(TAG_BROADCAST, "Enqueing broadcast: " + intent.getAction()
17584                 + " replacePending=" + replacePending);
17585
17586         int NR = registeredReceivers != null ? registeredReceivers.size() : 0;
17587         if (!ordered && NR > 0) {
17588             // If we are not serializing this broadcast, then send the
17589             // registered receivers separately so they don't wait for the
17590             // components to be launched.
17591             final BroadcastQueue queue = broadcastQueueForIntent(intent);
17592             BroadcastRecord r = new BroadcastRecord(queue, intent, callerApp,
17593                     callerPackage, callingPid, callingUid, resolvedType, requiredPermissions,
17594                     appOp, brOptions, registeredReceivers, resultTo, resultCode, resultData,
17595                     resultExtras, ordered, sticky, false, userId);
17596             if (DEBUG_BROADCAST) Slog.v(TAG_BROADCAST, "Enqueueing parallel broadcast " + r);
17597             final boolean replaced = replacePending && queue.replaceParallelBroadcastLocked(r);
17598             if (!replaced) {
17599                 queue.enqueueParallelBroadcastLocked(r);
17600                 queue.scheduleBroadcastsLocked();
17601             }
17602             registeredReceivers = null;
17603             NR = 0;
17604         }
17605
17606         // Merge into one list.
17607         int ir = 0;
17608         if (receivers != null) {
17609             // A special case for PACKAGE_ADDED: do not allow the package
17610             // being added to see this broadcast.  This prevents them from
17611             // using this as a back door to get run as soon as they are
17612             // installed.  Maybe in the future we want to have a special install
17613             // broadcast or such for apps, but we'd like to deliberately make
17614             // this decision.
17615             String skipPackages[] = null;
17616             if (Intent.ACTION_PACKAGE_ADDED.equals(intent.getAction())
17617                     || Intent.ACTION_PACKAGE_RESTARTED.equals(intent.getAction())
17618                     || Intent.ACTION_PACKAGE_DATA_CLEARED.equals(intent.getAction())) {
17619                 Uri data = intent.getData();
17620                 if (data != null) {
17621                     String pkgName = data.getSchemeSpecificPart();
17622                     if (pkgName != null) {
17623                         skipPackages = new String[] { pkgName };
17624                     }
17625                 }
17626             } else if (Intent.ACTION_EXTERNAL_APPLICATIONS_AVAILABLE.equals(intent.getAction())) {
17627                 skipPackages = intent.getStringArrayExtra(Intent.EXTRA_CHANGED_PACKAGE_LIST);
17628             }
17629             if (skipPackages != null && (skipPackages.length > 0)) {
17630                 for (String skipPackage : skipPackages) {
17631                     if (skipPackage != null) {
17632                         int NT = receivers.size();
17633                         for (int it=0; it<NT; it++) {
17634                             ResolveInfo curt = (ResolveInfo)receivers.get(it);
17635                             if (curt.activityInfo.packageName.equals(skipPackage)) {
17636                                 receivers.remove(it);
17637                                 it--;
17638                                 NT--;
17639                             }
17640                         }
17641                     }
17642                 }
17643             }
17644
17645             int NT = receivers != null ? receivers.size() : 0;
17646             int it = 0;
17647             ResolveInfo curt = null;
17648             BroadcastFilter curr = null;
17649             while (it < NT && ir < NR) {
17650                 if (curt == null) {
17651                     curt = (ResolveInfo)receivers.get(it);
17652                 }
17653                 if (curr == null) {
17654                     curr = registeredReceivers.get(ir);
17655                 }
17656                 if (curr.getPriority() >= curt.priority) {
17657                     // Insert this broadcast record into the final list.
17658                     receivers.add(it, curr);
17659                     ir++;
17660                     curr = null;
17661                     it++;
17662                     NT++;
17663                 } else {
17664                     // Skip to the next ResolveInfo in the final list.
17665                     it++;
17666                     curt = null;
17667                 }
17668             }
17669         }
17670         while (ir < NR) {
17671             if (receivers == null) {
17672                 receivers = new ArrayList();
17673             }
17674             receivers.add(registeredReceivers.get(ir));
17675             ir++;
17676         }
17677
17678         if ((receivers != null && receivers.size() > 0)
17679                 || resultTo != null) {
17680             BroadcastQueue queue = broadcastQueueForIntent(intent);
17681             BroadcastRecord r = new BroadcastRecord(queue, intent, callerApp,
17682                     callerPackage, callingPid, callingUid, resolvedType,
17683                     requiredPermissions, appOp, brOptions, receivers, resultTo, resultCode,
17684                     resultData, resultExtras, ordered, sticky, false, userId);
17685
17686             if (DEBUG_BROADCAST) Slog.v(TAG_BROADCAST, "Enqueueing ordered broadcast " + r
17687                     + ": prev had " + queue.mOrderedBroadcasts.size());
17688             if (DEBUG_BROADCAST) Slog.i(TAG_BROADCAST,
17689                     "Enqueueing broadcast " + r.intent.getAction());
17690
17691             boolean replaced = replacePending && queue.replaceOrderedBroadcastLocked(r);
17692             if (!replaced) {
17693                 queue.enqueueOrderedBroadcastLocked(r);
17694                 queue.scheduleBroadcastsLocked();
17695             }
17696         }
17697
17698         return ActivityManager.BROADCAST_SUCCESS;
17699     }
17700
17701     final Intent verifyBroadcastLocked(Intent intent) {
17702         // Refuse possible leaked file descriptors
17703         if (intent != null && intent.hasFileDescriptors() == true) {
17704             throw new IllegalArgumentException("File descriptors passed in Intent");
17705         }
17706
17707         int flags = intent.getFlags();
17708
17709         if (!mProcessesReady) {
17710             // if the caller really truly claims to know what they're doing, go
17711             // ahead and allow the broadcast without launching any receivers
17712             if ((flags&Intent.FLAG_RECEIVER_REGISTERED_ONLY_BEFORE_BOOT) != 0) {
17713                 // This will be turned into a FLAG_RECEIVER_REGISTERED_ONLY later on if needed.
17714             } else if ((flags&Intent.FLAG_RECEIVER_REGISTERED_ONLY) == 0) {
17715                 Slog.e(TAG, "Attempt to launch receivers of broadcast intent " + intent
17716                         + " before boot completion");
17717                 throw new IllegalStateException("Cannot broadcast before boot completed");
17718             }
17719         }
17720
17721         if ((flags&Intent.FLAG_RECEIVER_BOOT_UPGRADE) != 0) {
17722             throw new IllegalArgumentException(
17723                     "Can't use FLAG_RECEIVER_BOOT_UPGRADE here");
17724         }
17725
17726         return intent;
17727     }
17728
17729     public final int broadcastIntent(IApplicationThread caller,
17730             Intent intent, String resolvedType, IIntentReceiver resultTo,
17731             int resultCode, String resultData, Bundle resultExtras,
17732             String[] requiredPermissions, int appOp, Bundle bOptions,
17733             boolean serialized, boolean sticky, int userId) {
17734         enforceNotIsolatedCaller("broadcastIntent");
17735         synchronized(this) {
17736             intent = verifyBroadcastLocked(intent);
17737
17738             final ProcessRecord callerApp = getRecordForAppLocked(caller);
17739             final int callingPid = Binder.getCallingPid();
17740             final int callingUid = Binder.getCallingUid();
17741             final long origId = Binder.clearCallingIdentity();
17742             int res = broadcastIntentLocked(callerApp,
17743                     callerApp != null ? callerApp.info.packageName : null,
17744                     intent, resolvedType, resultTo, resultCode, resultData, resultExtras,
17745                     requiredPermissions, appOp, null, serialized, sticky,
17746                     callingPid, callingUid, userId);
17747             Binder.restoreCallingIdentity(origId);
17748             return res;
17749         }
17750     }
17751
17752
17753     int broadcastIntentInPackage(String packageName, int uid,
17754             Intent intent, String resolvedType, IIntentReceiver resultTo,
17755             int resultCode, String resultData, Bundle resultExtras,
17756             String requiredPermission, Bundle bOptions, boolean serialized, boolean sticky,
17757             int userId) {
17758         synchronized(this) {
17759             intent = verifyBroadcastLocked(intent);
17760
17761             final long origId = Binder.clearCallingIdentity();
17762             String[] requiredPermissions = requiredPermission == null ? null
17763                     : new String[] {requiredPermission};
17764             int res = broadcastIntentLocked(null, packageName, intent, resolvedType,
17765                     resultTo, resultCode, resultData, resultExtras,
17766                     requiredPermissions, AppOpsManager.OP_NONE, bOptions, serialized,
17767                     sticky, -1, uid, userId);
17768             Binder.restoreCallingIdentity(origId);
17769             return res;
17770         }
17771     }
17772
17773     public final void unbroadcastIntent(IApplicationThread caller, Intent intent, int userId) {
17774         // Refuse possible leaked file descriptors
17775         if (intent != null && intent.hasFileDescriptors() == true) {
17776             throw new IllegalArgumentException("File descriptors passed in Intent");
17777         }
17778
17779         userId = mUserController.handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(),
17780                 userId, true, ALLOW_NON_FULL, "removeStickyBroadcast", null);
17781
17782         synchronized(this) {
17783             if (checkCallingPermission(android.Manifest.permission.BROADCAST_STICKY)
17784                     != PackageManager.PERMISSION_GRANTED) {
17785                 String msg = "Permission Denial: unbroadcastIntent() from pid="
17786                         + Binder.getCallingPid()
17787                         + ", uid=" + Binder.getCallingUid()
17788                         + " requires " + android.Manifest.permission.BROADCAST_STICKY;
17789                 Slog.w(TAG, msg);
17790                 throw new SecurityException(msg);
17791             }
17792             ArrayMap<String, ArrayList<Intent>> stickies = mStickyBroadcasts.get(userId);
17793             if (stickies != null) {
17794                 ArrayList<Intent> list = stickies.get(intent.getAction());
17795                 if (list != null) {
17796                     int N = list.size();
17797                     int i;
17798                     for (i=0; i<N; i++) {
17799                         if (intent.filterEquals(list.get(i))) {
17800                             list.remove(i);
17801                             break;
17802                         }
17803                     }
17804                     if (list.size() <= 0) {
17805                         stickies.remove(intent.getAction());
17806                     }
17807                 }
17808                 if (stickies.size() <= 0) {
17809                     mStickyBroadcasts.remove(userId);
17810                 }
17811             }
17812         }
17813     }
17814
17815     void backgroundServicesFinishedLocked(int userId) {
17816         for (BroadcastQueue queue : mBroadcastQueues) {
17817             queue.backgroundServicesFinishedLocked(userId);
17818         }
17819     }
17820
17821     public void finishReceiver(IBinder who, int resultCode, String resultData,
17822             Bundle resultExtras, boolean resultAbort, int flags) {
17823         if (DEBUG_BROADCAST) Slog.v(TAG_BROADCAST, "Finish receiver: " + who);
17824
17825         // Refuse possible leaked file descriptors
17826         if (resultExtras != null && resultExtras.hasFileDescriptors()) {
17827             throw new IllegalArgumentException("File descriptors passed in Bundle");
17828         }
17829
17830         final long origId = Binder.clearCallingIdentity();
17831         try {
17832             boolean doNext = false;
17833             BroadcastRecord r;
17834
17835             synchronized(this) {
17836                 BroadcastQueue queue = (flags & Intent.FLAG_RECEIVER_FOREGROUND) != 0
17837                         ? mFgBroadcastQueue : mBgBroadcastQueue;
17838                 r = queue.getMatchingOrderedReceiver(who);
17839                 if (r != null) {
17840                     doNext = r.queue.finishReceiverLocked(r, resultCode,
17841                         resultData, resultExtras, resultAbort, true);
17842                 }
17843             }
17844
17845             if (doNext) {
17846                 r.queue.processNextBroadcast(false);
17847             }
17848             trimApplications();
17849         } finally {
17850             Binder.restoreCallingIdentity(origId);
17851         }
17852     }
17853
17854     // =========================================================
17855     // INSTRUMENTATION
17856     // =========================================================
17857
17858     public boolean startInstrumentation(ComponentName className,
17859             String profileFile, int flags, Bundle arguments,
17860             IInstrumentationWatcher watcher, IUiAutomationConnection uiAutomationConnection,
17861             int userId, String abiOverride) {
17862         enforceNotIsolatedCaller("startInstrumentation");
17863         userId = mUserController.handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(),
17864                 userId, false, ALLOW_FULL_ONLY, "startInstrumentation", null);
17865         // Refuse possible leaked file descriptors
17866         if (arguments != null && arguments.hasFileDescriptors()) {
17867             throw new IllegalArgumentException("File descriptors passed in Bundle");
17868         }
17869
17870         synchronized(this) {
17871             InstrumentationInfo ii = null;
17872             ApplicationInfo ai = null;
17873             try {
17874                 ii = mContext.getPackageManager().getInstrumentationInfo(
17875                     className, STOCK_PM_FLAGS);
17876                 ai = AppGlobals.getPackageManager().getApplicationInfo(
17877                         ii.targetPackage, STOCK_PM_FLAGS, userId);
17878             } catch (PackageManager.NameNotFoundException e) {
17879             } catch (RemoteException e) {
17880             }
17881             if (ii == null) {
17882                 reportStartInstrumentationFailureLocked(watcher, className,
17883                         "Unable to find instrumentation info for: " + className);
17884                 return false;
17885             }
17886             if (ai == null) {
17887                 reportStartInstrumentationFailureLocked(watcher, className,
17888                         "Unable to find instrumentation target package: " + ii.targetPackage);
17889                 return false;
17890             }
17891             if (!ai.hasCode()) {
17892                 reportStartInstrumentationFailureLocked(watcher, className,
17893                         "Instrumentation target has no code: " + ii.targetPackage);
17894                 return false;
17895             }
17896
17897             int match = mContext.getPackageManager().checkSignatures(
17898                     ii.targetPackage, ii.packageName);
17899             if (match < 0 && match != PackageManager.SIGNATURE_FIRST_NOT_SIGNED) {
17900                 String msg = "Permission Denial: starting instrumentation "
17901                         + className + " from pid="
17902                         + Binder.getCallingPid()
17903                         + ", uid=" + Binder.getCallingPid()
17904                         + " not allowed because package " + ii.packageName
17905                         + " does not have a signature matching the target "
17906                         + ii.targetPackage;
17907                 reportStartInstrumentationFailureLocked(watcher, className, msg);
17908                 throw new SecurityException(msg);
17909             }
17910
17911             final long origId = Binder.clearCallingIdentity();
17912             // Instrumentation can kill and relaunch even persistent processes
17913             forceStopPackageLocked(ii.targetPackage, -1, true, false, true, true, false, userId,
17914                     "start instr");
17915             ProcessRecord app = addAppLocked(ai, false, abiOverride);
17916             app.instrumentationClass = className;
17917             app.instrumentationInfo = ai;
17918             app.instrumentationProfileFile = profileFile;
17919             app.instrumentationArguments = arguments;
17920             app.instrumentationWatcher = watcher;
17921             app.instrumentationUiAutomationConnection = uiAutomationConnection;
17922             app.instrumentationResultClass = className;
17923             Binder.restoreCallingIdentity(origId);
17924         }
17925
17926         return true;
17927     }
17928
17929     /**
17930      * Report errors that occur while attempting to start Instrumentation.  Always writes the
17931      * error to the logs, but if somebody is watching, send the report there too.  This enables
17932      * the "am" command to report errors with more information.
17933      *
17934      * @param watcher The IInstrumentationWatcher.  Null if there isn't one.
17935      * @param cn The component name of the instrumentation.
17936      * @param report The error report.
17937      */
17938     private void reportStartInstrumentationFailureLocked(IInstrumentationWatcher watcher,
17939             ComponentName cn, String report) {
17940         Slog.w(TAG, report);
17941         if (watcher != null) {
17942             Bundle results = new Bundle();
17943             results.putString(Instrumentation.REPORT_KEY_IDENTIFIER, "ActivityManagerService");
17944             results.putString("Error", report);
17945             mInstrumentationReporter.reportStatus(watcher, cn, -1, results);
17946         }
17947     }
17948
17949     void finishInstrumentationLocked(ProcessRecord app, int resultCode, Bundle results) {
17950         if (app.instrumentationWatcher != null) {
17951             mInstrumentationReporter.reportFinished(app.instrumentationWatcher,
17952                     app.instrumentationClass, resultCode, results);
17953         }
17954
17955         // Can't call out of the system process with a lock held, so post a message.
17956         if (app.instrumentationUiAutomationConnection != null) {
17957             mHandler.obtainMessage(SHUTDOWN_UI_AUTOMATION_CONNECTION_MSG,
17958                     app.instrumentationUiAutomationConnection).sendToTarget();
17959         }
17960
17961         app.instrumentationWatcher = null;
17962         app.instrumentationUiAutomationConnection = null;
17963         app.instrumentationClass = null;
17964         app.instrumentationInfo = null;
17965         app.instrumentationProfileFile = null;
17966         app.instrumentationArguments = null;
17967
17968         forceStopPackageLocked(app.info.packageName, -1, false, false, true, true, false, app.userId,
17969                 "finished inst");
17970     }
17971
17972     public void finishInstrumentation(IApplicationThread target,
17973             int resultCode, Bundle results) {
17974         int userId = UserHandle.getCallingUserId();
17975         // Refuse possible leaked file descriptors
17976         if (results != null && results.hasFileDescriptors()) {
17977             throw new IllegalArgumentException("File descriptors passed in Intent");
17978         }
17979
17980         synchronized(this) {
17981             ProcessRecord app = getRecordForAppLocked(target);
17982             if (app == null) {
17983                 Slog.w(TAG, "finishInstrumentation: no app for " + target);
17984                 return;
17985             }
17986             final long origId = Binder.clearCallingIdentity();
17987             finishInstrumentationLocked(app, resultCode, results);
17988             Binder.restoreCallingIdentity(origId);
17989         }
17990     }
17991
17992     // =========================================================
17993     // CONFIGURATION
17994     // =========================================================
17995
17996     public ConfigurationInfo getDeviceConfigurationInfo() {
17997         ConfigurationInfo config = new ConfigurationInfo();
17998         synchronized (this) {
17999             config.reqTouchScreen = mConfiguration.touchscreen;
18000             config.reqKeyboardType = mConfiguration.keyboard;
18001             config.reqNavigation = mConfiguration.navigation;
18002             if (mConfiguration.navigation == Configuration.NAVIGATION_DPAD
18003                     || mConfiguration.navigation == Configuration.NAVIGATION_TRACKBALL) {
18004                 config.reqInputFeatures |= ConfigurationInfo.INPUT_FEATURE_FIVE_WAY_NAV;
18005             }
18006             if (mConfiguration.keyboard != Configuration.KEYBOARD_UNDEFINED
18007                     && mConfiguration.keyboard != Configuration.KEYBOARD_NOKEYS) {
18008                 config.reqInputFeatures |= ConfigurationInfo.INPUT_FEATURE_HARD_KEYBOARD;
18009             }
18010             config.reqGlEsVersion = GL_ES_VERSION;
18011         }
18012         return config;
18013     }
18014
18015     ActivityStack getFocusedStack() {
18016         return mStackSupervisor.getFocusedStack();
18017     }
18018
18019     @Override
18020     public int getFocusedStackId() throws RemoteException {
18021         ActivityStack focusedStack = getFocusedStack();
18022         if (focusedStack != null) {
18023             return focusedStack.getStackId();
18024         }
18025         return -1;
18026     }
18027
18028     public Configuration getConfiguration() {
18029         Configuration ci;
18030         synchronized(this) {
18031             ci = new Configuration(mConfiguration);
18032             ci.userSetLocale = false;
18033         }
18034         return ci;
18035     }
18036
18037     @Override
18038     public void suppressResizeConfigChanges(boolean suppress) throws RemoteException {
18039         enforceCallingPermission(MANAGE_ACTIVITY_STACKS, "suppressResizeConfigChanges()");
18040         synchronized (this) {
18041             mSuppressResizeConfigChanges = suppress;
18042         }
18043     }
18044
18045     @Override
18046     public void moveTasksToFullscreenStack(int fromStackId, boolean onTop) {
18047         enforceCallingPermission(MANAGE_ACTIVITY_STACKS, "moveTasksToFullscreenStack()");
18048         if (fromStackId == HOME_STACK_ID) {
18049             throw new IllegalArgumentException("You can't move tasks from the home stack.");
18050         }
18051         synchronized (this) {
18052             final long origId = Binder.clearCallingIdentity();
18053             final ActivityStack stack = mStackSupervisor.getStack(fromStackId);
18054             if (stack != null) {
18055                 mWindowManager.deferSurfaceLayout();
18056                 try {
18057                     if (fromStackId == DOCKED_STACK_ID) {
18058
18059                         // We are moving all tasks from the docked stack to the fullscreen stack,
18060                         // which is dismissing the docked stack, so resize all other stacks to
18061                         // fullscreen here already so we don't end up with resize trashing.
18062                         for (int i = FIRST_STATIC_STACK_ID; i <= LAST_STATIC_STACK_ID; i++) {
18063                             if (StackId.isResizeableByDockedStack(i)) {
18064                                 ActivityStack otherStack = mStackSupervisor.getStack(i);
18065                                 if (otherStack != null) {
18066                                     mStackSupervisor.resizeStackLocked(i,
18067                                             null, null, null, PRESERVE_WINDOWS,
18068                                             true /* allowResizeInDockedMode */);
18069                                 }
18070                             }
18071                         }
18072                     }
18073                     final ArrayList<TaskRecord> tasks = stack.getAllTasks();
18074                     final int size = tasks.size();
18075                     if (onTop) {
18076                         for (int i = 0; i < size; i++) {
18077                             mStackSupervisor.moveTaskToStackLocked(tasks.get(i).taskId,
18078                                     FULLSCREEN_WORKSPACE_STACK_ID, onTop, !FORCE_FOCUS,
18079                                     "moveTasksToFullscreenStack", ANIMATE);
18080                         }
18081                     } else {
18082                         for (int i = size - 1; i >= 0; i--) {
18083                             mStackSupervisor.positionTaskInStackLocked(tasks.get(i).taskId,
18084                                     FULLSCREEN_WORKSPACE_STACK_ID, 0);
18085                         }
18086                     }
18087                 } finally {
18088                     mWindowManager.continueSurfaceLayout();
18089                 }
18090
18091             }
18092             Binder.restoreCallingIdentity(origId);
18093         }
18094     }
18095
18096     @Override
18097     public void updatePersistentConfiguration(Configuration values) {
18098         enforceCallingPermission(android.Manifest.permission.CHANGE_CONFIGURATION,
18099                 "updateConfiguration()");
18100         enforceWriteSettingsPermission("updateConfiguration()");
18101         if (values == null) {
18102             throw new NullPointerException("Configuration must not be null");
18103         }
18104
18105         int userId = UserHandle.getCallingUserId();
18106
18107         synchronized(this) {
18108             final long origId = Binder.clearCallingIdentity();
18109             updateConfigurationLocked(values, null, false, true, userId);
18110             Binder.restoreCallingIdentity(origId);
18111         }
18112     }
18113
18114     private void updateFontScaleIfNeeded() {
18115         final int currentUserId;
18116         synchronized(this) {
18117             currentUserId = mUserController.getCurrentUserIdLocked();
18118         }
18119         final float scaleFactor = Settings.System.getFloatForUser(mContext.getContentResolver(),
18120                 FONT_SCALE, 1.0f, currentUserId);
18121         if (mConfiguration.fontScale != scaleFactor) {
18122             final Configuration configuration = mWindowManager.computeNewConfiguration();
18123             configuration.fontScale = scaleFactor;
18124             updatePersistentConfiguration(configuration);
18125         }
18126     }
18127
18128     private void enforceWriteSettingsPermission(String func) {
18129         int uid = Binder.getCallingUid();
18130         if (uid == Process.ROOT_UID) {
18131             return;
18132         }
18133
18134         if (Settings.checkAndNoteWriteSettingsOperation(mContext, uid,
18135                 Settings.getPackageNameForUid(mContext, uid), false)) {
18136             return;
18137         }
18138
18139         String msg = "Permission Denial: " + func + " from pid="
18140                 + Binder.getCallingPid()
18141                 + ", uid=" + uid
18142                 + " requires " + android.Manifest.permission.WRITE_SETTINGS;
18143         Slog.w(TAG, msg);
18144         throw new SecurityException(msg);
18145     }
18146
18147     public void updateConfiguration(Configuration values) {
18148         enforceCallingPermission(android.Manifest.permission.CHANGE_CONFIGURATION,
18149                 "updateConfiguration()");
18150
18151         synchronized(this) {
18152             if (values == null && mWindowManager != null) {
18153                 // sentinel: fetch the current configuration from the window manager
18154                 values = mWindowManager.computeNewConfiguration();
18155             }
18156
18157             if (mWindowManager != null) {
18158                 mProcessList.applyDisplaySize(mWindowManager);
18159             }
18160
18161             final long origId = Binder.clearCallingIdentity();
18162             if (values != null) {
18163                 Settings.System.clearConfiguration(values);
18164             }
18165             updateConfigurationLocked(values, null, false);
18166             Binder.restoreCallingIdentity(origId);
18167         }
18168     }
18169
18170     void updateUserConfigurationLocked() {
18171         Configuration configuration = new Configuration(mConfiguration);
18172         Settings.System.getConfigurationForUser(mContext.getContentResolver(), configuration,
18173                 mUserController.getCurrentUserIdLocked());
18174         updateConfigurationLocked(configuration, null, false);
18175     }
18176
18177     boolean updateConfigurationLocked(Configuration values,
18178             ActivityRecord starting, boolean initLocale) {
18179         // pass UserHandle.USER_NULL as userId because we don't persist configuration for any user
18180         return updateConfigurationLocked(values, starting, initLocale, false,
18181                 UserHandle.USER_NULL);
18182     }
18183
18184     // To cache the list of supported system locales
18185     private String[] mSupportedSystemLocales = null;
18186
18187     /**
18188      * Do either or both things: (1) change the current configuration, and (2)
18189      * make sure the given activity is running with the (now) current
18190      * configuration.  Returns true if the activity has been left running, or
18191      * false if <var>starting</var> is being destroyed to match the new
18192      * configuration.
18193      *
18194      * @param userId is only used when persistent parameter is set to true to persist configuration
18195      *               for that particular user
18196      */
18197     private boolean updateConfigurationLocked(Configuration values,
18198             ActivityRecord starting, boolean initLocale, boolean persistent, int userId) {
18199         int changes = 0;
18200
18201         if (values != null) {
18202             Configuration newConfig = new Configuration(mConfiguration);
18203             changes = newConfig.updateFrom(values);
18204             if (changes != 0) {
18205                 if (DEBUG_SWITCH || DEBUG_CONFIGURATION) Slog.i(TAG_CONFIGURATION,
18206                         "Updating configuration to: " + values);
18207
18208                 EventLog.writeEvent(EventLogTags.CONFIGURATION_CHANGED, changes);
18209
18210                 if (!initLocale && !values.getLocales().isEmpty() && values.userSetLocale) {
18211                     final Locale locale;
18212                     if (values.getLocales().size() == 1) {
18213                         // This is an optimization to avoid the JNI call when the result of
18214                         // getFirstMatch() does not depend on the supported locales.
18215                         locale = values.getLocales().get(0);
18216                     } else {
18217                         if (mSupportedSystemLocales == null) {
18218                             mSupportedSystemLocales =
18219                                     Resources.getSystem().getAssets().getLocales();
18220                         }
18221                         locale = values.getLocales().getFirstMatch(mSupportedSystemLocales);
18222                     }
18223                     SystemProperties.set("persist.sys.locale", locale.toLanguageTag());
18224                     mHandler.sendMessage(mHandler.obtainMessage(SEND_LOCALE_TO_MOUNT_DAEMON_MSG,
18225                             locale));
18226                 }
18227
18228                 mConfigurationSeq++;
18229                 if (mConfigurationSeq <= 0) {
18230                     mConfigurationSeq = 1;
18231                 }
18232                 newConfig.seq = mConfigurationSeq;
18233                 mConfiguration = newConfig;
18234                 Slog.i(TAG, "Config changes=" + Integer.toHexString(changes) + " " + newConfig);
18235                 mUsageStatsService.reportConfigurationChange(newConfig,
18236                         mUserController.getCurrentUserIdLocked());
18237                 //mUsageStatsService.noteStartConfig(newConfig);
18238
18239                 final Configuration configCopy = new Configuration(mConfiguration);
18240
18241                 // TODO: If our config changes, should we auto dismiss any currently
18242                 // showing dialogs?
18243                 mShowDialogs = shouldShowDialogs(newConfig, mInVrMode);
18244
18245                 AttributeCache ac = AttributeCache.instance();
18246                 if (ac != null) {
18247                     ac.updateConfiguration(configCopy);
18248                 }
18249
18250                 // Make sure all resources in our process are updated
18251                 // right now, so that anyone who is going to retrieve
18252                 // resource values after we return will be sure to get
18253                 // the new ones.  This is especially important during
18254                 // boot, where the first config change needs to guarantee
18255                 // all resources have that config before following boot
18256                 // code is executed.
18257                 mSystemThread.applyConfigurationToResources(configCopy);
18258
18259                 if (persistent && Settings.System.hasInterestingConfigurationChanges(changes)) {
18260                     Message msg = mHandler.obtainMessage(UPDATE_CONFIGURATION_MSG);
18261                     msg.obj = new Configuration(configCopy);
18262                     msg.arg1 = userId;
18263                     mHandler.sendMessage(msg);
18264                 }
18265
18266                 final boolean isDensityChange = (changes & ActivityInfo.CONFIG_DENSITY) != 0;
18267                 if (isDensityChange) {
18268                     killAllBackgroundProcessesExcept(Build.VERSION_CODES.N,
18269                             ActivityManager.PROCESS_STATE_FOREGROUND_SERVICE);
18270                 }
18271
18272                 for (int i=mLruProcesses.size()-1; i>=0; i--) {
18273                     ProcessRecord app = mLruProcesses.get(i);
18274                     try {
18275                         if (app.thread != null) {
18276                             if (DEBUG_CONFIGURATION) Slog.v(TAG_CONFIGURATION, "Sending to proc "
18277                                     + app.processName + " new config " + mConfiguration);
18278                             app.thread.scheduleConfigurationChanged(configCopy);
18279                         }
18280                     } catch (Exception e) {
18281                     }
18282                 }
18283                 Intent intent = new Intent(Intent.ACTION_CONFIGURATION_CHANGED);
18284                 intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY
18285                         | Intent.FLAG_RECEIVER_REPLACE_PENDING
18286                         | Intent.FLAG_RECEIVER_FOREGROUND);
18287                 broadcastIntentLocked(null, null, intent, null, null, 0, null, null,
18288                         null, AppOpsManager.OP_NONE, null, false, false,
18289                         MY_PID, Process.SYSTEM_UID, UserHandle.USER_ALL);
18290                 if ((changes&ActivityInfo.CONFIG_LOCALE) != 0) {
18291                     intent = new Intent(Intent.ACTION_LOCALE_CHANGED);
18292                     intent.addFlags(Intent.FLAG_RECEIVER_FOREGROUND);
18293                     if (!mProcessesReady) {
18294                         intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY);
18295                     }
18296                     broadcastIntentLocked(null, null, intent,
18297                             null, null, 0, null, null, null, AppOpsManager.OP_NONE,
18298                             null, false, false, MY_PID, Process.SYSTEM_UID, UserHandle.USER_ALL);
18299                 }
18300             }
18301         }
18302
18303         boolean kept = true;
18304         final ActivityStack mainStack = mStackSupervisor.getFocusedStack();
18305         // mainStack is null during startup.
18306         if (mainStack != null) {
18307             if (changes != 0 && starting == null) {
18308                 // If the configuration changed, and the caller is not already
18309                 // in the process of starting an activity, then find the top
18310                 // activity to check if its configuration needs to change.
18311                 starting = mainStack.topRunningActivityLocked();
18312             }
18313
18314             if (starting != null) {
18315                 kept = mainStack.ensureActivityConfigurationLocked(starting, changes, false);
18316                 // And we need to make sure at this point that all other activities
18317                 // are made visible with the correct configuration.
18318                 mStackSupervisor.ensureActivitiesVisibleLocked(starting, changes,
18319                         !PRESERVE_WINDOWS);
18320             }
18321         }
18322
18323         if (values != null && mWindowManager != null) {
18324             mWindowManager.setNewConfiguration(mConfiguration);
18325         }
18326
18327         return kept;
18328     }
18329
18330     /**
18331      * Decide based on the configuration whether we should shouw the ANR,
18332      * crash, etc dialogs.  The idea is that if there is no affordnace to
18333      * press the on-screen buttons, we shouldn't show the dialog.
18334      *
18335      * A thought: SystemUI might also want to get told about this, the Power
18336      * dialog / global actions also might want different behaviors.
18337      */
18338     private static final boolean shouldShowDialogs(Configuration config, boolean inVrMode) {
18339         final boolean inputMethodExists = !(config.keyboard == Configuration.KEYBOARD_NOKEYS
18340                                    && config.touchscreen == Configuration.TOUCHSCREEN_NOTOUCH
18341                                    && config.navigation == Configuration.NAVIGATION_NONAV);
18342         final boolean uiIsNotCarType = !((config.uiMode & Configuration.UI_MODE_TYPE_MASK)
18343                                     == Configuration.UI_MODE_TYPE_CAR);
18344         return inputMethodExists && uiIsNotCarType && !inVrMode;
18345     }
18346
18347     @Override
18348     public boolean shouldUpRecreateTask(IBinder token, String destAffinity) {
18349         synchronized (this) {
18350             ActivityRecord srec = ActivityRecord.forTokenLocked(token);
18351             if (srec != null) {
18352                 return srec.task.stack.shouldUpRecreateTaskLocked(srec, destAffinity);
18353             }
18354         }
18355         return false;
18356     }
18357
18358     public boolean navigateUpTo(IBinder token, Intent destIntent, int resultCode,
18359             Intent resultData) {
18360
18361         synchronized (this) {
18362             final ActivityRecord r = ActivityRecord.forTokenLocked(token);
18363             if (r != null) {
18364                 return r.task.stack.navigateUpToLocked(r, destIntent, resultCode, resultData);
18365             }
18366             return false;
18367         }
18368     }
18369
18370     public int getLaunchedFromUid(IBinder activityToken) {
18371         ActivityRecord srec;
18372         synchronized (this) {
18373             srec = ActivityRecord.forTokenLocked(activityToken);
18374         }
18375         if (srec == null) {
18376             return -1;
18377         }
18378         return srec.launchedFromUid;
18379     }
18380
18381     public String getLaunchedFromPackage(IBinder activityToken) {
18382         ActivityRecord srec;
18383         synchronized (this) {
18384             srec = ActivityRecord.forTokenLocked(activityToken);
18385         }
18386         if (srec == null) {
18387             return null;
18388         }
18389         return srec.launchedFromPackage;
18390     }
18391
18392     // =========================================================
18393     // LIFETIME MANAGEMENT
18394     // =========================================================
18395
18396     // Returns which broadcast queue the app is the current [or imminent] receiver
18397     // on, or 'null' if the app is not an active broadcast recipient.
18398     private BroadcastQueue isReceivingBroadcast(ProcessRecord app) {
18399         BroadcastRecord r = app.curReceiver;
18400         if (r != null) {
18401             return r.queue;
18402         }
18403
18404         // It's not the current receiver, but it might be starting up to become one
18405         synchronized (this) {
18406             for (BroadcastQueue queue : mBroadcastQueues) {
18407                 r = queue.mPendingBroadcast;
18408                 if (r != null && r.curApp == app) {
18409                     // found it; report which queue it's in
18410                     return queue;
18411                 }
18412             }
18413         }
18414
18415         return null;
18416     }
18417
18418     Association startAssociationLocked(int sourceUid, String sourceProcess, int targetUid,
18419             ComponentName targetComponent, String targetProcess) {
18420         if (!mTrackingAssociations) {
18421             return null;
18422         }
18423         ArrayMap<ComponentName, SparseArray<ArrayMap<String, Association>>> components
18424                 = mAssociations.get(targetUid);
18425         if (components == null) {
18426             components = new ArrayMap<>();
18427             mAssociations.put(targetUid, components);
18428         }
18429         SparseArray<ArrayMap<String, Association>> sourceUids = components.get(targetComponent);
18430         if (sourceUids == null) {
18431             sourceUids = new SparseArray<>();
18432             components.put(targetComponent, sourceUids);
18433         }
18434         ArrayMap<String, Association> sourceProcesses = sourceUids.get(sourceUid);
18435         if (sourceProcesses == null) {
18436             sourceProcesses = new ArrayMap<>();
18437             sourceUids.put(sourceUid, sourceProcesses);
18438         }
18439         Association ass = sourceProcesses.get(sourceProcess);
18440         if (ass == null) {
18441             ass = new Association(sourceUid, sourceProcess, targetUid, targetComponent,
18442                     targetProcess);
18443             sourceProcesses.put(sourceProcess, ass);
18444         }
18445         ass.mCount++;
18446         ass.mNesting++;
18447         if (ass.mNesting == 1) {
18448             ass.mStartTime = SystemClock.uptimeMillis();
18449         }
18450         return ass;
18451     }
18452
18453     void stopAssociationLocked(int sourceUid, String sourceProcess, int targetUid,
18454             ComponentName targetComponent) {
18455         if (!mTrackingAssociations) {
18456             return;
18457         }
18458         ArrayMap<ComponentName, SparseArray<ArrayMap<String, Association>>> components
18459                 = mAssociations.get(targetUid);
18460         if (components == null) {
18461             return;
18462         }
18463         SparseArray<ArrayMap<String, Association>> sourceUids = components.get(targetComponent);
18464         if (sourceUids == null) {
18465             return;
18466         }
18467         ArrayMap<String, Association> sourceProcesses = sourceUids.get(sourceUid);
18468         if (sourceProcesses == null) {
18469             return;
18470         }
18471         Association ass = sourceProcesses.get(sourceProcess);
18472         if (ass == null || ass.mNesting <= 0) {
18473             return;
18474         }
18475         ass.mNesting--;
18476         if (ass.mNesting == 0) {
18477             ass.mTime += SystemClock.uptimeMillis() - ass.mStartTime;
18478         }
18479     }
18480
18481     private final int computeOomAdjLocked(ProcessRecord app, int cachedAdj, ProcessRecord TOP_APP,
18482             boolean doingAll, long now) {
18483         if (mAdjSeq == app.adjSeq) {
18484             // This adjustment has already been computed.
18485             return app.curRawAdj;
18486         }
18487
18488         if (app.thread == null) {
18489             app.adjSeq = mAdjSeq;
18490             app.curSchedGroup = ProcessList.SCHED_GROUP_BACKGROUND;
18491             app.curProcState = ActivityManager.PROCESS_STATE_CACHED_EMPTY;
18492             return (app.curAdj=app.curRawAdj=ProcessList.CACHED_APP_MAX_ADJ);
18493         }
18494
18495         app.adjTypeCode = ActivityManager.RunningAppProcessInfo.REASON_UNKNOWN;
18496         app.adjSource = null;
18497         app.adjTarget = null;
18498         app.empty = false;
18499         app.cached = false;
18500
18501         final int activitiesSize = app.activities.size();
18502
18503         if (app.maxAdj <= ProcessList.FOREGROUND_APP_ADJ) {
18504             // The max adjustment doesn't allow this app to be anything
18505             // below foreground, so it is not worth doing work for it.
18506             app.adjType = "fixed";
18507             app.adjSeq = mAdjSeq;
18508             app.curRawAdj = app.maxAdj;
18509             app.foregroundActivities = false;
18510             app.curSchedGroup = ProcessList.SCHED_GROUP_DEFAULT;
18511             app.curProcState = ActivityManager.PROCESS_STATE_PERSISTENT;
18512             // System processes can do UI, and when they do we want to have
18513             // them trim their memory after the user leaves the UI.  To
18514             // facilitate this, here we need to determine whether or not it
18515             // is currently showing UI.
18516             app.systemNoUi = true;
18517             if (app == TOP_APP) {
18518                 app.systemNoUi = false;
18519             } else if (activitiesSize > 0) {
18520                 for (int j = 0; j < activitiesSize; j++) {
18521                     final ActivityRecord r = app.activities.get(j);
18522                     if (r.visible) {
18523                         app.systemNoUi = false;
18524                     }
18525                 }
18526             }
18527             if (!app.systemNoUi) {
18528                 app.curProcState = ActivityManager.PROCESS_STATE_PERSISTENT_UI;
18529             }
18530             return (app.curAdj=app.maxAdj);
18531         }
18532
18533         app.systemNoUi = false;
18534
18535         final int PROCESS_STATE_CUR_TOP = mTopProcessState;
18536
18537         // Determine the importance of the process, starting with most
18538         // important to least, and assign an appropriate OOM adjustment.
18539         int adj;
18540         int schedGroup;
18541         int procState;
18542         boolean foregroundActivities = false;
18543         BroadcastQueue queue;
18544         if (app == TOP_APP) {
18545             // The last app on the list is the foreground app.
18546             adj = ProcessList.FOREGROUND_APP_ADJ;
18547             schedGroup = ProcessList.SCHED_GROUP_TOP_APP;
18548             app.adjType = "top-activity";
18549             foregroundActivities = true;
18550             procState = PROCESS_STATE_CUR_TOP;
18551         } else if (app.instrumentationClass != null) {
18552             // Don't want to kill running instrumentation.
18553             adj = ProcessList.FOREGROUND_APP_ADJ;
18554             schedGroup = ProcessList.SCHED_GROUP_DEFAULT;
18555             app.adjType = "instrumentation";
18556             procState = ActivityManager.PROCESS_STATE_FOREGROUND_SERVICE;
18557         } else if ((queue = isReceivingBroadcast(app)) != null) {
18558             // An app that is currently receiving a broadcast also
18559             // counts as being in the foreground for OOM killer purposes.
18560             // It's placed in a sched group based on the nature of the
18561             // broadcast as reflected by which queue it's active in.
18562             adj = ProcessList.FOREGROUND_APP_ADJ;
18563             schedGroup = (queue == mFgBroadcastQueue)
18564                     ? ProcessList.SCHED_GROUP_DEFAULT : ProcessList.SCHED_GROUP_BACKGROUND;
18565             app.adjType = "broadcast";
18566             procState = ActivityManager.PROCESS_STATE_RECEIVER;
18567         } else if (app.executingServices.size() > 0) {
18568             // An app that is currently executing a service callback also
18569             // counts as being in the foreground.
18570             adj = ProcessList.FOREGROUND_APP_ADJ;
18571             schedGroup = app.execServicesFg ?
18572                     ProcessList.SCHED_GROUP_DEFAULT : ProcessList.SCHED_GROUP_BACKGROUND;
18573             app.adjType = "exec-service";
18574             procState = ActivityManager.PROCESS_STATE_SERVICE;
18575             //Slog.i(TAG, "EXEC " + (app.execServicesFg ? "FG" : "BG") + ": " + app);
18576         } else {
18577             // As far as we know the process is empty.  We may change our mind later.
18578             schedGroup = ProcessList.SCHED_GROUP_BACKGROUND;
18579             // At this point we don't actually know the adjustment.  Use the cached adj
18580             // value that the caller wants us to.
18581             adj = cachedAdj;
18582             procState = ActivityManager.PROCESS_STATE_CACHED_EMPTY;
18583             app.cached = true;
18584             app.empty = true;
18585             app.adjType = "cch-empty";
18586         }
18587
18588         // Examine all activities if not already foreground.
18589         if (!foregroundActivities && activitiesSize > 0) {
18590             int minLayer = ProcessList.VISIBLE_APP_LAYER_MAX;
18591             for (int j = 0; j < activitiesSize; j++) {
18592                 final ActivityRecord r = app.activities.get(j);
18593                 if (r.app != app) {
18594                     Slog.w(TAG, "Wtf, activity " + r + " in proc activity list not using proc "
18595                             + app + "?!? Using " + r.app + " instead.");
18596                     continue;
18597                 }
18598                 if (r.visible) {
18599                     // App has a visible activity; only upgrade adjustment.
18600                     if (adj > ProcessList.VISIBLE_APP_ADJ) {
18601                         adj = ProcessList.VISIBLE_APP_ADJ;
18602                         app.adjType = "visible";
18603                     }
18604                     if (procState > PROCESS_STATE_CUR_TOP) {
18605                         procState = PROCESS_STATE_CUR_TOP;
18606                     }
18607                     schedGroup = ProcessList.SCHED_GROUP_DEFAULT;
18608                     app.cached = false;
18609                     app.empty = false;
18610                     foregroundActivities = true;
18611                     if (r.task != null && minLayer > 0) {
18612                         final int layer = r.task.mLayerRank;
18613                         if (layer >= 0 && minLayer > layer) {
18614                             minLayer = layer;
18615                         }
18616                     }
18617                     break;
18618                 } else if (r.state == ActivityState.PAUSING || r.state == ActivityState.PAUSED) {
18619                     if (adj > ProcessList.PERCEPTIBLE_APP_ADJ) {
18620                         adj = ProcessList.PERCEPTIBLE_APP_ADJ;
18621                         app.adjType = "pausing";
18622                     }
18623                     if (procState > PROCESS_STATE_CUR_TOP) {
18624                         procState = PROCESS_STATE_CUR_TOP;
18625                     }
18626                     schedGroup = ProcessList.SCHED_GROUP_DEFAULT;
18627                     app.cached = false;
18628                     app.empty = false;
18629                     foregroundActivities = true;
18630                 } else if (r.state == ActivityState.STOPPING) {
18631                     if (adj > ProcessList.PERCEPTIBLE_APP_ADJ) {
18632                         adj = ProcessList.PERCEPTIBLE_APP_ADJ;
18633                         app.adjType = "stopping";
18634                     }
18635                     // For the process state, we will at this point consider the
18636                     // process to be cached.  It will be cached either as an activity
18637                     // or empty depending on whether the activity is finishing.  We do
18638                     // this so that we can treat the process as cached for purposes of
18639                     // memory trimming (determing current memory level, trim command to
18640                     // send to process) since there can be an arbitrary number of stopping
18641                     // processes and they should soon all go into the cached state.
18642                     if (!r.finishing) {
18643                         if (procState > ActivityManager.PROCESS_STATE_LAST_ACTIVITY) {
18644                             procState = ActivityManager.PROCESS_STATE_LAST_ACTIVITY;
18645                         }
18646                     }
18647                     app.cached = false;
18648                     app.empty = false;
18649                     foregroundActivities = true;
18650                 } else {
18651                     if (procState > ActivityManager.PROCESS_STATE_CACHED_ACTIVITY) {
18652                         procState = ActivityManager.PROCESS_STATE_CACHED_ACTIVITY;
18653                         app.adjType = "cch-act";
18654                     }
18655                 }
18656             }
18657             if (adj == ProcessList.VISIBLE_APP_ADJ) {
18658                 adj += minLayer;
18659             }
18660         }
18661
18662         if (adj > ProcessList.PERCEPTIBLE_APP_ADJ
18663                 || procState > ActivityManager.PROCESS_STATE_FOREGROUND_SERVICE) {
18664             if (app.foregroundServices) {
18665                 // The user is aware of this app, so make it visible.
18666                 adj = ProcessList.PERCEPTIBLE_APP_ADJ;
18667                 procState = ActivityManager.PROCESS_STATE_FOREGROUND_SERVICE;
18668                 app.cached = false;
18669                 app.adjType = "fg-service";
18670                 schedGroup = ProcessList.SCHED_GROUP_DEFAULT;
18671             } else if (app.forcingToForeground != null) {
18672                 // The user is aware of this app, so make it visible.
18673                 adj = ProcessList.PERCEPTIBLE_APP_ADJ;
18674                 procState = ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND;
18675                 app.cached = false;
18676                 app.adjType = "force-fg";
18677                 app.adjSource = app.forcingToForeground;
18678                 schedGroup = ProcessList.SCHED_GROUP_DEFAULT;
18679             }
18680         }
18681
18682         if (app == mHeavyWeightProcess) {
18683             if (adj > ProcessList.HEAVY_WEIGHT_APP_ADJ) {
18684                 // We don't want to kill the current heavy-weight process.
18685                 adj = ProcessList.HEAVY_WEIGHT_APP_ADJ;
18686                 schedGroup = ProcessList.SCHED_GROUP_BACKGROUND;
18687                 app.cached = false;
18688                 app.adjType = "heavy";
18689             }
18690             if (procState > ActivityManager.PROCESS_STATE_HEAVY_WEIGHT) {
18691                 procState = ActivityManager.PROCESS_STATE_HEAVY_WEIGHT;
18692             }
18693         }
18694
18695         if (app == mHomeProcess) {
18696             if (adj > ProcessList.HOME_APP_ADJ) {
18697                 // This process is hosting what we currently consider to be the
18698                 // home app, so we don't want to let it go into the background.
18699                 adj = ProcessList.HOME_APP_ADJ;
18700                 schedGroup = ProcessList.SCHED_GROUP_BACKGROUND;
18701                 app.cached = false;
18702                 app.adjType = "home";
18703             }
18704             if (procState > ActivityManager.PROCESS_STATE_HOME) {
18705                 procState = ActivityManager.PROCESS_STATE_HOME;
18706             }
18707         }
18708
18709         if (app == mPreviousProcess && app.activities.size() > 0) {
18710             if (adj > ProcessList.PREVIOUS_APP_ADJ) {
18711                 // This was the previous process that showed UI to the user.
18712                 // We want to try to keep it around more aggressively, to give
18713                 // a good experience around switching between two apps.
18714                 adj = ProcessList.PREVIOUS_APP_ADJ;
18715                 schedGroup = ProcessList.SCHED_GROUP_BACKGROUND;
18716                 app.cached = false;
18717                 app.adjType = "previous";
18718             }
18719             if (procState > ActivityManager.PROCESS_STATE_LAST_ACTIVITY) {
18720                 procState = ActivityManager.PROCESS_STATE_LAST_ACTIVITY;
18721             }
18722         }
18723
18724         if (false) Slog.i(TAG, "OOM " + app + ": initial adj=" + adj
18725                 + " reason=" + app.adjType);
18726
18727         // By default, we use the computed adjustment.  It may be changed if
18728         // there are applications dependent on our services or providers, but
18729         // this gives us a baseline and makes sure we don't get into an
18730         // infinite recursion.
18731         app.adjSeq = mAdjSeq;
18732         app.curRawAdj = adj;
18733         app.hasStartedServices = false;
18734
18735         if (mBackupTarget != null && app == mBackupTarget.app) {
18736             // If possible we want to avoid killing apps while they're being backed up
18737             if (adj > ProcessList.BACKUP_APP_ADJ) {
18738                 if (DEBUG_BACKUP) Slog.v(TAG_BACKUP, "oom BACKUP_APP_ADJ for " + app);
18739                 adj = ProcessList.BACKUP_APP_ADJ;
18740                 if (procState > ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND) {
18741                     procState = ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND;
18742                 }
18743                 app.adjType = "backup";
18744                 app.cached = false;
18745             }
18746             if (procState > ActivityManager.PROCESS_STATE_BACKUP) {
18747                 procState = ActivityManager.PROCESS_STATE_BACKUP;
18748             }
18749         }
18750
18751         boolean mayBeTop = false;
18752
18753         for (int is = app.services.size()-1;
18754                 is >= 0 && (adj > ProcessList.FOREGROUND_APP_ADJ
18755                         || schedGroup == ProcessList.SCHED_GROUP_BACKGROUND
18756                         || procState > ActivityManager.PROCESS_STATE_TOP);
18757                 is--) {
18758             ServiceRecord s = app.services.valueAt(is);
18759             if (s.startRequested) {
18760                 app.hasStartedServices = true;
18761                 if (procState > ActivityManager.PROCESS_STATE_SERVICE) {
18762                     procState = ActivityManager.PROCESS_STATE_SERVICE;
18763                 }
18764                 if (app.hasShownUi && app != mHomeProcess) {
18765                     // If this process has shown some UI, let it immediately
18766                     // go to the LRU list because it may be pretty heavy with
18767                     // UI stuff.  We'll tag it with a label just to help
18768                     // debug and understand what is going on.
18769                     if (adj > ProcessList.SERVICE_ADJ) {
18770                         app.adjType = "cch-started-ui-services";
18771                     }
18772                 } else {
18773                     if (now < (s.lastActivity + ActiveServices.MAX_SERVICE_INACTIVITY)) {
18774                         // This service has seen some activity within
18775                         // recent memory, so we will keep its process ahead
18776                         // of the background processes.
18777                         if (adj > ProcessList.SERVICE_ADJ) {
18778                             adj = ProcessList.SERVICE_ADJ;
18779                             app.adjType = "started-services";
18780                             app.cached = false;
18781                         }
18782                     }
18783                     // If we have let the service slide into the background
18784                     // state, still have some text describing what it is doing
18785                     // even though the service no longer has an impact.
18786                     if (adj > ProcessList.SERVICE_ADJ) {
18787                         app.adjType = "cch-started-services";
18788                     }
18789                 }
18790             }
18791             for (int conni = s.connections.size()-1;
18792                     conni >= 0 && (adj > ProcessList.FOREGROUND_APP_ADJ
18793                             || schedGroup == ProcessList.SCHED_GROUP_BACKGROUND
18794                             || procState > ActivityManager.PROCESS_STATE_TOP);
18795                     conni--) {
18796                 ArrayList<ConnectionRecord> clist = s.connections.valueAt(conni);
18797                 for (int i = 0;
18798                         i < clist.size() && (adj > ProcessList.FOREGROUND_APP_ADJ
18799                                 || schedGroup == ProcessList.SCHED_GROUP_BACKGROUND
18800                                 || procState > ActivityManager.PROCESS_STATE_TOP);
18801                         i++) {
18802                     // XXX should compute this based on the max of
18803                     // all connected clients.
18804                     ConnectionRecord cr = clist.get(i);
18805                     if (cr.binding.client == app) {
18806                         // Binding to ourself is not interesting.
18807                         continue;
18808                     }
18809                     if ((cr.flags&Context.BIND_WAIVE_PRIORITY) == 0) {
18810                         ProcessRecord client = cr.binding.client;
18811                         int clientAdj = computeOomAdjLocked(client, cachedAdj,
18812                                 TOP_APP, doingAll, now);
18813                         int clientProcState = client.curProcState;
18814                         if (clientProcState >= ActivityManager.PROCESS_STATE_CACHED_ACTIVITY) {
18815                             // If the other app is cached for any reason, for purposes here
18816                             // we are going to consider it empty.  The specific cached state
18817                             // doesn't propagate except under certain conditions.
18818                             clientProcState = ActivityManager.PROCESS_STATE_CACHED_EMPTY;
18819                         }
18820                         String adjType = null;
18821                         if ((cr.flags&Context.BIND_ALLOW_OOM_MANAGEMENT) != 0) {
18822                             // Not doing bind OOM management, so treat
18823                             // this guy more like a started service.
18824                             if (app.hasShownUi && app != mHomeProcess) {
18825                                 // If this process has shown some UI, let it immediately
18826                                 // go to the LRU list because it may be pretty heavy with
18827                                 // UI stuff.  We'll tag it with a label just to help
18828                                 // debug and understand what is going on.
18829                                 if (adj > clientAdj) {
18830                                     adjType = "cch-bound-ui-services";
18831                                 }
18832                                 app.cached = false;
18833                                 clientAdj = adj;
18834                                 clientProcState = procState;
18835                             } else {
18836                                 if (now >= (s.lastActivity
18837                                         + ActiveServices.MAX_SERVICE_INACTIVITY)) {
18838                                     // This service has not seen activity within
18839                                     // recent memory, so allow it to drop to the
18840                                     // LRU list if there is no other reason to keep
18841                                     // it around.  We'll also tag it with a label just
18842                                     // to help debug and undertand what is going on.
18843                                     if (adj > clientAdj) {
18844                                         adjType = "cch-bound-services";
18845                                     }
18846                                     clientAdj = adj;
18847                                 }
18848                             }
18849                         }
18850                         if (adj > clientAdj) {
18851                             // If this process has recently shown UI, and
18852                             // the process that is binding to it is less
18853                             // important than being visible, then we don't
18854                             // care about the binding as much as we care
18855                             // about letting this process get into the LRU
18856                             // list to be killed and restarted if needed for
18857                             // memory.
18858                             if (app.hasShownUi && app != mHomeProcess
18859                                     && clientAdj > ProcessList.PERCEPTIBLE_APP_ADJ) {
18860                                 adjType = "cch-bound-ui-services";
18861                             } else {
18862                                 if ((cr.flags&(Context.BIND_ABOVE_CLIENT
18863                                         |Context.BIND_IMPORTANT)) != 0) {
18864                                     adj = clientAdj >= ProcessList.PERSISTENT_SERVICE_ADJ
18865                                             ? clientAdj : ProcessList.PERSISTENT_SERVICE_ADJ;
18866                                 } else if ((cr.flags&Context.BIND_NOT_VISIBLE) != 0
18867                                         && clientAdj < ProcessList.PERCEPTIBLE_APP_ADJ
18868                                         && adj > ProcessList.PERCEPTIBLE_APP_ADJ) {
18869                                     adj = ProcessList.PERCEPTIBLE_APP_ADJ;
18870                                 } else if (clientAdj >= ProcessList.PERCEPTIBLE_APP_ADJ) {
18871                                     adj = clientAdj;
18872                                 } else {
18873                                     if (adj > ProcessList.VISIBLE_APP_ADJ) {
18874                                         adj = Math.max(clientAdj, ProcessList.VISIBLE_APP_ADJ);
18875                                     }
18876                                 }
18877                                 if (!client.cached) {
18878                                     app.cached = false;
18879                                 }
18880                                 adjType = "service";
18881                             }
18882                         }
18883                         if ((cr.flags&Context.BIND_NOT_FOREGROUND) == 0) {
18884                             // This will treat important bound services identically to
18885                             // the top app, which may behave differently than generic
18886                             // foreground work.
18887                             if (client.curSchedGroup > schedGroup) {
18888                                 if ((cr.flags&Context.BIND_IMPORTANT) != 0) {
18889                                     schedGroup = client.curSchedGroup;
18890                                 } else {
18891                                     schedGroup = ProcessList.SCHED_GROUP_DEFAULT;
18892                                 }
18893                             }
18894                             if (clientProcState <= ActivityManager.PROCESS_STATE_TOP) {
18895                                 if (clientProcState == ActivityManager.PROCESS_STATE_TOP) {
18896                                     // Special handling of clients who are in the top state.
18897                                     // We *may* want to consider this process to be in the
18898                                     // top state as well, but only if there is not another
18899                                     // reason for it to be running.  Being on the top is a
18900                                     // special state, meaning you are specifically running
18901                                     // for the current top app.  If the process is already
18902                                     // running in the background for some other reason, it
18903                                     // is more important to continue considering it to be
18904                                     // in the background state.
18905                                     mayBeTop = true;
18906                                     clientProcState = ActivityManager.PROCESS_STATE_CACHED_EMPTY;
18907                                 } else {
18908                                     // Special handling for above-top states (persistent
18909                                     // processes).  These should not bring the current process
18910                                     // into the top state, since they are not on top.  Instead
18911                                     // give them the best state after that.
18912                                     if ((cr.flags&Context.BIND_FOREGROUND_SERVICE) != 0) {
18913                                         clientProcState =
18914                                                 ActivityManager.PROCESS_STATE_BOUND_FOREGROUND_SERVICE;
18915                                     } else if (mWakefulness
18916                                                     == PowerManagerInternal.WAKEFULNESS_AWAKE &&
18917                                             (cr.flags&Context.BIND_FOREGROUND_SERVICE_WHILE_AWAKE)
18918                                                     != 0) {
18919                                         clientProcState =
18920                                                 ActivityManager.PROCESS_STATE_BOUND_FOREGROUND_SERVICE;
18921                                     } else {
18922                                         clientProcState =
18923                                                 ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND;
18924                                     }
18925                                 }
18926                             }
18927                         } else {
18928                             if (clientProcState <
18929                                     ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND) {
18930                                 clientProcState =
18931                                         ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND;
18932                             }
18933                         }
18934                         if (procState > clientProcState) {
18935                             procState = clientProcState;
18936                         }
18937                         if (procState < ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND
18938                                 && (cr.flags&Context.BIND_SHOWING_UI) != 0) {
18939                             app.pendingUiClean = true;
18940                         }
18941                         if (adjType != null) {
18942                             app.adjType = adjType;
18943                             app.adjTypeCode = ActivityManager.RunningAppProcessInfo
18944                                     .REASON_SERVICE_IN_USE;
18945                             app.adjSource = cr.binding.client;
18946                             app.adjSourceProcState = clientProcState;
18947                             app.adjTarget = s.name;
18948                         }
18949                     }
18950                     if ((cr.flags&Context.BIND_TREAT_LIKE_ACTIVITY) != 0) {
18951                         app.treatLikeActivity = true;
18952                     }
18953                     final ActivityRecord a = cr.activity;
18954                     if ((cr.flags&Context.BIND_ADJUST_WITH_ACTIVITY) != 0) {
18955                         if (a != null && adj > ProcessList.FOREGROUND_APP_ADJ &&
18956                             (a.visible || a.state == ActivityState.RESUMED ||
18957                              a.state == ActivityState.PAUSING)) {
18958                             adj = ProcessList.FOREGROUND_APP_ADJ;
18959                             if ((cr.flags&Context.BIND_NOT_FOREGROUND) == 0) {
18960                                 if ((cr.flags&Context.BIND_IMPORTANT) != 0) {
18961                                     schedGroup = ProcessList.SCHED_GROUP_TOP_APP;
18962                                 } else {
18963                                     schedGroup = ProcessList.SCHED_GROUP_DEFAULT;
18964                                 }
18965                             }
18966                             app.cached = false;
18967                             app.adjType = "service";
18968                             app.adjTypeCode = ActivityManager.RunningAppProcessInfo
18969                                     .REASON_SERVICE_IN_USE;
18970                             app.adjSource = a;
18971                             app.adjSourceProcState = procState;
18972                             app.adjTarget = s.name;
18973                         }
18974                     }
18975                 }
18976             }
18977         }
18978
18979         for (int provi = app.pubProviders.size()-1;
18980                 provi >= 0 && (adj > ProcessList.FOREGROUND_APP_ADJ
18981                         || schedGroup == ProcessList.SCHED_GROUP_BACKGROUND
18982                         || procState > ActivityManager.PROCESS_STATE_TOP);
18983                 provi--) {
18984             ContentProviderRecord cpr = app.pubProviders.valueAt(provi);
18985             for (int i = cpr.connections.size()-1;
18986                     i >= 0 && (adj > ProcessList.FOREGROUND_APP_ADJ
18987                             || schedGroup == ProcessList.SCHED_GROUP_BACKGROUND
18988                             || procState > ActivityManager.PROCESS_STATE_TOP);
18989                     i--) {
18990                 ContentProviderConnection conn = cpr.connections.get(i);
18991                 ProcessRecord client = conn.client;
18992                 if (client == app) {
18993                     // Being our own client is not interesting.
18994                     continue;
18995                 }
18996                 int clientAdj = computeOomAdjLocked(client, cachedAdj, TOP_APP, doingAll, now);
18997                 int clientProcState = client.curProcState;
18998                 if (clientProcState >= ActivityManager.PROCESS_STATE_CACHED_ACTIVITY) {
18999                     // If the other app is cached for any reason, for purposes here
19000                     // we are going to consider it empty.
19001                     clientProcState = ActivityManager.PROCESS_STATE_CACHED_EMPTY;
19002                 }
19003                 if (adj > clientAdj) {
19004                     if (app.hasShownUi && app != mHomeProcess
19005                             && clientAdj > ProcessList.PERCEPTIBLE_APP_ADJ) {
19006                         app.adjType = "cch-ui-provider";
19007                     } else {
19008                         adj = clientAdj > ProcessList.FOREGROUND_APP_ADJ
19009                                 ? clientAdj : ProcessList.FOREGROUND_APP_ADJ;
19010                         app.adjType = "provider";
19011                     }
19012                     app.cached &= client.cached;
19013                     app.adjTypeCode = ActivityManager.RunningAppProcessInfo
19014                             .REASON_PROVIDER_IN_USE;
19015                     app.adjSource = client;
19016                     app.adjSourceProcState = clientProcState;
19017                     app.adjTarget = cpr.name;
19018                 }
19019                 if (clientProcState <= ActivityManager.PROCESS_STATE_TOP) {
19020                     if (clientProcState == ActivityManager.PROCESS_STATE_TOP) {
19021                         // Special handling of clients who are in the top state.
19022                         // We *may* want to consider this process to be in the
19023                         // top state as well, but only if there is not another
19024                         // reason for it to be running.  Being on the top is a
19025                         // special state, meaning you are specifically running
19026                         // for the current top app.  If the process is already
19027                         // running in the background for some other reason, it
19028                         // is more important to continue considering it to be
19029                         // in the background state.
19030                         mayBeTop = true;
19031                         clientProcState = ActivityManager.PROCESS_STATE_CACHED_EMPTY;
19032                     } else {
19033                         // Special handling for above-top states (persistent
19034                         // processes).  These should not bring the current process
19035                         // into the top state, since they are not on top.  Instead
19036                         // give them the best state after that.
19037                         clientProcState =
19038                                 ActivityManager.PROCESS_STATE_BOUND_FOREGROUND_SERVICE;
19039                     }
19040                 }
19041                 if (procState > clientProcState) {
19042                     procState = clientProcState;
19043                 }
19044                 if (client.curSchedGroup > schedGroup) {
19045                     schedGroup = ProcessList.SCHED_GROUP_DEFAULT;
19046                 }
19047             }
19048             // If the provider has external (non-framework) process
19049             // dependencies, ensure that its adjustment is at least
19050             // FOREGROUND_APP_ADJ.
19051             if (cpr.hasExternalProcessHandles()) {
19052                 if (adj > ProcessList.FOREGROUND_APP_ADJ) {
19053                     adj = ProcessList.FOREGROUND_APP_ADJ;
19054                     schedGroup = ProcessList.SCHED_GROUP_DEFAULT;
19055                     app.cached = false;
19056                     app.adjType = "provider";
19057                     app.adjTarget = cpr.name;
19058                 }
19059                 if (procState > ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND) {
19060                     procState = ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND;
19061                 }
19062             }
19063         }
19064
19065         if (app.lastProviderTime > 0 && (app.lastProviderTime+CONTENT_PROVIDER_RETAIN_TIME) > now) {
19066             if (adj > ProcessList.PREVIOUS_APP_ADJ) {
19067                 adj = ProcessList.PREVIOUS_APP_ADJ;
19068                 schedGroup = ProcessList.SCHED_GROUP_BACKGROUND;
19069                 app.cached = false;
19070                 app.adjType = "provider";
19071             }
19072             if (procState > ActivityManager.PROCESS_STATE_LAST_ACTIVITY) {
19073                 procState = ActivityManager.PROCESS_STATE_LAST_ACTIVITY;
19074             }
19075         }
19076
19077         if (mayBeTop && procState > ActivityManager.PROCESS_STATE_TOP) {
19078             // A client of one of our services or providers is in the top state.  We
19079             // *may* want to be in the top state, but not if we are already running in
19080             // the background for some other reason.  For the decision here, we are going
19081             // to pick out a few specific states that we want to remain in when a client
19082             // is top (states that tend to be longer-term) and otherwise allow it to go
19083             // to the top state.
19084             switch (procState) {
19085                 case ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND:
19086                 case ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND:
19087                 case ActivityManager.PROCESS_STATE_SERVICE:
19088                     // These all are longer-term states, so pull them up to the top
19089                     // of the background states, but not all the way to the top state.
19090                     procState = ActivityManager.PROCESS_STATE_BOUND_FOREGROUND_SERVICE;
19091                     break;
19092                 default:
19093                     // Otherwise, top is a better choice, so take it.
19094                     procState = ActivityManager.PROCESS_STATE_TOP;
19095                     break;
19096             }
19097         }
19098
19099         if (procState >= ActivityManager.PROCESS_STATE_CACHED_EMPTY) {
19100             if (app.hasClientActivities) {
19101                 // This is a cached process, but with client activities.  Mark it so.
19102                 procState = ActivityManager.PROCESS_STATE_CACHED_ACTIVITY_CLIENT;
19103                 app.adjType = "cch-client-act";
19104             } else if (app.treatLikeActivity) {
19105                 // This is a cached process, but somebody wants us to treat it like it has
19106                 // an activity, okay!
19107                 procState = ActivityManager.PROCESS_STATE_CACHED_ACTIVITY;
19108                 app.adjType = "cch-as-act";
19109             }
19110         }
19111
19112         if (adj == ProcessList.SERVICE_ADJ) {
19113             if (doingAll) {
19114                 app.serviceb = mNewNumAServiceProcs > (mNumServiceProcs/3);
19115                 mNewNumServiceProcs++;
19116                 //Slog.i(TAG, "ADJ " + app + " serviceb=" + app.serviceb);
19117                 if (!app.serviceb) {
19118                     // This service isn't far enough down on the LRU list to
19119                     // normally be a B service, but if we are low on RAM and it
19120                     // is large we want to force it down since we would prefer to
19121                     // keep launcher over it.
19122                     if (mLastMemoryLevel > ProcessStats.ADJ_MEM_FACTOR_NORMAL
19123                             && app.lastPss >= mProcessList.getCachedRestoreThresholdKb()) {
19124                         app.serviceHighRam = true;
19125                         app.serviceb = true;
19126                         //Slog.i(TAG, "ADJ " + app + " high ram!");
19127                     } else {
19128                         mNewNumAServiceProcs++;
19129                         //Slog.i(TAG, "ADJ " + app + " not high ram!");
19130                     }
19131                 } else {
19132                     app.serviceHighRam = false;
19133                 }
19134             }
19135             if (app.serviceb) {
19136                 adj = ProcessList.SERVICE_B_ADJ;
19137             }
19138         }
19139
19140         app.curRawAdj = adj;
19141
19142         //Slog.i(TAG, "OOM ADJ " + app + ": pid=" + app.pid +
19143         //      " adj=" + adj + " curAdj=" + app.curAdj + " maxAdj=" + app.maxAdj);
19144         if (adj > app.maxAdj) {
19145             adj = app.maxAdj;
19146             if (app.maxAdj <= ProcessList.PERCEPTIBLE_APP_ADJ) {
19147                 schedGroup = ProcessList.SCHED_GROUP_DEFAULT;
19148             }
19149         }
19150
19151         // Do final modification to adj.  Everything we do between here and applying
19152         // the final setAdj must be done in this function, because we will also use
19153         // it when computing the final cached adj later.  Note that we don't need to
19154         // worry about this for max adj above, since max adj will always be used to
19155         // keep it out of the cached vaues.
19156         app.curAdj = app.modifyRawOomAdj(adj);
19157         app.curSchedGroup = schedGroup;
19158         app.curProcState = procState;
19159         app.foregroundActivities = foregroundActivities;
19160
19161         return app.curRawAdj;
19162     }
19163
19164     /**
19165      * Record new PSS sample for a process.
19166      */
19167     void recordPssSampleLocked(ProcessRecord proc, int procState, long pss, long uss, long swapPss,
19168             long now) {
19169         EventLogTags.writeAmPss(proc.pid, proc.uid, proc.processName, pss * 1024, uss * 1024,
19170                 swapPss * 1024);
19171         proc.lastPssTime = now;
19172         proc.baseProcessTracker.addPss(pss, uss, true, proc.pkgList);
19173         if (DEBUG_PSS) Slog.d(TAG_PSS,
19174                 "PSS of " + proc.toShortString() + ": " + pss + " lastPss=" + proc.lastPss
19175                 + " state=" + ProcessList.makeProcStateString(procState));
19176         if (proc.initialIdlePss == 0) {
19177             proc.initialIdlePss = pss;
19178         }
19179         proc.lastPss = pss;
19180         proc.lastSwapPss = swapPss;
19181         if (procState >= ActivityManager.PROCESS_STATE_HOME) {
19182             proc.lastCachedPss = pss;
19183             proc.lastCachedSwapPss = swapPss;
19184         }
19185
19186         final SparseArray<Pair<Long, String>> watchUids
19187                 = mMemWatchProcesses.getMap().get(proc.processName);
19188         Long check = null;
19189         if (watchUids != null) {
19190             Pair<Long, String> val = watchUids.get(proc.uid);
19191             if (val == null) {
19192                 val = watchUids.get(0);
19193             }
19194             if (val != null) {
19195                 check = val.first;
19196             }
19197         }
19198         if (check != null) {
19199             if ((pss * 1024) >= check && proc.thread != null && mMemWatchDumpProcName == null) {
19200                 boolean isDebuggable = "1".equals(SystemProperties.get(SYSTEM_DEBUGGABLE, "0"));
19201                 if (!isDebuggable) {
19202                     if ((proc.info.flags&ApplicationInfo.FLAG_DEBUGGABLE) != 0) {
19203                         isDebuggable = true;
19204                     }
19205                 }
19206                 if (isDebuggable) {
19207                     Slog.w(TAG, "Process " + proc + " exceeded pss limit " + check + "; reporting");
19208                     final ProcessRecord myProc = proc;
19209                     final File heapdumpFile = DumpHeapProvider.getJavaFile();
19210                     mMemWatchDumpProcName = proc.processName;
19211                     mMemWatchDumpFile = heapdumpFile.toString();
19212                     mMemWatchDumpPid = proc.pid;
19213                     mMemWatchDumpUid = proc.uid;
19214                     BackgroundThread.getHandler().post(new Runnable() {
19215                         @Override
19216                         public void run() {
19217                             revokeUriPermission(ActivityThread.currentActivityThread()
19218                                             .getApplicationThread(),
19219                                     DumpHeapActivity.JAVA_URI,
19220                                     Intent.FLAG_GRANT_READ_URI_PERMISSION
19221                                             | Intent.FLAG_GRANT_WRITE_URI_PERMISSION,
19222                                     UserHandle.myUserId());
19223                             ParcelFileDescriptor fd = null;
19224                             try {
19225                                 heapdumpFile.delete();
19226                                 fd = ParcelFileDescriptor.open(heapdumpFile,
19227                                         ParcelFileDescriptor.MODE_CREATE |
19228                                                 ParcelFileDescriptor.MODE_TRUNCATE |
19229                                                 ParcelFileDescriptor.MODE_WRITE_ONLY |
19230                                                 ParcelFileDescriptor.MODE_APPEND);
19231                                 IApplicationThread thread = myProc.thread;
19232                                 if (thread != null) {
19233                                     try {
19234                                         if (DEBUG_PSS) Slog.d(TAG_PSS,
19235                                                 "Requesting dump heap from "
19236                                                 + myProc + " to " + heapdumpFile);
19237                                         thread.dumpHeap(true, heapdumpFile.toString(), fd);
19238                                     } catch (RemoteException e) {
19239                                     }
19240                                 }
19241                             } catch (FileNotFoundException e) {
19242                                 e.printStackTrace();
19243                             } finally {
19244                                 if (fd != null) {
19245                                     try {
19246                                         fd.close();
19247                                     } catch (IOException e) {
19248                                     }
19249                                 }
19250                             }
19251                         }
19252                     });
19253                 } else {
19254                     Slog.w(TAG, "Process " + proc + " exceeded pss limit " + check
19255                             + ", but debugging not enabled");
19256                 }
19257             }
19258         }
19259     }
19260
19261     /**
19262      * Schedule PSS collection of a process.
19263      */
19264     void requestPssLocked(ProcessRecord proc, int procState) {
19265         if (mPendingPssProcesses.contains(proc)) {
19266             return;
19267         }
19268         if (mPendingPssProcesses.size() == 0) {
19269             mBgHandler.sendEmptyMessage(COLLECT_PSS_BG_MSG);
19270         }
19271         if (DEBUG_PSS) Slog.d(TAG_PSS, "Requesting PSS of: " + proc);
19272         proc.pssProcState = procState;
19273         mPendingPssProcesses.add(proc);
19274     }
19275
19276     /**
19277      * Schedule PSS collection of all processes.
19278      */
19279     void requestPssAllProcsLocked(long now, boolean always, boolean memLowered) {
19280         if (!always) {
19281             if (now < (mLastFullPssTime +
19282                     (memLowered ? FULL_PSS_LOWERED_INTERVAL : FULL_PSS_MIN_INTERVAL))) {
19283                 return;
19284             }
19285         }
19286         if (DEBUG_PSS) Slog.d(TAG_PSS, "Requesting PSS of all procs!  memLowered=" + memLowered);
19287         mLastFullPssTime = now;
19288         mFullPssPending = true;
19289         mPendingPssProcesses.ensureCapacity(mLruProcesses.size());
19290         mPendingPssProcesses.clear();
19291         for (int i = mLruProcesses.size() - 1; i >= 0; i--) {
19292             ProcessRecord app = mLruProcesses.get(i);
19293             if (app.thread == null
19294                     || app.curProcState == ActivityManager.PROCESS_STATE_NONEXISTENT) {
19295                 continue;
19296             }
19297             if (memLowered || now > (app.lastStateTime+ProcessList.PSS_ALL_INTERVAL)) {
19298                 app.pssProcState = app.setProcState;
19299                 app.nextPssTime = ProcessList.computeNextPssTime(app.curProcState, true,
19300                         mTestPssMode, isSleeping(), now);
19301                 mPendingPssProcesses.add(app);
19302             }
19303         }
19304         mBgHandler.sendEmptyMessage(COLLECT_PSS_BG_MSG);
19305     }
19306
19307     public void setTestPssMode(boolean enabled) {
19308         synchronized (this) {
19309             mTestPssMode = enabled;
19310             if (enabled) {
19311                 // Whenever we enable the mode, we want to take a snapshot all of current
19312                 // process mem use.
19313                 requestPssAllProcsLocked(SystemClock.uptimeMillis(), true, true);
19314             }
19315         }
19316     }
19317
19318     /**
19319      * Ask a given process to GC right now.
19320      */
19321     final void performAppGcLocked(ProcessRecord app) {
19322         try {
19323             app.lastRequestedGc = SystemClock.uptimeMillis();
19324             if (app.thread != null) {
19325                 if (app.reportLowMemory) {
19326                     app.reportLowMemory = false;
19327                     app.thread.scheduleLowMemory();
19328                 } else {
19329                     app.thread.processInBackground();
19330                 }
19331             }
19332         } catch (Exception e) {
19333             // whatever.
19334         }
19335     }
19336
19337     /**
19338      * Returns true if things are idle enough to perform GCs.
19339      */
19340     private final boolean canGcNowLocked() {
19341         boolean processingBroadcasts = false;
19342         for (BroadcastQueue q : mBroadcastQueues) {
19343             if (q.mParallelBroadcasts.size() != 0 || q.mOrderedBroadcasts.size() != 0) {
19344                 processingBroadcasts = true;
19345             }
19346         }
19347         return !processingBroadcasts
19348                 && (isSleeping() || mStackSupervisor.allResumedActivitiesIdle());
19349     }
19350
19351     /**
19352      * Perform GCs on all processes that are waiting for it, but only
19353      * if things are idle.
19354      */
19355     final void performAppGcsLocked() {
19356         final int N = mProcessesToGc.size();
19357         if (N <= 0) {
19358             return;
19359         }
19360         if (canGcNowLocked()) {
19361             while (mProcessesToGc.size() > 0) {
19362                 ProcessRecord proc = mProcessesToGc.remove(0);
19363                 if (proc.curRawAdj > ProcessList.PERCEPTIBLE_APP_ADJ || proc.reportLowMemory) {
19364                     if ((proc.lastRequestedGc+GC_MIN_INTERVAL)
19365                             <= SystemClock.uptimeMillis()) {
19366                         // To avoid spamming the system, we will GC processes one
19367                         // at a time, waiting a few seconds between each.
19368                         performAppGcLocked(proc);
19369                         scheduleAppGcsLocked();
19370                         return;
19371                     } else {
19372                         // It hasn't been long enough since we last GCed this
19373                         // process...  put it in the list to wait for its time.
19374                         addProcessToGcListLocked(proc);
19375                         break;
19376                     }
19377                 }
19378             }
19379
19380             scheduleAppGcsLocked();
19381         }
19382     }
19383
19384     /**
19385      * If all looks good, perform GCs on all processes waiting for them.
19386      */
19387     final void performAppGcsIfAppropriateLocked() {
19388         if (canGcNowLocked()) {
19389             performAppGcsLocked();
19390             return;
19391         }
19392         // Still not idle, wait some more.
19393         scheduleAppGcsLocked();
19394     }
19395
19396     /**
19397      * Schedule the execution of all pending app GCs.
19398      */
19399     final void scheduleAppGcsLocked() {
19400         mHandler.removeMessages(GC_BACKGROUND_PROCESSES_MSG);
19401
19402         if (mProcessesToGc.size() > 0) {
19403             // Schedule a GC for the time to the next process.
19404             ProcessRecord proc = mProcessesToGc.get(0);
19405             Message msg = mHandler.obtainMessage(GC_BACKGROUND_PROCESSES_MSG);
19406
19407             long when = proc.lastRequestedGc + GC_MIN_INTERVAL;
19408             long now = SystemClock.uptimeMillis();
19409             if (when < (now+GC_TIMEOUT)) {
19410                 when = now + GC_TIMEOUT;
19411             }
19412             mHandler.sendMessageAtTime(msg, when);
19413         }
19414     }
19415
19416     /**
19417      * Add a process to the array of processes waiting to be GCed.  Keeps the
19418      * list in sorted order by the last GC time.  The process can't already be
19419      * on the list.
19420      */
19421     final void addProcessToGcListLocked(ProcessRecord proc) {
19422         boolean added = false;
19423         for (int i=mProcessesToGc.size()-1; i>=0; i--) {
19424             if (mProcessesToGc.get(i).lastRequestedGc <
19425                     proc.lastRequestedGc) {
19426                 added = true;
19427                 mProcessesToGc.add(i+1, proc);
19428                 break;
19429             }
19430         }
19431         if (!added) {
19432             mProcessesToGc.add(0, proc);
19433         }
19434     }
19435
19436     /**
19437      * Set up to ask a process to GC itself.  This will either do it
19438      * immediately, or put it on the list of processes to gc the next
19439      * time things are idle.
19440      */
19441     final void scheduleAppGcLocked(ProcessRecord app) {
19442         long now = SystemClock.uptimeMillis();
19443         if ((app.lastRequestedGc+GC_MIN_INTERVAL) > now) {
19444             return;
19445         }
19446         if (!mProcessesToGc.contains(app)) {
19447             addProcessToGcListLocked(app);
19448             scheduleAppGcsLocked();
19449         }
19450     }
19451
19452     final void checkExcessivePowerUsageLocked(boolean doKills) {
19453         updateCpuStatsNow();
19454
19455         BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
19456         boolean doWakeKills = doKills;
19457         boolean doCpuKills = doKills;
19458         if (mLastPowerCheckRealtime == 0) {
19459             doWakeKills = false;
19460         }
19461         if (mLastPowerCheckUptime == 0) {
19462             doCpuKills = false;
19463         }
19464         if (stats.isScreenOn()) {
19465             doWakeKills = false;
19466         }
19467         final long curRealtime = SystemClock.elapsedRealtime();
19468         final long realtimeSince = curRealtime - mLastPowerCheckRealtime;
19469         final long curUptime = SystemClock.uptimeMillis();
19470         final long uptimeSince = curUptime - mLastPowerCheckUptime;
19471         mLastPowerCheckRealtime = curRealtime;
19472         mLastPowerCheckUptime = curUptime;
19473         if (realtimeSince < WAKE_LOCK_MIN_CHECK_DURATION) {
19474             doWakeKills = false;
19475         }
19476         if (uptimeSince < CPU_MIN_CHECK_DURATION) {
19477             doCpuKills = false;
19478         }
19479         int i = mLruProcesses.size();
19480         while (i > 0) {
19481             i--;
19482             ProcessRecord app = mLruProcesses.get(i);
19483             if (app.setProcState >= ActivityManager.PROCESS_STATE_HOME) {
19484                 long wtime;
19485                 synchronized (stats) {
19486                     wtime = stats.getProcessWakeTime(app.info.uid,
19487                             app.pid, curRealtime);
19488                 }
19489                 long wtimeUsed = wtime - app.lastWakeTime;
19490                 long cputimeUsed = app.curCpuTime - app.lastCpuTime;
19491                 if (DEBUG_POWER) {
19492                     StringBuilder sb = new StringBuilder(128);
19493                     sb.append("Wake for ");
19494                     app.toShortString(sb);
19495                     sb.append(": over ");
19496                     TimeUtils.formatDuration(realtimeSince, sb);
19497                     sb.append(" used ");
19498                     TimeUtils.formatDuration(wtimeUsed, sb);
19499                     sb.append(" (");
19500                     sb.append((wtimeUsed*100)/realtimeSince);
19501                     sb.append("%)");
19502                     Slog.i(TAG_POWER, sb.toString());
19503                     sb.setLength(0);
19504                     sb.append("CPU for ");
19505                     app.toShortString(sb);
19506                     sb.append(": over ");
19507                     TimeUtils.formatDuration(uptimeSince, sb);
19508                     sb.append(" used ");
19509                     TimeUtils.formatDuration(cputimeUsed, sb);
19510                     sb.append(" (");
19511                     sb.append((cputimeUsed*100)/uptimeSince);
19512                     sb.append("%)");
19513                     Slog.i(TAG_POWER, sb.toString());
19514                 }
19515                 // If a process has held a wake lock for more
19516                 // than 50% of the time during this period,
19517                 // that sounds bad.  Kill!
19518                 if (doWakeKills && realtimeSince > 0
19519                         && ((wtimeUsed*100)/realtimeSince) >= 50) {
19520                     synchronized (stats) {
19521                         stats.reportExcessiveWakeLocked(app.info.uid, app.processName,
19522                                 realtimeSince, wtimeUsed);
19523                     }
19524                     app.kill("excessive wake held " + wtimeUsed + " during " + realtimeSince, true);
19525                     app.baseProcessTracker.reportExcessiveWake(app.pkgList);
19526                 } else if (doCpuKills && uptimeSince > 0
19527                         && ((cputimeUsed*100)/uptimeSince) >= 25) {
19528                     synchronized (stats) {
19529                         stats.reportExcessiveCpuLocked(app.info.uid, app.processName,
19530                                 uptimeSince, cputimeUsed);
19531                     }
19532                     app.kill("excessive cpu " + cputimeUsed + " during " + uptimeSince, true);
19533                     app.baseProcessTracker.reportExcessiveCpu(app.pkgList);
19534                 } else {
19535                     app.lastWakeTime = wtime;
19536                     app.lastCpuTime = app.curCpuTime;
19537                 }
19538             }
19539         }
19540     }
19541
19542     private final boolean applyOomAdjLocked(ProcessRecord app, boolean doingAll, long now,
19543             long nowElapsed) {
19544         boolean success = true;
19545
19546         if (app.curRawAdj != app.setRawAdj) {
19547             app.setRawAdj = app.curRawAdj;
19548         }
19549
19550         int changes = 0;
19551
19552         if (app.curAdj != app.setAdj) {
19553             ProcessList.setOomAdj(app.pid, app.info.uid, app.curAdj);
19554             if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG_OOM_ADJ,
19555                     "Set " + app.pid + " " + app.processName + " adj " + app.curAdj + ": "
19556                     + app.adjType);
19557             app.setAdj = app.curAdj;
19558         }
19559
19560         if (app.setSchedGroup != app.curSchedGroup) {
19561             app.setSchedGroup = app.curSchedGroup;
19562             if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG_OOM_ADJ,
19563                     "Setting sched group of " + app.processName
19564                     + " to " + app.curSchedGroup);
19565             if (app.waitingToKill != null && app.curReceiver == null
19566                     && app.setSchedGroup == ProcessList.SCHED_GROUP_BACKGROUND) {
19567                 app.kill(app.waitingToKill, true);
19568                 success = false;
19569             } else {
19570                 int processGroup;
19571                 switch (app.curSchedGroup) {
19572                     case ProcessList.SCHED_GROUP_BACKGROUND:
19573                         processGroup = Process.THREAD_GROUP_BG_NONINTERACTIVE;
19574                         break;
19575                     case ProcessList.SCHED_GROUP_TOP_APP:
19576                         processGroup = Process.THREAD_GROUP_TOP_APP;
19577                         break;
19578                     default:
19579                         processGroup = Process.THREAD_GROUP_DEFAULT;
19580                         break;
19581                 }
19582                 if (true) {
19583                     long oldId = Binder.clearCallingIdentity();
19584                     try {
19585                         Process.setProcessGroup(app.pid, processGroup);
19586                     } catch (Exception e) {
19587                         Slog.w(TAG, "Failed setting process group of " + app.pid
19588                                 + " to " + app.curSchedGroup);
19589                         e.printStackTrace();
19590                     } finally {
19591                         Binder.restoreCallingIdentity(oldId);
19592                     }
19593                 } else {
19594                     if (app.thread != null) {
19595                         try {
19596                             app.thread.setSchedulingGroup(processGroup);
19597                         } catch (RemoteException e) {
19598                         }
19599                     }
19600                 }
19601             }
19602         }
19603         if (app.repForegroundActivities != app.foregroundActivities) {
19604             app.repForegroundActivities = app.foregroundActivities;
19605             changes |= ProcessChangeItem.CHANGE_ACTIVITIES;
19606         }
19607         if (app.repProcState != app.curProcState) {
19608             app.repProcState = app.curProcState;
19609             changes |= ProcessChangeItem.CHANGE_PROCESS_STATE;
19610             if (app.thread != null) {
19611                 try {
19612                     if (false) {
19613                         //RuntimeException h = new RuntimeException("here");
19614                         Slog.i(TAG, "Sending new process state " + app.repProcState
19615                                 + " to " + app /*, h*/);
19616                     }
19617                     app.thread.setProcessState(app.repProcState);
19618                 } catch (RemoteException e) {
19619                 }
19620             }
19621         }
19622         if (app.setProcState == ActivityManager.PROCESS_STATE_NONEXISTENT
19623                 || ProcessList.procStatesDifferForMem(app.curProcState, app.setProcState)) {
19624             if (false && mTestPssMode && app.setProcState >= 0 && app.lastStateTime <= (now-200)) {
19625                 // Experimental code to more aggressively collect pss while
19626                 // running test...  the problem is that this tends to collect
19627                 // the data right when a process is transitioning between process
19628                 // states, which well tend to give noisy data.
19629                 long start = SystemClock.uptimeMillis();
19630                 long pss = Debug.getPss(app.pid, mTmpLong, null);
19631                 recordPssSampleLocked(app, app.curProcState, pss, mTmpLong[0], mTmpLong[1], now);
19632                 mPendingPssProcesses.remove(app);
19633                 Slog.i(TAG, "Recorded pss for " + app + " state " + app.setProcState
19634                         + " to " + app.curProcState + ": "
19635                         + (SystemClock.uptimeMillis()-start) + "ms");
19636             }
19637             app.lastStateTime = now;
19638             app.nextPssTime = ProcessList.computeNextPssTime(app.curProcState, true,
19639                     mTestPssMode, isSleeping(), now);
19640             if (DEBUG_PSS) Slog.d(TAG_PSS, "Process state change from "
19641                     + ProcessList.makeProcStateString(app.setProcState) + " to "
19642                     + ProcessList.makeProcStateString(app.curProcState) + " next pss in "
19643                     + (app.nextPssTime-now) + ": " + app);
19644         } else {
19645             if (now > app.nextPssTime || (now > (app.lastPssTime+ProcessList.PSS_MAX_INTERVAL)
19646                     && now > (app.lastStateTime+ProcessList.minTimeFromStateChange(
19647                     mTestPssMode)))) {
19648                 requestPssLocked(app, app.setProcState);
19649                 app.nextPssTime = ProcessList.computeNextPssTime(app.curProcState, false,
19650                         mTestPssMode, isSleeping(), now);
19651             } else if (false && DEBUG_PSS) Slog.d(TAG_PSS,
19652                     "Not requesting PSS of " + app + ": next=" + (app.nextPssTime-now));
19653         }
19654         if (app.setProcState != app.curProcState) {
19655             if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG_OOM_ADJ,
19656                     "Proc state change of " + app.processName
19657                             + " to " + app.curProcState);
19658             boolean setImportant = app.setProcState < ActivityManager.PROCESS_STATE_SERVICE;
19659             boolean curImportant = app.curProcState < ActivityManager.PROCESS_STATE_SERVICE;
19660             if (setImportant && !curImportant) {
19661                 // This app is no longer something we consider important enough to allow to
19662                 // use arbitrary amounts of battery power.  Note
19663                 // its current wake lock time to later know to kill it if
19664                 // it is not behaving well.
19665                 BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
19666                 synchronized (stats) {
19667                     app.lastWakeTime = stats.getProcessWakeTime(app.info.uid,
19668                             app.pid, nowElapsed);
19669                 }
19670                 app.lastCpuTime = app.curCpuTime;
19671
19672             }
19673             // Inform UsageStats of important process state change
19674             // Must be called before updating setProcState
19675             maybeUpdateUsageStatsLocked(app, nowElapsed);
19676
19677             app.setProcState = app.curProcState;
19678             if (app.setProcState >= ActivityManager.PROCESS_STATE_HOME) {
19679                 app.notCachedSinceIdle = false;
19680             }
19681             if (!doingAll) {
19682                 setProcessTrackerStateLocked(app, mProcessStats.getMemFactorLocked(), now);
19683             } else {
19684                 app.procStateChanged = true;
19685             }
19686         } else if (app.reportedInteraction && (nowElapsed-app.interactionEventTime)
19687                 > USAGE_STATS_INTERACTION_INTERVAL) {
19688             // For apps that sit around for a long time in the interactive state, we need
19689             // to report this at least once a day so they don't go idle.
19690             maybeUpdateUsageStatsLocked(app, nowElapsed);
19691         }
19692
19693         if (changes != 0) {
19694             if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG_PROCESS_OBSERVERS,
19695                     "Changes in " + app + ": " + changes);
19696             int i = mPendingProcessChanges.size()-1;
19697             ProcessChangeItem item = null;
19698             while (i >= 0) {
19699                 item = mPendingProcessChanges.get(i);
19700                 if (item.pid == app.pid) {
19701                     if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG_PROCESS_OBSERVERS,
19702                             "Re-using existing item: " + item);
19703                     break;
19704                 }
19705                 i--;
19706             }
19707             if (i < 0) {
19708                 // No existing item in pending changes; need a new one.
19709                 final int NA = mAvailProcessChanges.size();
19710                 if (NA > 0) {
19711                     item = mAvailProcessChanges.remove(NA-1);
19712                     if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG_PROCESS_OBSERVERS,
19713                             "Retrieving available item: " + item);
19714                 } else {
19715                     item = new ProcessChangeItem();
19716                     if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG_PROCESS_OBSERVERS,
19717                             "Allocating new item: " + item);
19718                 }
19719                 item.changes = 0;
19720                 item.pid = app.pid;
19721                 item.uid = app.info.uid;
19722                 if (mPendingProcessChanges.size() == 0) {
19723                     if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG_PROCESS_OBSERVERS,
19724                             "*** Enqueueing dispatch processes changed!");
19725                     mUiHandler.obtainMessage(DISPATCH_PROCESSES_CHANGED_UI_MSG).sendToTarget();
19726                 }
19727                 mPendingProcessChanges.add(item);
19728             }
19729             item.changes |= changes;
19730             item.processState = app.repProcState;
19731             item.foregroundActivities = app.repForegroundActivities;
19732             if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG_PROCESS_OBSERVERS,
19733                     "Item " + Integer.toHexString(System.identityHashCode(item))
19734                     + " " + app.toShortString() + ": changes=" + item.changes
19735                     + " procState=" + item.processState
19736                     + " foreground=" + item.foregroundActivities
19737                     + " type=" + app.adjType + " source=" + app.adjSource
19738                     + " target=" + app.adjTarget);
19739         }
19740
19741         return success;
19742     }
19743
19744     private final void enqueueUidChangeLocked(UidRecord uidRec, int uid, int change) {
19745         final UidRecord.ChangeItem pendingChange;
19746         if (uidRec == null || uidRec.pendingChange == null) {
19747             if (mPendingUidChanges.size() == 0) {
19748                 if (DEBUG_UID_OBSERVERS) Slog.i(TAG_UID_OBSERVERS,
19749                         "*** Enqueueing dispatch uid changed!");
19750                 mUiHandler.obtainMessage(DISPATCH_UIDS_CHANGED_UI_MSG).sendToTarget();
19751             }
19752             final int NA = mAvailUidChanges.size();
19753             if (NA > 0) {
19754                 pendingChange = mAvailUidChanges.remove(NA-1);
19755                 if (DEBUG_UID_OBSERVERS) Slog.i(TAG_UID_OBSERVERS,
19756                         "Retrieving available item: " + pendingChange);
19757             } else {
19758                 pendingChange = new UidRecord.ChangeItem();
19759                 if (DEBUG_UID_OBSERVERS) Slog.i(TAG_UID_OBSERVERS,
19760                         "Allocating new item: " + pendingChange);
19761             }
19762             if (uidRec != null) {
19763                 uidRec.pendingChange = pendingChange;
19764                 if (change == UidRecord.CHANGE_GONE && !uidRec.idle) {
19765                     // If this uid is going away, and we haven't yet reported it is gone,
19766                     // then do so now.
19767                     change = UidRecord.CHANGE_GONE_IDLE;
19768                 }
19769             } else if (uid < 0) {
19770                 throw new IllegalArgumentException("No UidRecord or uid");
19771             }
19772             pendingChange.uidRecord = uidRec;
19773             pendingChange.uid = uidRec != null ? uidRec.uid : uid;
19774             mPendingUidChanges.add(pendingChange);
19775         } else {
19776             pendingChange = uidRec.pendingChange;
19777             if (change == UidRecord.CHANGE_GONE && pendingChange.change == UidRecord.CHANGE_IDLE) {
19778                 change = UidRecord.CHANGE_GONE_IDLE;
19779             }
19780         }
19781         pendingChange.change = change;
19782         pendingChange.processState = uidRec != null
19783                 ? uidRec.setProcState : ActivityManager.PROCESS_STATE_NONEXISTENT;
19784     }
19785
19786     private void maybeUpdateProviderUsageStatsLocked(ProcessRecord app, String providerPkgName,
19787             String authority) {
19788         if (app == null) return;
19789         if (app.curProcState <= ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND) {
19790             UserState userState = mUserController.getStartedUserStateLocked(app.userId);
19791             if (userState == null) return;
19792             final long now = SystemClock.elapsedRealtime();
19793             Long lastReported = userState.mProviderLastReportedFg.get(authority);
19794             if (lastReported == null || lastReported < now - 60 * 1000L) {
19795                 mUsageStatsService.reportContentProviderUsage(
19796                         authority, providerPkgName, app.userId);
19797                 userState.mProviderLastReportedFg.put(authority, now);
19798             }
19799         }
19800     }
19801
19802     private void maybeUpdateUsageStatsLocked(ProcessRecord app, long nowElapsed) {
19803         if (DEBUG_USAGE_STATS) {
19804             Slog.d(TAG, "Checking proc [" + Arrays.toString(app.getPackageList())
19805                     + "] state changes: old = " + app.setProcState + ", new = "
19806                     + app.curProcState);
19807         }
19808         if (mUsageStatsService == null) {
19809             return;
19810         }
19811         boolean isInteraction;
19812         // To avoid some abuse patterns, we are going to be careful about what we consider
19813         // to be an app interaction.  Being the top activity doesn't count while the display
19814         // is sleeping, nor do short foreground services.
19815         if (app.curProcState <= ActivityManager.PROCESS_STATE_BOUND_FOREGROUND_SERVICE) {
19816             isInteraction = true;
19817             app.fgInteractionTime = 0;
19818         } else if (app.curProcState <= ActivityManager.PROCESS_STATE_TOP_SLEEPING) {
19819             if (app.fgInteractionTime == 0) {
19820                 app.fgInteractionTime = nowElapsed;
19821                 isInteraction = false;
19822             } else {
19823                 isInteraction = nowElapsed > app.fgInteractionTime + SERVICE_USAGE_INTERACTION_TIME;
19824             }
19825         } else {
19826             isInteraction = app.curProcState
19827                     <= ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND;
19828             app.fgInteractionTime = 0;
19829         }
19830         if (isInteraction && (!app.reportedInteraction
19831                 || (nowElapsed-app.interactionEventTime) > USAGE_STATS_INTERACTION_INTERVAL)) {
19832             app.interactionEventTime = nowElapsed;
19833             String[] packages = app.getPackageList();
19834             if (packages != null) {
19835                 for (int i = 0; i < packages.length; i++) {
19836                     mUsageStatsService.reportEvent(packages[i], app.userId,
19837                             UsageEvents.Event.SYSTEM_INTERACTION);
19838                 }
19839             }
19840         }
19841         app.reportedInteraction = isInteraction;
19842         if (!isInteraction) {
19843             app.interactionEventTime = 0;
19844         }
19845     }
19846
19847     private final void setProcessTrackerStateLocked(ProcessRecord proc, int memFactor, long now) {
19848         if (proc.thread != null) {
19849             if (proc.baseProcessTracker != null) {
19850                 proc.baseProcessTracker.setState(proc.repProcState, memFactor, now, proc.pkgList);
19851             }
19852         }
19853     }
19854
19855     private final boolean updateOomAdjLocked(ProcessRecord app, int cachedAdj,
19856             ProcessRecord TOP_APP, boolean doingAll, long now) {
19857         if (app.thread == null) {
19858             return false;
19859         }
19860
19861         computeOomAdjLocked(app, cachedAdj, TOP_APP, doingAll, now);
19862
19863         return applyOomAdjLocked(app, doingAll, now, SystemClock.elapsedRealtime());
19864     }
19865
19866     final void updateProcessForegroundLocked(ProcessRecord proc, boolean isForeground,
19867             boolean oomAdj) {
19868         if (isForeground != proc.foregroundServices) {
19869             proc.foregroundServices = isForeground;
19870             ArrayList<ProcessRecord> curProcs = mForegroundPackages.get(proc.info.packageName,
19871                     proc.info.uid);
19872             if (isForeground) {
19873                 if (curProcs == null) {
19874                     curProcs = new ArrayList<ProcessRecord>();
19875                     mForegroundPackages.put(proc.info.packageName, proc.info.uid, curProcs);
19876                 }
19877                 if (!curProcs.contains(proc)) {
19878                     curProcs.add(proc);
19879                     mBatteryStatsService.noteEvent(BatteryStats.HistoryItem.EVENT_FOREGROUND_START,
19880                             proc.info.packageName, proc.info.uid);
19881                 }
19882             } else {
19883                 if (curProcs != null) {
19884                     if (curProcs.remove(proc)) {
19885                         mBatteryStatsService.noteEvent(
19886                                 BatteryStats.HistoryItem.EVENT_FOREGROUND_FINISH,
19887                                 proc.info.packageName, proc.info.uid);
19888                         if (curProcs.size() <= 0) {
19889                             mForegroundPackages.remove(proc.info.packageName, proc.info.uid);
19890                         }
19891                     }
19892                 }
19893             }
19894             if (oomAdj) {
19895                 updateOomAdjLocked();
19896             }
19897         }
19898     }
19899
19900     private final ActivityRecord resumedAppLocked() {
19901         ActivityRecord act = mStackSupervisor.resumedAppLocked();
19902         String pkg;
19903         int uid;
19904         if (act != null) {
19905             pkg = act.packageName;
19906             uid = act.info.applicationInfo.uid;
19907         } else {
19908             pkg = null;
19909             uid = -1;
19910         }
19911         // Has the UID or resumed package name changed?
19912         if (uid != mCurResumedUid || (pkg != mCurResumedPackage
19913                 && (pkg == null || !pkg.equals(mCurResumedPackage)))) {
19914             if (mCurResumedPackage != null) {
19915                 mBatteryStatsService.noteEvent(BatteryStats.HistoryItem.EVENT_TOP_FINISH,
19916                         mCurResumedPackage, mCurResumedUid);
19917             }
19918             mCurResumedPackage = pkg;
19919             mCurResumedUid = uid;
19920             if (mCurResumedPackage != null) {
19921                 mBatteryStatsService.noteEvent(BatteryStats.HistoryItem.EVENT_TOP_START,
19922                         mCurResumedPackage, mCurResumedUid);
19923             }
19924         }
19925         return act;
19926     }
19927
19928     final boolean updateOomAdjLocked(ProcessRecord app) {
19929         final ActivityRecord TOP_ACT = resumedAppLocked();
19930         final ProcessRecord TOP_APP = TOP_ACT != null ? TOP_ACT.app : null;
19931         final boolean wasCached = app.cached;
19932
19933         mAdjSeq++;
19934
19935         // This is the desired cached adjusment we want to tell it to use.
19936         // If our app is currently cached, we know it, and that is it.  Otherwise,
19937         // we don't know it yet, and it needs to now be cached we will then
19938         // need to do a complete oom adj.
19939         final int cachedAdj = app.curRawAdj >= ProcessList.CACHED_APP_MIN_ADJ
19940                 ? app.curRawAdj : ProcessList.UNKNOWN_ADJ;
19941         boolean success = updateOomAdjLocked(app, cachedAdj, TOP_APP, false,
19942                 SystemClock.uptimeMillis());
19943         if (wasCached != app.cached || app.curRawAdj == ProcessList.UNKNOWN_ADJ) {
19944             // Changed to/from cached state, so apps after it in the LRU
19945             // list may also be changed.
19946             updateOomAdjLocked();
19947         }
19948         return success;
19949     }
19950
19951     final void updateOomAdjLocked() {
19952         final ActivityRecord TOP_ACT = resumedAppLocked();
19953         final ProcessRecord TOP_APP = TOP_ACT != null ? TOP_ACT.app : null;
19954         final long now = SystemClock.uptimeMillis();
19955         final long nowElapsed = SystemClock.elapsedRealtime();
19956         final long oldTime = now - ProcessList.MAX_EMPTY_TIME;
19957         final int N = mLruProcesses.size();
19958
19959         if (false) {
19960             RuntimeException e = new RuntimeException();
19961             e.fillInStackTrace();
19962             Slog.i(TAG, "updateOomAdj: top=" + TOP_ACT, e);
19963         }
19964
19965         // Reset state in all uid records.
19966         for (int i=mActiveUids.size()-1; i>=0; i--) {
19967             final UidRecord uidRec = mActiveUids.valueAt(i);
19968             if (false && DEBUG_UID_OBSERVERS) Slog.i(TAG_UID_OBSERVERS,
19969                     "Starting update of " + uidRec);
19970             uidRec.reset();
19971         }
19972
19973         mStackSupervisor.rankTaskLayersIfNeeded();
19974
19975         mAdjSeq++;
19976         mNewNumServiceProcs = 0;
19977         mNewNumAServiceProcs = 0;
19978
19979         final int emptyProcessLimit;
19980         final int cachedProcessLimit;
19981         if (mProcessLimit <= 0) {
19982             emptyProcessLimit = cachedProcessLimit = 0;
19983         } else if (mProcessLimit == 1) {
19984             emptyProcessLimit = 1;
19985             cachedProcessLimit = 0;
19986         } else {
19987             emptyProcessLimit = ProcessList.computeEmptyProcessLimit(mProcessLimit);
19988             cachedProcessLimit = mProcessLimit - emptyProcessLimit;
19989         }
19990
19991         // Let's determine how many processes we have running vs.
19992         // how many slots we have for background processes; we may want
19993         // to put multiple processes in a slot of there are enough of
19994         // them.
19995         int numSlots = (ProcessList.CACHED_APP_MAX_ADJ
19996                 - ProcessList.CACHED_APP_MIN_ADJ + 1) / 2;
19997         int numEmptyProcs = N - mNumNonCachedProcs - mNumCachedHiddenProcs;
19998         if (numEmptyProcs > cachedProcessLimit) {
19999             // If there are more empty processes than our limit on cached
20000             // processes, then use the cached process limit for the factor.
20001             // This ensures that the really old empty processes get pushed
20002             // down to the bottom, so if we are running low on memory we will
20003             // have a better chance at keeping around more cached processes
20004             // instead of a gazillion empty processes.
20005             numEmptyProcs = cachedProcessLimit;
20006         }
20007         int emptyFactor = numEmptyProcs/numSlots;
20008         if (emptyFactor < 1) emptyFactor = 1;
20009         int cachedFactor = (mNumCachedHiddenProcs > 0 ? mNumCachedHiddenProcs : 1)/numSlots;
20010         if (cachedFactor < 1) cachedFactor = 1;
20011         int stepCached = 0;
20012         int stepEmpty = 0;
20013         int numCached = 0;
20014         int numEmpty = 0;
20015         int numTrimming = 0;
20016
20017         mNumNonCachedProcs = 0;
20018         mNumCachedHiddenProcs = 0;
20019
20020         // First update the OOM adjustment for each of the
20021         // application processes based on their current state.
20022         int curCachedAdj = ProcessList.CACHED_APP_MIN_ADJ;
20023         int nextCachedAdj = curCachedAdj+1;
20024         int curEmptyAdj = ProcessList.CACHED_APP_MIN_ADJ;
20025         int nextEmptyAdj = curEmptyAdj+2;
20026         for (int i=N-1; i>=0; i--) {
20027             ProcessRecord app = mLruProcesses.get(i);
20028             if (!app.killedByAm && app.thread != null) {
20029                 app.procStateChanged = false;
20030                 computeOomAdjLocked(app, ProcessList.UNKNOWN_ADJ, TOP_APP, true, now);
20031
20032                 // If we haven't yet assigned the final cached adj
20033                 // to the process, do that now.
20034                 if (app.curAdj >= ProcessList.UNKNOWN_ADJ) {
20035                     switch (app.curProcState) {
20036                         case ActivityManager.PROCESS_STATE_CACHED_ACTIVITY:
20037                         case ActivityManager.PROCESS_STATE_CACHED_ACTIVITY_CLIENT:
20038                             // This process is a cached process holding activities...
20039                             // assign it the next cached value for that type, and then
20040                             // step that cached level.
20041                             app.curRawAdj = curCachedAdj;
20042                             app.curAdj = app.modifyRawOomAdj(curCachedAdj);
20043                             if (DEBUG_LRU && false) Slog.d(TAG_LRU, "Assigning activity LRU #" + i
20044                                     + " adj: " + app.curAdj + " (curCachedAdj=" + curCachedAdj
20045                                     + ")");
20046                             if (curCachedAdj != nextCachedAdj) {
20047                                 stepCached++;
20048                                 if (stepCached >= cachedFactor) {
20049                                     stepCached = 0;
20050                                     curCachedAdj = nextCachedAdj;
20051                                     nextCachedAdj += 2;
20052                                     if (nextCachedAdj > ProcessList.CACHED_APP_MAX_ADJ) {
20053                                         nextCachedAdj = ProcessList.CACHED_APP_MAX_ADJ;
20054                                     }
20055                                 }
20056                             }
20057                             break;
20058                         default:
20059                             // For everything else, assign next empty cached process
20060                             // level and bump that up.  Note that this means that
20061                             // long-running services that have dropped down to the
20062                             // cached level will be treated as empty (since their process
20063                             // state is still as a service), which is what we want.
20064                             app.curRawAdj = curEmptyAdj;
20065                             app.curAdj = app.modifyRawOomAdj(curEmptyAdj);
20066                             if (DEBUG_LRU && false) Slog.d(TAG_LRU, "Assigning empty LRU #" + i
20067                                     + " adj: " + app.curAdj + " (curEmptyAdj=" + curEmptyAdj
20068                                     + ")");
20069                             if (curEmptyAdj != nextEmptyAdj) {
20070                                 stepEmpty++;
20071                                 if (stepEmpty >= emptyFactor) {
20072                                     stepEmpty = 0;
20073                                     curEmptyAdj = nextEmptyAdj;
20074                                     nextEmptyAdj += 2;
20075                                     if (nextEmptyAdj > ProcessList.CACHED_APP_MAX_ADJ) {
20076                                         nextEmptyAdj = ProcessList.CACHED_APP_MAX_ADJ;
20077                                     }
20078                                 }
20079                             }
20080                             break;
20081                     }
20082                 }
20083
20084                 applyOomAdjLocked(app, true, now, nowElapsed);
20085
20086                 // Count the number of process types.
20087                 switch (app.curProcState) {
20088                     case ActivityManager.PROCESS_STATE_CACHED_ACTIVITY:
20089                     case ActivityManager.PROCESS_STATE_CACHED_ACTIVITY_CLIENT:
20090                         mNumCachedHiddenProcs++;
20091                         numCached++;
20092                         if (numCached > cachedProcessLimit) {
20093                             app.kill("cached #" + numCached, true);
20094                         }
20095                         break;
20096                     case ActivityManager.PROCESS_STATE_CACHED_EMPTY:
20097                         if (numEmpty > ProcessList.TRIM_EMPTY_APPS
20098                                 && app.lastActivityTime < oldTime) {
20099                             app.kill("empty for "
20100                                     + ((oldTime + ProcessList.MAX_EMPTY_TIME - app.lastActivityTime)
20101                                     / 1000) + "s", true);
20102                         } else {
20103                             numEmpty++;
20104                             if (numEmpty > emptyProcessLimit) {
20105                                 app.kill("empty #" + numEmpty, DEBUG_PROCESSES);
20106                             }
20107                         }
20108                         break;
20109                     default:
20110                         mNumNonCachedProcs++;
20111                         break;
20112                 }
20113
20114                 if (app.isolated && app.services.size() <= 0) {
20115                     // If this is an isolated process, and there are no
20116                     // services running in it, then the process is no longer
20117                     // needed.  We agressively kill these because we can by
20118                     // definition not re-use the same process again, and it is
20119                     // good to avoid having whatever code was running in them
20120                     // left sitting around after no longer needed.
20121                     app.kill("isolated not needed", true);
20122                 } else {
20123                     // Keeping this process, update its uid.
20124                     final UidRecord uidRec = app.uidRecord;
20125                     if (uidRec != null && uidRec.curProcState > app.curProcState) {
20126                         uidRec.curProcState = app.curProcState;
20127                     }
20128                 }
20129
20130                 if (app.curProcState >= ActivityManager.PROCESS_STATE_HOME
20131                         && !app.killedByAm) {
20132                     numTrimming++;
20133                 }
20134             }
20135         }
20136
20137         mNumServiceProcs = mNewNumServiceProcs;
20138
20139         // Now determine the memory trimming level of background processes.
20140         // Unfortunately we need to start at the back of the list to do this
20141         // properly.  We only do this if the number of background apps we
20142         // are managing to keep around is less than half the maximum we desire;
20143         // if we are keeping a good number around, we'll let them use whatever
20144         // memory they want.
20145         final int numCachedAndEmpty = numCached + numEmpty;
20146         int memFactor;
20147         if (numCached <= ProcessList.TRIM_CACHED_APPS
20148                 && numEmpty <= ProcessList.TRIM_EMPTY_APPS) {
20149             if (numCachedAndEmpty <= ProcessList.TRIM_CRITICAL_THRESHOLD) {
20150                 memFactor = ProcessStats.ADJ_MEM_FACTOR_CRITICAL;
20151             } else if (numCachedAndEmpty <= ProcessList.TRIM_LOW_THRESHOLD) {
20152                 memFactor = ProcessStats.ADJ_MEM_FACTOR_LOW;
20153             } else {
20154                 memFactor = ProcessStats.ADJ_MEM_FACTOR_MODERATE;
20155             }
20156         } else {
20157             memFactor = ProcessStats.ADJ_MEM_FACTOR_NORMAL;
20158         }
20159         // We always allow the memory level to go up (better).  We only allow it to go
20160         // down if we are in a state where that is allowed, *and* the total number of processes
20161         // has gone down since last time.
20162         if (DEBUG_OOM_ADJ) Slog.d(TAG_OOM_ADJ, "oom: memFactor=" + memFactor
20163                 + " last=" + mLastMemoryLevel + " allowLow=" + mAllowLowerMemLevel
20164                 + " numProcs=" + mLruProcesses.size() + " last=" + mLastNumProcesses);
20165         if (memFactor > mLastMemoryLevel) {
20166             if (!mAllowLowerMemLevel || mLruProcesses.size() >= mLastNumProcesses) {
20167                 memFactor = mLastMemoryLevel;
20168                 if (DEBUG_OOM_ADJ) Slog.d(TAG_OOM_ADJ, "Keeping last mem factor!");
20169             }
20170         }
20171         mLastMemoryLevel = memFactor;
20172         mLastNumProcesses = mLruProcesses.size();
20173         boolean allChanged = mProcessStats.setMemFactorLocked(memFactor, !isSleeping(), now);
20174         final int trackerMemFactor = mProcessStats.getMemFactorLocked();
20175         if (memFactor != ProcessStats.ADJ_MEM_FACTOR_NORMAL) {
20176             if (mLowRamStartTime == 0) {
20177                 mLowRamStartTime = now;
20178             }
20179             int step = 0;
20180             int fgTrimLevel;
20181             switch (memFactor) {
20182                 case ProcessStats.ADJ_MEM_FACTOR_CRITICAL:
20183                     fgTrimLevel = ComponentCallbacks2.TRIM_MEMORY_RUNNING_CRITICAL;
20184                     break;
20185                 case ProcessStats.ADJ_MEM_FACTOR_LOW:
20186                     fgTrimLevel = ComponentCallbacks2.TRIM_MEMORY_RUNNING_LOW;
20187                     break;
20188                 default:
20189                     fgTrimLevel = ComponentCallbacks2.TRIM_MEMORY_RUNNING_MODERATE;
20190                     break;
20191             }
20192             int factor = numTrimming/3;
20193             int minFactor = 2;
20194             if (mHomeProcess != null) minFactor++;
20195             if (mPreviousProcess != null) minFactor++;
20196             if (factor < minFactor) factor = minFactor;
20197             int curLevel = ComponentCallbacks2.TRIM_MEMORY_COMPLETE;
20198             for (int i=N-1; i>=0; i--) {
20199                 ProcessRecord app = mLruProcesses.get(i);
20200                 if (allChanged || app.procStateChanged) {
20201                     setProcessTrackerStateLocked(app, trackerMemFactor, now);
20202                     app.procStateChanged = false;
20203                 }
20204                 if (app.curProcState >= ActivityManager.PROCESS_STATE_HOME
20205                         && !app.killedByAm) {
20206                     if (app.trimMemoryLevel < curLevel && app.thread != null) {
20207                         try {
20208                             if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG_OOM_ADJ,
20209                                     "Trimming memory of " + app.processName + " to " + curLevel);
20210                             app.thread.scheduleTrimMemory(curLevel);
20211                         } catch (RemoteException e) {
20212                         }
20213                         if (false) {
20214                             // For now we won't do this; our memory trimming seems
20215                             // to be good enough at this point that destroying
20216                             // activities causes more harm than good.
20217                             if (curLevel >= ComponentCallbacks2.TRIM_MEMORY_COMPLETE
20218                                     && app != mHomeProcess && app != mPreviousProcess) {
20219                                 // Need to do this on its own message because the stack may not
20220                                 // be in a consistent state at this point.
20221                                 // For these apps we will also finish their activities
20222                                 // to help them free memory.
20223                                 mStackSupervisor.scheduleDestroyAllActivities(app, "trim");
20224                             }
20225                         }
20226                     }
20227                     app.trimMemoryLevel = curLevel;
20228                     step++;
20229                     if (step >= factor) {
20230                         step = 0;
20231                         switch (curLevel) {
20232                             case ComponentCallbacks2.TRIM_MEMORY_COMPLETE:
20233                                 curLevel = ComponentCallbacks2.TRIM_MEMORY_MODERATE;
20234                                 break;
20235                             case ComponentCallbacks2.TRIM_MEMORY_MODERATE:
20236                                 curLevel = ComponentCallbacks2.TRIM_MEMORY_BACKGROUND;
20237                                 break;
20238                         }
20239                     }
20240                 } else if (app.curProcState == ActivityManager.PROCESS_STATE_HEAVY_WEIGHT) {
20241                     if (app.trimMemoryLevel < ComponentCallbacks2.TRIM_MEMORY_BACKGROUND
20242                             && app.thread != null) {
20243                         try {
20244                             if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG_OOM_ADJ,
20245                                     "Trimming memory of heavy-weight " + app.processName
20246                                     + " to " + ComponentCallbacks2.TRIM_MEMORY_BACKGROUND);
20247                             app.thread.scheduleTrimMemory(
20248                                     ComponentCallbacks2.TRIM_MEMORY_BACKGROUND);
20249                         } catch (RemoteException e) {
20250                         }
20251                     }
20252                     app.trimMemoryLevel = ComponentCallbacks2.TRIM_MEMORY_BACKGROUND;
20253                 } else {
20254                     if ((app.curProcState >= ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND
20255                             || app.systemNoUi) && app.pendingUiClean) {
20256                         // If this application is now in the background and it
20257                         // had done UI, then give it the special trim level to
20258                         // have it free UI resources.
20259                         final int level = ComponentCallbacks2.TRIM_MEMORY_UI_HIDDEN;
20260                         if (app.trimMemoryLevel < level && app.thread != null) {
20261                             try {
20262                                 if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG_OOM_ADJ,
20263                                         "Trimming memory of bg-ui " + app.processName
20264                                         + " to " + level);
20265                                 app.thread.scheduleTrimMemory(level);
20266                             } catch (RemoteException e) {
20267                             }
20268                         }
20269                         app.pendingUiClean = false;
20270                     }
20271                     if (app.trimMemoryLevel < fgTrimLevel && app.thread != null) {
20272                         try {
20273                             if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG_OOM_ADJ,
20274                                     "Trimming memory of fg " + app.processName
20275                                     + " to " + fgTrimLevel);
20276                             app.thread.scheduleTrimMemory(fgTrimLevel);
20277                         } catch (RemoteException e) {
20278                         }
20279                     }
20280                     app.trimMemoryLevel = fgTrimLevel;
20281                 }
20282             }
20283         } else {
20284             if (mLowRamStartTime != 0) {
20285                 mLowRamTimeSinceLastIdle += now - mLowRamStartTime;
20286                 mLowRamStartTime = 0;
20287             }
20288             for (int i=N-1; i>=0; i--) {
20289                 ProcessRecord app = mLruProcesses.get(i);
20290                 if (allChanged || app.procStateChanged) {
20291                     setProcessTrackerStateLocked(app, trackerMemFactor, now);
20292                     app.procStateChanged = false;
20293                 }
20294                 if ((app.curProcState >= ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND
20295                         || app.systemNoUi) && app.pendingUiClean) {
20296                     if (app.trimMemoryLevel < ComponentCallbacks2.TRIM_MEMORY_UI_HIDDEN
20297                             && app.thread != null) {
20298                         try {
20299                             if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG_OOM_ADJ,
20300                                     "Trimming memory of ui hidden " + app.processName
20301                                     + " to " + ComponentCallbacks2.TRIM_MEMORY_UI_HIDDEN);
20302                             app.thread.scheduleTrimMemory(
20303                                     ComponentCallbacks2.TRIM_MEMORY_UI_HIDDEN);
20304                         } catch (RemoteException e) {
20305                         }
20306                     }
20307                     app.pendingUiClean = false;
20308                 }
20309                 app.trimMemoryLevel = 0;
20310             }
20311         }
20312
20313         if (mAlwaysFinishActivities) {
20314             // Need to do this on its own message because the stack may not
20315             // be in a consistent state at this point.
20316             mStackSupervisor.scheduleDestroyAllActivities(null, "always-finish");
20317         }
20318
20319         if (allChanged) {
20320             requestPssAllProcsLocked(now, false, mProcessStats.isMemFactorLowered());
20321         }
20322
20323         // Update from any uid changes.
20324         for (int i=mActiveUids.size()-1; i>=0; i--) {
20325             final UidRecord uidRec = mActiveUids.valueAt(i);
20326             int uidChange = UidRecord.CHANGE_PROCSTATE;
20327             if (uidRec.setProcState != uidRec.curProcState) {
20328                 if (DEBUG_UID_OBSERVERS) Slog.i(TAG_UID_OBSERVERS,
20329                         "Changes in " + uidRec + ": proc state from " + uidRec.setProcState
20330                         + " to " + uidRec.curProcState);
20331                 if (ActivityManager.isProcStateBackground(uidRec.curProcState)) {
20332                     if (!ActivityManager.isProcStateBackground(uidRec.setProcState)) {
20333                         uidRec.lastBackgroundTime = nowElapsed;
20334                         if (!mHandler.hasMessages(IDLE_UIDS_MSG)) {
20335                             // Note: the background settle time is in elapsed realtime, while
20336                             // the handler time base is uptime.  All this means is that we may
20337                             // stop background uids later than we had intended, but that only
20338                             // happens because the device was sleeping so we are okay anyway.
20339                             mHandler.sendEmptyMessageDelayed(IDLE_UIDS_MSG, BACKGROUND_SETTLE_TIME);
20340                         }
20341                     }
20342                 } else {
20343                     if (uidRec.idle) {
20344                         uidChange = UidRecord.CHANGE_ACTIVE;
20345                         uidRec.idle = false;
20346                     }
20347                     uidRec.lastBackgroundTime = 0;
20348                 }
20349                 uidRec.setProcState = uidRec.curProcState;
20350                 enqueueUidChangeLocked(uidRec, -1, uidChange);
20351                 mBatteryStatsService.noteUidProcessState(uidRec.uid, uidRec.curProcState);
20352             }
20353         }
20354
20355         if (mProcessStats.shouldWriteNowLocked(now)) {
20356             mHandler.post(new Runnable() {
20357                 @Override public void run() {
20358                     synchronized (ActivityManagerService.this) {
20359                         mProcessStats.writeStateAsyncLocked();
20360                     }
20361                 }
20362             });
20363         }
20364
20365         if (DEBUG_OOM_ADJ) {
20366             final long duration = SystemClock.uptimeMillis() - now;
20367             if (false) {
20368                 Slog.d(TAG_OOM_ADJ, "Did OOM ADJ in " + duration + "ms",
20369                         new RuntimeException("here").fillInStackTrace());
20370             } else {
20371                 Slog.d(TAG_OOM_ADJ, "Did OOM ADJ in " + duration + "ms");
20372             }
20373         }
20374     }
20375
20376     final void idleUids() {
20377         synchronized (this) {
20378             final long nowElapsed = SystemClock.elapsedRealtime();
20379             final long maxBgTime = nowElapsed - BACKGROUND_SETTLE_TIME;
20380             long nextTime = 0;
20381             for (int i=mActiveUids.size()-1; i>=0; i--) {
20382                 final UidRecord uidRec = mActiveUids.valueAt(i);
20383                 final long bgTime = uidRec.lastBackgroundTime;
20384                 if (bgTime > 0 && !uidRec.idle) {
20385                     if (bgTime <= maxBgTime) {
20386                         uidRec.idle = true;
20387                         doStopUidLocked(uidRec.uid, uidRec);
20388                     } else {
20389                         if (nextTime == 0 || nextTime > bgTime) {
20390                             nextTime = bgTime;
20391                         }
20392                     }
20393                 }
20394             }
20395             if (nextTime > 0) {
20396                 mHandler.removeMessages(IDLE_UIDS_MSG);
20397                 mHandler.sendEmptyMessageDelayed(IDLE_UIDS_MSG,
20398                         nextTime + BACKGROUND_SETTLE_TIME - nowElapsed);
20399             }
20400         }
20401     }
20402
20403     final void runInBackgroundDisabled(int uid) {
20404         synchronized (this) {
20405             UidRecord uidRec = mActiveUids.get(uid);
20406             if (uidRec != null) {
20407                 // This uid is actually running...  should it be considered background now?
20408                 if (uidRec.idle) {
20409                     doStopUidLocked(uidRec.uid, uidRec);
20410                 }
20411             } else {
20412                 // This uid isn't actually running...  still send a report about it being "stopped".
20413                 doStopUidLocked(uid, null);
20414             }
20415         }
20416     }
20417
20418     final void doStopUidLocked(int uid, final UidRecord uidRec) {
20419         mServices.stopInBackgroundLocked(uid);
20420         enqueueUidChangeLocked(uidRec, uid, UidRecord.CHANGE_IDLE);
20421     }
20422
20423     final void trimApplications() {
20424         synchronized (this) {
20425             int i;
20426
20427             // First remove any unused application processes whose package
20428             // has been removed.
20429             for (i=mRemovedProcesses.size()-1; i>=0; i--) {
20430                 final ProcessRecord app = mRemovedProcesses.get(i);
20431                 if (app.activities.size() == 0
20432                         && app.curReceiver == null && app.services.size() == 0) {
20433                     Slog.i(
20434                         TAG, "Exiting empty application process "
20435                         + app.processName + " ("
20436                         + (app.thread != null ? app.thread.asBinder() : null)
20437                         + ")\n");
20438                     if (app.pid > 0 && app.pid != MY_PID) {
20439                         app.kill("empty", false);
20440                     } else {
20441                         try {
20442                             app.thread.scheduleExit();
20443                         } catch (Exception e) {
20444                             // Ignore exceptions.
20445                         }
20446                     }
20447                     cleanUpApplicationRecordLocked(app, false, true, -1);
20448                     mRemovedProcesses.remove(i);
20449
20450                     if (app.persistent) {
20451                         addAppLocked(app.info, false, null /* ABI override */);
20452                     }
20453                 }
20454             }
20455
20456             // Now update the oom adj for all processes.
20457             updateOomAdjLocked();
20458         }
20459     }
20460
20461     /** This method sends the specified signal to each of the persistent apps */
20462     public void signalPersistentProcesses(int sig) throws RemoteException {
20463         if (sig != Process.SIGNAL_USR1) {
20464             throw new SecurityException("Only SIGNAL_USR1 is allowed");
20465         }
20466
20467         synchronized (this) {
20468             if (checkCallingPermission(android.Manifest.permission.SIGNAL_PERSISTENT_PROCESSES)
20469                     != PackageManager.PERMISSION_GRANTED) {
20470                 throw new SecurityException("Requires permission "
20471                         + android.Manifest.permission.SIGNAL_PERSISTENT_PROCESSES);
20472             }
20473
20474             for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) {
20475                 ProcessRecord r = mLruProcesses.get(i);
20476                 if (r.thread != null && r.persistent) {
20477                     Process.sendSignal(r.pid, sig);
20478                 }
20479             }
20480         }
20481     }
20482
20483     private void stopProfilerLocked(ProcessRecord proc, int profileType) {
20484         if (proc == null || proc == mProfileProc) {
20485             proc = mProfileProc;
20486             profileType = mProfileType;
20487             clearProfilerLocked();
20488         }
20489         if (proc == null) {
20490             return;
20491         }
20492         try {
20493             proc.thread.profilerControl(false, null, profileType);
20494         } catch (RemoteException e) {
20495             throw new IllegalStateException("Process disappeared");
20496         }
20497     }
20498
20499     private void clearProfilerLocked() {
20500         if (mProfileFd != null) {
20501             try {
20502                 mProfileFd.close();
20503             } catch (IOException e) {
20504             }
20505         }
20506         mProfileApp = null;
20507         mProfileProc = null;
20508         mProfileFile = null;
20509         mProfileType = 0;
20510         mAutoStopProfiler = false;
20511         mSamplingInterval = 0;
20512     }
20513
20514     public boolean profileControl(String process, int userId, boolean start,
20515             ProfilerInfo profilerInfo, int profileType) throws RemoteException {
20516
20517         try {
20518             synchronized (this) {
20519                 // note: hijacking SET_ACTIVITY_WATCHER, but should be changed to
20520                 // its own permission.
20521                 if (checkCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER)
20522                         != PackageManager.PERMISSION_GRANTED) {
20523                     throw new SecurityException("Requires permission "
20524                             + android.Manifest.permission.SET_ACTIVITY_WATCHER);
20525                 }
20526
20527                 if (start && (profilerInfo == null || profilerInfo.profileFd == null)) {
20528                     throw new IllegalArgumentException("null profile info or fd");
20529                 }
20530
20531                 ProcessRecord proc = null;
20532                 if (process != null) {
20533                     proc = findProcessLocked(process, userId, "profileControl");
20534                 }
20535
20536                 if (start && (proc == null || proc.thread == null)) {
20537                     throw new IllegalArgumentException("Unknown process: " + process);
20538                 }
20539
20540                 if (start) {
20541                     stopProfilerLocked(null, 0);
20542                     setProfileApp(proc.info, proc.processName, profilerInfo);
20543                     mProfileProc = proc;
20544                     mProfileType = profileType;
20545                     ParcelFileDescriptor fd = profilerInfo.profileFd;
20546                     try {
20547                         fd = fd.dup();
20548                     } catch (IOException e) {
20549                         fd = null;
20550                     }
20551                     profilerInfo.profileFd = fd;
20552                     proc.thread.profilerControl(start, profilerInfo, profileType);
20553                     fd = null;
20554                     mProfileFd = null;
20555                 } else {
20556                     stopProfilerLocked(proc, profileType);
20557                     if (profilerInfo != null && profilerInfo.profileFd != null) {
20558                         try {
20559                             profilerInfo.profileFd.close();
20560                         } catch (IOException e) {
20561                         }
20562                     }
20563                 }
20564
20565                 return true;
20566             }
20567         } catch (RemoteException e) {
20568             throw new IllegalStateException("Process disappeared");
20569         } finally {
20570             if (profilerInfo != null && profilerInfo.profileFd != null) {
20571                 try {
20572                     profilerInfo.profileFd.close();
20573                 } catch (IOException e) {
20574                 }
20575             }
20576         }
20577     }
20578
20579     private ProcessRecord findProcessLocked(String process, int userId, String callName) {
20580         userId = mUserController.handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(),
20581                 userId, true, ALLOW_FULL_ONLY, callName, null);
20582         ProcessRecord proc = null;
20583         try {
20584             int pid = Integer.parseInt(process);
20585             synchronized (mPidsSelfLocked) {
20586                 proc = mPidsSelfLocked.get(pid);
20587             }
20588         } catch (NumberFormatException e) {
20589         }
20590
20591         if (proc == null) {
20592             ArrayMap<String, SparseArray<ProcessRecord>> all
20593                     = mProcessNames.getMap();
20594             SparseArray<ProcessRecord> procs = all.get(process);
20595             if (procs != null && procs.size() > 0) {
20596                 proc = procs.valueAt(0);
20597                 if (userId != UserHandle.USER_ALL && proc.userId != userId) {
20598                     for (int i=1; i<procs.size(); i++) {
20599                         ProcessRecord thisProc = procs.valueAt(i);
20600                         if (thisProc.userId == userId) {
20601                             proc = thisProc;
20602                             break;
20603                         }
20604                     }
20605                 }
20606             }
20607         }
20608
20609         return proc;
20610     }
20611
20612     public boolean dumpHeap(String process, int userId, boolean managed,
20613             String path, ParcelFileDescriptor fd) throws RemoteException {
20614
20615         try {
20616             synchronized (this) {
20617                 // note: hijacking SET_ACTIVITY_WATCHER, but should be changed to
20618                 // its own permission (same as profileControl).
20619                 if (checkCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER)
20620                         != PackageManager.PERMISSION_GRANTED) {
20621                     throw new SecurityException("Requires permission "
20622                             + android.Manifest.permission.SET_ACTIVITY_WATCHER);
20623                 }
20624
20625                 if (fd == null) {
20626                     throw new IllegalArgumentException("null fd");
20627                 }
20628
20629                 ProcessRecord proc = findProcessLocked(process, userId, "dumpHeap");
20630                 if (proc == null || proc.thread == null) {
20631                     throw new IllegalArgumentException("Unknown process: " + process);
20632                 }
20633
20634                 boolean isDebuggable = "1".equals(SystemProperties.get(SYSTEM_DEBUGGABLE, "0"));
20635                 if (!isDebuggable) {
20636                     if ((proc.info.flags&ApplicationInfo.FLAG_DEBUGGABLE) == 0) {
20637                         throw new SecurityException("Process not debuggable: " + proc);
20638                     }
20639                 }
20640
20641                 proc.thread.dumpHeap(managed, path, fd);
20642                 fd = null;
20643                 return true;
20644             }
20645         } catch (RemoteException e) {
20646             throw new IllegalStateException("Process disappeared");
20647         } finally {
20648             if (fd != null) {
20649                 try {
20650                     fd.close();
20651                 } catch (IOException e) {
20652                 }
20653             }
20654         }
20655     }
20656
20657     @Override
20658     public void setDumpHeapDebugLimit(String processName, int uid, long maxMemSize,
20659             String reportPackage) {
20660         if (processName != null) {
20661             enforceCallingPermission(android.Manifest.permission.SET_DEBUG_APP,
20662                     "setDumpHeapDebugLimit()");
20663         } else {
20664             synchronized (mPidsSelfLocked) {
20665                 ProcessRecord proc = mPidsSelfLocked.get(Binder.getCallingPid());
20666                 if (proc == null) {
20667                     throw new SecurityException("No process found for calling pid "
20668                             + Binder.getCallingPid());
20669                 }
20670                 if (!Build.IS_DEBUGGABLE
20671                         && (proc.info.flags&ApplicationInfo.FLAG_DEBUGGABLE) == 0) {
20672                     throw new SecurityException("Not running a debuggable build");
20673                 }
20674                 processName = proc.processName;
20675                 uid = proc.uid;
20676                 if (reportPackage != null && !proc.pkgList.containsKey(reportPackage)) {
20677                     throw new SecurityException("Package " + reportPackage + " is not running in "
20678                             + proc);
20679                 }
20680             }
20681         }
20682         synchronized (this) {
20683             if (maxMemSize > 0) {
20684                 mMemWatchProcesses.put(processName, uid, new Pair(maxMemSize, reportPackage));
20685             } else {
20686                 if (uid != 0) {
20687                     mMemWatchProcesses.remove(processName, uid);
20688                 } else {
20689                     mMemWatchProcesses.getMap().remove(processName);
20690                 }
20691             }
20692         }
20693     }
20694
20695     @Override
20696     public void dumpHeapFinished(String path) {
20697         synchronized (this) {
20698             if (Binder.getCallingPid() != mMemWatchDumpPid) {
20699                 Slog.w(TAG, "dumpHeapFinished: Calling pid " + Binder.getCallingPid()
20700                         + " does not match last pid " + mMemWatchDumpPid);
20701                 return;
20702             }
20703             if (mMemWatchDumpFile == null || !mMemWatchDumpFile.equals(path)) {
20704                 Slog.w(TAG, "dumpHeapFinished: Calling path " + path
20705                         + " does not match last path " + mMemWatchDumpFile);
20706                 return;
20707             }
20708             if (DEBUG_PSS) Slog.d(TAG_PSS, "Dump heap finished for " + path);
20709             mHandler.sendEmptyMessage(POST_DUMP_HEAP_NOTIFICATION_MSG);
20710         }
20711     }
20712
20713     /** In this method we try to acquire our lock to make sure that we have not deadlocked */
20714     public void monitor() {
20715         synchronized (this) { }
20716     }
20717
20718     void onCoreSettingsChange(Bundle settings) {
20719         for (int i = mLruProcesses.size() - 1; i >= 0; i--) {
20720             ProcessRecord processRecord = mLruProcesses.get(i);
20721             try {
20722                 if (processRecord.thread != null) {
20723                     processRecord.thread.setCoreSettings(settings);
20724                 }
20725             } catch (RemoteException re) {
20726                 /* ignore */
20727             }
20728         }
20729     }
20730
20731     // Multi-user methods
20732
20733     /**
20734      * Start user, if its not already running, but don't bring it to foreground.
20735      */
20736     @Override
20737     public boolean startUserInBackground(final int userId) {
20738         return mUserController.startUser(userId, /* foreground */ false);
20739     }
20740
20741     @Override
20742     public boolean unlockUser(int userId, byte[] token, byte[] secret) {
20743         return mUserController.unlockUser(userId, token, secret);
20744     }
20745
20746     @Override
20747     public boolean switchUser(final int targetUserId) {
20748         enforceShellRestriction(UserManager.DISALLOW_DEBUGGING_FEATURES, targetUserId);
20749         UserInfo currentUserInfo;
20750         UserInfo targetUserInfo;
20751         synchronized (this) {
20752             int currentUserId = mUserController.getCurrentUserIdLocked();
20753             currentUserInfo = mUserController.getUserInfo(currentUserId);
20754             targetUserInfo = mUserController.getUserInfo(targetUserId);
20755             if (targetUserInfo == null) {
20756                 Slog.w(TAG, "No user info for user #" + targetUserId);
20757                 return false;
20758             }
20759             if (!targetUserInfo.supportsSwitchTo()) {
20760                 Slog.w(TAG, "Cannot switch to User #" + targetUserId + ": not supported");
20761                 return false;
20762             }
20763             if (targetUserInfo.isManagedProfile()) {
20764                 Slog.w(TAG, "Cannot switch to User #" + targetUserId + ": not a full user");
20765                 return false;
20766             }
20767             mUserController.setTargetUserIdLocked(targetUserId);
20768         }
20769         Pair<UserInfo, UserInfo> userNames = new Pair<>(currentUserInfo, targetUserInfo);
20770         mUiHandler.removeMessages(START_USER_SWITCH_UI_MSG);
20771         mUiHandler.sendMessage(mUiHandler.obtainMessage(START_USER_SWITCH_UI_MSG, userNames));
20772         return true;
20773     }
20774
20775     void scheduleStartProfilesLocked() {
20776         if (!mHandler.hasMessages(START_PROFILES_MSG)) {
20777             mHandler.sendMessageDelayed(mHandler.obtainMessage(START_PROFILES_MSG),
20778                     DateUtils.SECOND_IN_MILLIS);
20779         }
20780     }
20781
20782     @Override
20783     public int stopUser(final int userId, boolean force, final IStopUserCallback callback) {
20784         return mUserController.stopUser(userId, force, callback);
20785     }
20786
20787     @Override
20788     public UserInfo getCurrentUser() {
20789         return mUserController.getCurrentUser();
20790     }
20791
20792     @Override
20793     public boolean isUserRunning(int userId, int flags) {
20794         if (userId != UserHandle.getCallingUserId() && checkCallingPermission(
20795                 INTERACT_ACROSS_USERS) != PackageManager.PERMISSION_GRANTED) {
20796             String msg = "Permission Denial: isUserRunning() from pid="
20797                     + Binder.getCallingPid()
20798                     + ", uid=" + Binder.getCallingUid()
20799                     + " requires " + INTERACT_ACROSS_USERS;
20800             Slog.w(TAG, msg);
20801             throw new SecurityException(msg);
20802         }
20803         synchronized (this) {
20804             return mUserController.isUserRunningLocked(userId, flags);
20805         }
20806     }
20807
20808     @Override
20809     public int[] getRunningUserIds() {
20810         if (checkCallingPermission(INTERACT_ACROSS_USERS)
20811                 != PackageManager.PERMISSION_GRANTED) {
20812             String msg = "Permission Denial: isUserRunning() from pid="
20813                     + Binder.getCallingPid()
20814                     + ", uid=" + Binder.getCallingUid()
20815                     + " requires " + INTERACT_ACROSS_USERS;
20816             Slog.w(TAG, msg);
20817             throw new SecurityException(msg);
20818         }
20819         synchronized (this) {
20820             return mUserController.getStartedUserArrayLocked();
20821         }
20822     }
20823
20824     @Override
20825     public void registerUserSwitchObserver(IUserSwitchObserver observer) {
20826         mUserController.registerUserSwitchObserver(observer);
20827     }
20828
20829     @Override
20830     public void unregisterUserSwitchObserver(IUserSwitchObserver observer) {
20831         mUserController.unregisterUserSwitchObserver(observer);
20832     }
20833
20834     ApplicationInfo getAppInfoForUser(ApplicationInfo info, int userId) {
20835         if (info == null) return null;
20836         ApplicationInfo newInfo = new ApplicationInfo(info);
20837         newInfo.initForUser(userId);
20838         return newInfo;
20839     }
20840
20841     public boolean isUserStopped(int userId) {
20842         synchronized (this) {
20843             return mUserController.getStartedUserStateLocked(userId) == null;
20844         }
20845     }
20846
20847     ActivityInfo getActivityInfoForUser(ActivityInfo aInfo, int userId) {
20848         if (aInfo == null
20849                 || (userId < 1 && aInfo.applicationInfo.uid < UserHandle.PER_USER_RANGE)) {
20850             return aInfo;
20851         }
20852
20853         ActivityInfo info = new ActivityInfo(aInfo);
20854         info.applicationInfo = getAppInfoForUser(info.applicationInfo, userId);
20855         return info;
20856     }
20857
20858     private boolean processSanityChecksLocked(ProcessRecord process) {
20859         if (process == null || process.thread == null) {
20860             return false;
20861         }
20862
20863         boolean isDebuggable = "1".equals(SystemProperties.get(SYSTEM_DEBUGGABLE, "0"));
20864         if (!isDebuggable) {
20865             if ((process.info.flags&ApplicationInfo.FLAG_DEBUGGABLE) == 0) {
20866                 return false;
20867             }
20868         }
20869
20870         return true;
20871     }
20872
20873     public boolean startBinderTracking() throws RemoteException {
20874         synchronized (this) {
20875             mBinderTransactionTrackingEnabled = true;
20876             // TODO: hijacking SET_ACTIVITY_WATCHER, but should be changed to its own
20877             // permission (same as profileControl).
20878             if (checkCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER)
20879                     != PackageManager.PERMISSION_GRANTED) {
20880                 throw new SecurityException("Requires permission "
20881                         + android.Manifest.permission.SET_ACTIVITY_WATCHER);
20882             }
20883
20884             for (int i = 0; i < mLruProcesses.size(); i++) {
20885                 ProcessRecord process = mLruProcesses.get(i);
20886                 if (!processSanityChecksLocked(process)) {
20887                     continue;
20888                 }
20889                 try {
20890                     process.thread.startBinderTracking();
20891                 } catch (RemoteException e) {
20892                     Log.v(TAG, "Process disappared");
20893                 }
20894             }
20895             return true;
20896         }
20897     }
20898
20899     public boolean stopBinderTrackingAndDump(ParcelFileDescriptor fd) throws RemoteException {
20900         try {
20901             synchronized (this) {
20902                 mBinderTransactionTrackingEnabled = false;
20903                 // TODO: hijacking SET_ACTIVITY_WATCHER, but should be changed to its own
20904                 // permission (same as profileControl).
20905                 if (checkCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER)
20906                         != PackageManager.PERMISSION_GRANTED) {
20907                     throw new SecurityException("Requires permission "
20908                             + android.Manifest.permission.SET_ACTIVITY_WATCHER);
20909                 }
20910
20911                 if (fd == null) {
20912                     throw new IllegalArgumentException("null fd");
20913                 }
20914
20915                 PrintWriter pw = new FastPrintWriter(new FileOutputStream(fd.getFileDescriptor()));
20916                 pw.println("Binder transaction traces for all processes.\n");
20917                 for (ProcessRecord process : mLruProcesses) {
20918                     if (!processSanityChecksLocked(process)) {
20919                         continue;
20920                     }
20921
20922                     pw.println("Traces for process: " + process.processName);
20923                     pw.flush();
20924                     try {
20925                         TransferPipe tp = new TransferPipe();
20926                         try {
20927                             process.thread.stopBinderTrackingAndDump(
20928                                     tp.getWriteFd().getFileDescriptor());
20929                             tp.go(fd.getFileDescriptor());
20930                         } finally {
20931                             tp.kill();
20932                         }
20933                     } catch (IOException e) {
20934                         pw.println("Failure while dumping IPC traces from " + process +
20935                                 ".  Exception: " + e);
20936                         pw.flush();
20937                     } catch (RemoteException e) {
20938                         pw.println("Got a RemoteException while dumping IPC traces from " +
20939                                 process + ".  Exception: " + e);
20940                         pw.flush();
20941                     }
20942                 }
20943                 fd = null;
20944                 return true;
20945             }
20946         } finally {
20947             if (fd != null) {
20948                 try {
20949                     fd.close();
20950                 } catch (IOException e) {
20951                 }
20952             }
20953         }
20954     }
20955
20956     private final class LocalService extends ActivityManagerInternal {
20957         @Override
20958         public void onWakefulnessChanged(int wakefulness) {
20959             ActivityManagerService.this.onWakefulnessChanged(wakefulness);
20960         }
20961
20962         @Override
20963         public int startIsolatedProcess(String entryPoint, String[] entryPointArgs,
20964                 String processName, String abiOverride, int uid, Runnable crashHandler) {
20965             return ActivityManagerService.this.startIsolatedProcess(entryPoint, entryPointArgs,
20966                     processName, abiOverride, uid, crashHandler);
20967         }
20968
20969         @Override
20970         public SleepToken acquireSleepToken(String tag) {
20971             Preconditions.checkNotNull(tag);
20972
20973             synchronized (ActivityManagerService.this) {
20974                 SleepTokenImpl token = new SleepTokenImpl(tag);
20975                 mSleepTokens.add(token);
20976                 updateSleepIfNeededLocked();
20977                 return token;
20978             }
20979         }
20980
20981         @Override
20982         public ComponentName getHomeActivityForUser(int userId) {
20983             synchronized (ActivityManagerService.this) {
20984                 ActivityRecord homeActivity = mStackSupervisor.getHomeActivityForUser(userId);
20985                 return homeActivity == null ? null : homeActivity.realActivity;
20986             }
20987         }
20988
20989         @Override
20990         public void onUserRemoved(int userId) {
20991             synchronized (ActivityManagerService.this) {
20992                 ActivityManagerService.this.onUserStoppedLocked(userId);
20993             }
20994         }
20995
20996         @Override
20997         public void onLocalVoiceInteractionStarted(IBinder activity,
20998                 IVoiceInteractionSession voiceSession, IVoiceInteractor voiceInteractor) {
20999             synchronized (ActivityManagerService.this) {
21000                 ActivityManagerService.this.onLocalVoiceInteractionStartedLocked(activity,
21001                         voiceSession, voiceInteractor);
21002             }
21003         }
21004
21005         @Override
21006         public void notifyStartingWindowDrawn() {
21007             synchronized (ActivityManagerService.this) {
21008                 mStackSupervisor.mActivityMetricsLogger.notifyStartingWindowDrawn();
21009             }
21010         }
21011
21012         @Override
21013         public void notifyAppTransitionStarting(int reason) {
21014             synchronized (ActivityManagerService.this) {
21015                 mStackSupervisor.mActivityMetricsLogger.notifyTransitionStarting(reason);
21016             }
21017         }
21018     }
21019
21020     private final class SleepTokenImpl extends SleepToken {
21021         private final String mTag;
21022         private final long mAcquireTime;
21023
21024         public SleepTokenImpl(String tag) {
21025             mTag = tag;
21026             mAcquireTime = SystemClock.uptimeMillis();
21027         }
21028
21029         @Override
21030         public void release() {
21031             synchronized (ActivityManagerService.this) {
21032                 if (mSleepTokens.remove(this)) {
21033                     updateSleepIfNeededLocked();
21034                 }
21035             }
21036         }
21037
21038         @Override
21039         public String toString() {
21040             return "{\"" + mTag + "\", acquire at " + TimeUtils.formatUptime(mAcquireTime) + "}";
21041         }
21042     }
21043
21044     /**
21045      * An implementation of IAppTask, that allows an app to manage its own tasks via
21046      * {@link android.app.ActivityManager.AppTask}.  We keep track of the callingUid to ensure that
21047      * only the process that calls getAppTasks() can call the AppTask methods.
21048      */
21049     class AppTaskImpl extends IAppTask.Stub {
21050         private int mTaskId;
21051         private int mCallingUid;
21052
21053         public AppTaskImpl(int taskId, int callingUid) {
21054             mTaskId = taskId;
21055             mCallingUid = callingUid;
21056         }
21057
21058         private void checkCaller() {
21059             if (mCallingUid != Binder.getCallingUid()) {
21060                 throw new SecurityException("Caller " + mCallingUid
21061                         + " does not match caller of getAppTasks(): " + Binder.getCallingUid());
21062             }
21063         }
21064
21065         @Override
21066         public void finishAndRemoveTask() {
21067             checkCaller();
21068
21069             synchronized (ActivityManagerService.this) {
21070                 long origId = Binder.clearCallingIdentity();
21071                 try {
21072                     // We remove the task from recents to preserve backwards
21073                     if (!removeTaskByIdLocked(mTaskId, false, REMOVE_FROM_RECENTS)) {
21074                         throw new IllegalArgumentException("Unable to find task ID " + mTaskId);
21075                     }
21076                 } finally {
21077                     Binder.restoreCallingIdentity(origId);
21078                 }
21079             }
21080         }
21081
21082         @Override
21083         public ActivityManager.RecentTaskInfo getTaskInfo() {
21084             checkCaller();
21085
21086             synchronized (ActivityManagerService.this) {
21087                 long origId = Binder.clearCallingIdentity();
21088                 try {
21089                     TaskRecord tr = mStackSupervisor.anyTaskForIdLocked(mTaskId);
21090                     if (tr == null) {
21091                         throw new IllegalArgumentException("Unable to find task ID " + mTaskId);
21092                     }
21093                     return createRecentTaskInfoFromTaskRecord(tr);
21094                 } finally {
21095                     Binder.restoreCallingIdentity(origId);
21096                 }
21097             }
21098         }
21099
21100         @Override
21101         public void moveToFront() {
21102             checkCaller();
21103             // Will bring task to front if it already has a root activity.
21104             final long origId = Binder.clearCallingIdentity();
21105             try {
21106                 startActivityFromRecentsInner(mTaskId, null);
21107             } finally {
21108                 Binder.restoreCallingIdentity(origId);
21109             }
21110         }
21111
21112         @Override
21113         public int startActivity(IBinder whoThread, String callingPackage,
21114                 Intent intent, String resolvedType, Bundle bOptions) {
21115             checkCaller();
21116
21117             int callingUser = UserHandle.getCallingUserId();
21118             TaskRecord tr;
21119             IApplicationThread appThread;
21120             synchronized (ActivityManagerService.this) {
21121                 tr = mStackSupervisor.anyTaskForIdLocked(mTaskId);
21122                 if (tr == null) {
21123                     throw new IllegalArgumentException("Unable to find task ID " + mTaskId);
21124                 }
21125                 appThread = ApplicationThreadNative.asInterface(whoThread);
21126                 if (appThread == null) {
21127                     throw new IllegalArgumentException("Bad app thread " + appThread);
21128                 }
21129             }
21130             return mActivityStarter.startActivityMayWait(appThread, -1, callingPackage, intent,
21131                     resolvedType, null, null, null, null, 0, 0, null, null,
21132                     null, bOptions, false, callingUser, null, tr);
21133         }
21134
21135         @Override
21136         public void setExcludeFromRecents(boolean exclude) {
21137             checkCaller();
21138
21139             synchronized (ActivityManagerService.this) {
21140                 long origId = Binder.clearCallingIdentity();
21141                 try {
21142                     TaskRecord tr = mStackSupervisor.anyTaskForIdLocked(mTaskId);
21143                     if (tr == null) {
21144                         throw new IllegalArgumentException("Unable to find task ID " + mTaskId);
21145                     }
21146                     Intent intent = tr.getBaseIntent();
21147                     if (exclude) {
21148                         intent.addFlags(Intent.FLAG_ACTIVITY_EXCLUDE_FROM_RECENTS);
21149                     } else {
21150                         intent.setFlags(intent.getFlags()
21151                                 & ~Intent.FLAG_ACTIVITY_EXCLUDE_FROM_RECENTS);
21152                     }
21153                 } finally {
21154                     Binder.restoreCallingIdentity(origId);
21155                 }
21156             }
21157         }
21158     }
21159
21160     /**
21161      * Kill processes for the user with id userId and that depend on the package named packageName
21162      */
21163     @Override
21164     public void killPackageDependents(String packageName, int userId) {
21165         enforceCallingPermission(android.Manifest.permission.KILL_UID, "killPackageDependents()");
21166         if (packageName == null) {
21167             throw new NullPointerException(
21168                     "Cannot kill the dependents of a package without its name.");
21169         }
21170
21171         long callingId = Binder.clearCallingIdentity();
21172         IPackageManager pm = AppGlobals.getPackageManager();
21173         int pkgUid = -1;
21174         try {
21175             pkgUid = pm.getPackageUid(packageName, MATCH_DEBUG_TRIAGED_MISSING, userId);
21176         } catch (RemoteException e) {
21177         }
21178         if (userId != UserHandle.USER_ALL && pkgUid == -1) {
21179             throw new IllegalArgumentException(
21180                     "Cannot kill dependents of non-existing package " + packageName);
21181         }
21182         try {
21183             synchronized(this) {
21184                 killPackageProcessesLocked(packageName, UserHandle.getAppId(pkgUid), userId,
21185                         ProcessList.FOREGROUND_APP_ADJ, false, true, true, false,
21186                         "dep: " + packageName);
21187             }
21188         } finally {
21189             Binder.restoreCallingIdentity(callingId);
21190         }
21191     }
21192 }