OSDN Git Service

Merge "Prevent windows in pinned stack from gaining window focus."
[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 static android.Manifest.permission.INTERACT_ACROSS_USERS;
20 import static android.Manifest.permission.INTERACT_ACROSS_USERS_FULL;
21 import static android.Manifest.permission.START_TASKS_FROM_RECENTS;
22 import static android.content.pm.PackageManager.PERMISSION_GRANTED;
23 import static com.android.internal.util.XmlUtils.readBooleanAttribute;
24 import static com.android.internal.util.XmlUtils.readIntAttribute;
25 import static com.android.internal.util.XmlUtils.readLongAttribute;
26 import static com.android.internal.util.XmlUtils.writeBooleanAttribute;
27 import static com.android.internal.util.XmlUtils.writeIntAttribute;
28 import static com.android.internal.util.XmlUtils.writeLongAttribute;
29 import static com.android.server.Watchdog.NATIVE_STACKS_OF_INTEREST;
30 import static com.android.server.am.ActivityManagerDebugConfig.*;
31 import static com.android.server.am.TaskRecord.INVALID_TASK_ID;
32 import static com.android.server.am.TaskRecord.LOCK_TASK_AUTH_DONT_LOCK;
33 import static com.android.server.am.TaskRecord.LOCK_TASK_AUTH_LAUNCHABLE_PRIV;
34 import static com.android.server.am.TaskRecord.LOCK_TASK_AUTH_PINNABLE;
35 import static org.xmlpull.v1.XmlPullParser.END_DOCUMENT;
36 import static org.xmlpull.v1.XmlPullParser.START_TAG;
37
38 import com.google.android.collect.Lists;
39 import com.google.android.collect.Maps;
40
41 import android.Manifest;
42 import android.app.AppOpsManager;
43 import android.app.ApplicationThreadNative;
44 import android.app.BroadcastOptions;
45 import android.app.IActivityContainer;
46 import android.app.IActivityContainerCallback;
47 import android.app.IAppTask;
48 import android.app.ITaskStackListener;
49 import android.app.ProfilerInfo;
50 import android.app.assist.AssistContent;
51 import android.app.assist.AssistStructure;
52 import android.app.usage.UsageEvents;
53 import android.app.usage.UsageStatsManagerInternal;
54 import android.appwidget.AppWidgetManager;
55 import android.content.pm.PackageManagerInternal;
56 import android.content.pm.PermissionInfo;
57 import android.content.res.Resources;
58 import android.graphics.Bitmap;
59 import android.graphics.Point;
60 import android.graphics.Rect;
61 import android.os.BatteryStats;
62 import android.os.PersistableBundle;
63 import android.os.PowerManager;
64 import android.os.Trace;
65 import android.os.TransactionTooLargeException;
66 import android.os.WorkSource;
67 import android.os.storage.IMountService;
68 import android.os.storage.MountServiceInternal;
69 import android.os.storage.StorageManager;
70 import android.service.voice.IVoiceInteractionSession;
71 import android.service.voice.VoiceInteractionSession;
72 import android.util.ArrayMap;
73 import android.util.ArraySet;
74 import android.util.DebugUtils;
75 import android.util.SparseIntArray;
76 import android.view.Display;
77
78 import com.android.internal.R;
79 import com.android.internal.annotations.GuardedBy;
80 import com.android.internal.app.AssistUtils;
81 import com.android.internal.app.DumpHeapActivity;
82 import com.android.internal.app.IAppOpsCallback;
83 import com.android.internal.app.IAppOpsService;
84 import com.android.internal.app.IVoiceInteractor;
85 import com.android.internal.app.ProcessMap;
86 import com.android.internal.app.ProcessStats;
87 import com.android.internal.app.SystemUserHomeActivity;
88 import com.android.internal.os.BackgroundThread;
89 import com.android.internal.os.BatteryStatsImpl;
90 import com.android.internal.os.IResultReceiver;
91 import com.android.internal.os.ProcessCpuTracker;
92 import com.android.internal.os.TransferPipe;
93 import com.android.internal.os.Zygote;
94 import com.android.internal.util.ArrayUtils;
95 import com.android.internal.util.FastPrintWriter;
96 import com.android.internal.util.FastXmlSerializer;
97 import com.android.internal.util.MemInfoReader;
98 import com.android.internal.util.Preconditions;
99 import com.android.server.AppOpsService;
100 import com.android.server.AttributeCache;
101 import com.android.server.DeviceIdleController;
102 import com.android.server.IntentResolver;
103 import com.android.server.LocalServices;
104 import com.android.server.ServiceThread;
105 import com.android.server.SystemService;
106 import com.android.server.SystemServiceManager;
107 import com.android.server.Watchdog;
108 import com.android.server.am.ActivityStack.ActivityState;
109 import com.android.server.firewall.IntentFirewall;
110 import com.android.server.pm.Installer;
111 import com.android.server.statusbar.StatusBarManagerInternal;
112 import com.android.server.wm.AppTransition;
113 import com.android.server.wm.WindowManagerService;
114
115 import org.xmlpull.v1.XmlPullParser;
116 import org.xmlpull.v1.XmlPullParserException;
117 import org.xmlpull.v1.XmlSerializer;
118
119 import android.Manifest;
120 import android.app.Activity;
121 import android.app.ActivityManager;
122 import android.app.ActivityManager.RunningTaskInfo;
123 import android.app.ActivityManager.StackId;
124 import android.app.ActivityManager.StackInfo;
125 import android.app.ActivityManager.TaskThumbnailInfo;
126 import android.app.ActivityManagerInternal;
127 import android.app.ActivityManagerInternal.SleepToken;
128 import android.app.ActivityManagerNative;
129 import android.app.ActivityOptions;
130 import android.app.ActivityThread;
131 import android.app.AlertDialog;
132 import android.app.AppGlobals;
133 import android.app.AppOpsManager;
134 import android.app.ApplicationErrorReport;
135 import android.app.ApplicationThreadNative;
136 import android.app.BroadcastOptions;
137 import android.app.Dialog;
138 import android.app.IActivityContainer;
139 import android.app.IActivityContainerCallback;
140 import android.app.IActivityController;
141 import android.app.IAppTask;
142 import android.app.IApplicationThread;
143 import android.app.IInstrumentationWatcher;
144 import android.app.INotificationManager;
145 import android.app.IProcessObserver;
146 import android.app.IServiceConnection;
147 import android.app.IStopUserCallback;
148 import android.app.ITaskStackListener;
149 import android.app.IUiAutomationConnection;
150 import android.app.IUidObserver;
151 import android.app.IUserSwitchObserver;
152 import android.app.Instrumentation;
153 import android.app.Notification;
154 import android.app.NotificationManager;
155 import android.app.PendingIntent;
156 import android.app.ProfilerInfo;
157 import android.app.admin.DevicePolicyManager;
158 import android.app.assist.AssistContent;
159 import android.app.assist.AssistStructure;
160 import android.app.backup.IBackupManager;
161 import android.app.usage.UsageEvents;
162 import android.app.usage.UsageStatsManagerInternal;
163 import android.appwidget.AppWidgetManager;
164 import android.content.ActivityNotFoundException;
165 import android.content.BroadcastReceiver;
166 import android.content.ClipData;
167 import android.content.ComponentCallbacks2;
168 import android.content.ComponentName;
169 import android.content.ContentProvider;
170 import android.content.ContentResolver;
171 import android.content.Context;
172 import android.content.DialogInterface;
173 import android.content.IContentProvider;
174 import android.content.IIntentReceiver;
175 import android.content.IIntentSender;
176 import android.content.Intent;
177 import android.content.IntentFilter;
178 import android.content.IntentSender;
179 import android.content.pm.ActivityInfo;
180 import android.content.pm.ApplicationInfo;
181 import android.content.pm.ConfigurationInfo;
182 import android.content.pm.IPackageDataObserver;
183 import android.content.pm.IPackageManager;
184 import android.content.pm.InstrumentationInfo;
185 import android.content.pm.PackageInfo;
186 import android.content.pm.PackageManager;
187 import android.content.pm.PackageManager.NameNotFoundException;
188 import android.content.pm.ParceledListSlice;
189 import android.content.pm.PathPermission;
190 import android.content.pm.PermissionInfo;
191 import android.content.pm.ProviderInfo;
192 import android.content.pm.ResolveInfo;
193 import android.content.pm.ServiceInfo;
194 import android.content.pm.UserInfo;
195 import android.content.res.CompatibilityInfo;
196 import android.content.res.Configuration;
197 import android.content.res.Resources;
198 import android.graphics.Bitmap;
199 import android.graphics.Point;
200 import android.graphics.Rect;
201 import android.net.Proxy;
202 import android.net.ProxyInfo;
203 import android.net.Uri;
204 import android.os.BatteryStats;
205 import android.os.Binder;
206 import android.os.Build;
207 import android.os.Bundle;
208 import android.os.Debug;
209 import android.os.DropBoxManager;
210 import android.os.Environment;
211 import android.os.FactoryTest;
212 import android.os.FileObserver;
213 import android.os.FileUtils;
214 import android.os.Handler;
215 import android.os.IBinder;
216 import android.os.IPermissionController;
217 import android.os.IProcessInfoService;
218 import android.os.Looper;
219 import android.os.Message;
220 import android.os.Parcel;
221 import android.os.ParcelFileDescriptor;
222 import android.os.PersistableBundle;
223 import android.os.PowerManager;
224 import android.os.PowerManagerInternal;
225 import android.os.Process;
226 import android.os.RemoteCallbackList;
227 import android.os.RemoteException;
228 import android.os.ResultReceiver;
229 import android.os.ServiceManager;
230 import android.os.StrictMode;
231 import android.os.SystemClock;
232 import android.os.SystemProperties;
233 import android.os.Trace;
234 import android.os.TransactionTooLargeException;
235 import android.os.UpdateLock;
236 import android.os.UserHandle;
237 import android.os.UserManager;
238 import android.os.WorkSource;
239 import android.os.storage.IMountService;
240 import android.os.storage.MountServiceInternal;
241 import android.os.storage.StorageManager;
242 import android.provider.Settings;
243 import android.service.voice.IVoiceInteractionSession;
244 import android.service.voice.VoiceInteractionSession;
245 import android.text.format.DateUtils;
246 import android.text.format.Time;
247 import android.util.ArrayMap;
248 import android.util.ArraySet;
249 import android.util.AtomicFile;
250 import android.util.DebugUtils;
251 import android.util.EventLog;
252 import android.util.LocaleList;
253 import android.util.Log;
254 import android.util.Pair;
255 import android.util.PrintWriterPrinter;
256 import android.util.Slog;
257 import android.util.SparseArray;
258 import android.util.TimeUtils;
259 import android.util.Xml;
260 import android.view.Display;
261 import android.view.Gravity;
262 import android.view.LayoutInflater;
263 import android.view.View;
264 import android.view.WindowManager;
265
266 import java.io.BufferedInputStream;
267 import java.io.BufferedOutputStream;
268 import java.io.DataInputStream;
269 import java.io.DataOutputStream;
270 import java.io.File;
271 import java.io.FileDescriptor;
272 import java.io.FileInputStream;
273 import java.io.FileNotFoundException;
274 import java.io.FileOutputStream;
275 import java.io.IOException;
276 import java.io.InputStreamReader;
277 import java.io.PrintWriter;
278 import java.io.StringWriter;
279 import java.lang.ref.WeakReference;
280 import java.nio.charset.StandardCharsets;
281 import java.util.ArrayList;
282 import java.util.Arrays;
283 import java.util.Collections;
284 import java.util.Comparator;
285 import java.util.HashMap;
286 import java.util.HashSet;
287 import java.util.Iterator;
288 import java.util.List;
289 import java.util.Locale;
290 import java.util.Map;
291 import java.util.Set;
292 import java.util.concurrent.atomic.AtomicBoolean;
293 import java.util.concurrent.atomic.AtomicLong;
294
295 import dalvik.system.VMRuntime;
296 import libcore.io.IoUtils;
297 import libcore.util.EmptyArray;
298
299 import static android.Manifest.permission.INTERACT_ACROSS_USERS;
300 import static android.Manifest.permission.INTERACT_ACROSS_USERS_FULL;
301 import static android.Manifest.permission.START_TASKS_FROM_RECENTS;
302 import static android.app.ActivityManager.RESIZE_MODE_PRESERVE_WINDOW;
303 import static android.app.ActivityManager.StackId.DOCKED_STACK_ID;
304 import static android.app.ActivityManager.StackId.FREEFORM_WORKSPACE_STACK_ID;
305 import static android.app.ActivityManager.StackId.FULLSCREEN_WORKSPACE_STACK_ID;
306 import static android.app.ActivityManager.StackId.HOME_STACK_ID;
307 import static android.app.ActivityManager.StackId.INVALID_STACK_ID;
308 import static android.content.pm.PackageManager.FEATURE_FREEFORM_WINDOW_MANAGEMENT;
309 import static android.content.pm.PackageManager.PERMISSION_GRANTED;
310 import static android.provider.Settings.Global.ALWAYS_FINISH_ACTIVITIES;
311 import static android.provider.Settings.Global.DEBUG_APP;
312 import static android.provider.Settings.Global.DEVELOPMENT_FORCE_RESIZABLE_ACTIVITIES;
313 import static android.provider.Settings.Global.DEVELOPMENT_FORCE_RTL;
314 import static android.provider.Settings.Global.WAIT_FOR_DEBUGGER;
315 import static com.android.internal.util.XmlUtils.readBooleanAttribute;
316 import static com.android.internal.util.XmlUtils.readIntAttribute;
317 import static com.android.internal.util.XmlUtils.readLongAttribute;
318 import static com.android.internal.util.XmlUtils.writeBooleanAttribute;
319 import static com.android.internal.util.XmlUtils.writeIntAttribute;
320 import static com.android.internal.util.XmlUtils.writeLongAttribute;
321 import static com.android.server.Watchdog.NATIVE_STACKS_OF_INTEREST;
322 import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_ALL;
323 import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_BACKUP;
324 import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_BROADCAST;
325 import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_BROADCAST_BACKGROUND;
326 import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_BROADCAST_LIGHT;
327 import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_CLEANUP;
328 import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_CONFIGURATION;
329 import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_FOCUS;
330 import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_IMMERSIVE;
331 import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_LOCKSCREEN;
332 import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_LOCKTASK;
333 import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_LRU;
334 import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_MU;
335 import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_OOM_ADJ;
336 import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_POWER;
337 import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_POWER_QUICK;
338 import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_PROCESSES;
339 import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_PROCESS_OBSERVERS;
340 import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_PROVIDER;
341 import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_PSS;
342 import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_RECENTS;
343 import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_SERVICE;
344 import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_STACK;
345 import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_SWITCH;
346 import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_TASKS;
347 import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_UID_OBSERVERS;
348 import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_URI_PERMISSION;
349 import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_USAGE_STATS;
350 import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_VISIBILITY;
351 import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_VISIBLE_BEHIND;
352 import static com.android.server.am.ActivityManagerDebugConfig.POSTFIX_BACKUP;
353 import static com.android.server.am.ActivityManagerDebugConfig.POSTFIX_BROADCAST;
354 import static com.android.server.am.ActivityManagerDebugConfig.POSTFIX_CLEANUP;
355 import static com.android.server.am.ActivityManagerDebugConfig.POSTFIX_CONFIGURATION;
356 import static com.android.server.am.ActivityManagerDebugConfig.POSTFIX_FOCUS;
357 import static com.android.server.am.ActivityManagerDebugConfig.POSTFIX_IMMERSIVE;
358 import static com.android.server.am.ActivityManagerDebugConfig.POSTFIX_LOCKSCREEN;
359 import static com.android.server.am.ActivityManagerDebugConfig.POSTFIX_LOCKTASK;
360 import static com.android.server.am.ActivityManagerDebugConfig.POSTFIX_LRU;
361 import static com.android.server.am.ActivityManagerDebugConfig.POSTFIX_MU;
362 import static com.android.server.am.ActivityManagerDebugConfig.POSTFIX_OOM_ADJ;
363 import static com.android.server.am.ActivityManagerDebugConfig.POSTFIX_POWER;
364 import static com.android.server.am.ActivityManagerDebugConfig.POSTFIX_PROCESSES;
365 import static com.android.server.am.ActivityManagerDebugConfig.POSTFIX_PROCESS_OBSERVERS;
366 import static com.android.server.am.ActivityManagerDebugConfig.POSTFIX_PROVIDER;
367 import static com.android.server.am.ActivityManagerDebugConfig.POSTFIX_PSS;
368 import static com.android.server.am.ActivityManagerDebugConfig.POSTFIX_RECENTS;
369 import static com.android.server.am.ActivityManagerDebugConfig.POSTFIX_SERVICE;
370 import static com.android.server.am.ActivityManagerDebugConfig.POSTFIX_STACK;
371 import static com.android.server.am.ActivityManagerDebugConfig.POSTFIX_SWITCH;
372 import static com.android.server.am.ActivityManagerDebugConfig.POSTFIX_UID_OBSERVERS;
373 import static com.android.server.am.ActivityManagerDebugConfig.POSTFIX_URI_PERMISSION;
374 import static com.android.server.am.ActivityManagerDebugConfig.POSTFIX_VISIBILITY;
375 import static com.android.server.am.ActivityManagerDebugConfig.POSTFIX_VISIBLE_BEHIND;
376 import static com.android.server.am.ActivityManagerDebugConfig.TAG_AM;
377 import static com.android.server.am.ActivityManagerDebugConfig.TAG_WITH_CLASS_NAME;
378 import static com.android.server.am.ActivityStackSupervisor.FORCE_FOCUS;
379 import static com.android.server.am.ActivityStackSupervisor.ON_TOP;
380 import static com.android.server.am.ActivityStackSupervisor.PRESERVE_WINDOWS;
381 import static com.android.server.am.ActivityStackSupervisor.RESTORE_FROM_RECENTS;
382 import static com.android.server.am.TaskRecord.INVALID_TASK_ID;
383 import static com.android.server.am.TaskRecord.LOCK_TASK_AUTH_DONT_LOCK;
384 import static com.android.server.am.TaskRecord.LOCK_TASK_AUTH_LAUNCHABLE_PRIV;
385 import static com.android.server.am.TaskRecord.LOCK_TASK_AUTH_PINNABLE;
386 import static org.xmlpull.v1.XmlPullParser.END_DOCUMENT;
387 import static org.xmlpull.v1.XmlPullParser.START_TAG;
388
389 public final class ActivityManagerService extends ActivityManagerNative
390         implements Watchdog.Monitor, BatteryStatsImpl.BatteryCallback {
391
392     // File that stores last updated system version and called preboot receivers
393     static final String CALLED_PRE_BOOTS_FILENAME = "called_pre_boots.dat";
394
395     private static final String TAG = TAG_WITH_CLASS_NAME ? "ActivityManagerService" : TAG_AM;
396     private static final String TAG_BACKUP = TAG + POSTFIX_BACKUP;
397     private static final String TAG_BROADCAST = TAG + POSTFIX_BROADCAST;
398     private static final String TAG_CLEANUP = TAG + POSTFIX_CLEANUP;
399     private static final String TAG_CONFIGURATION = TAG + POSTFIX_CONFIGURATION;
400     private static final String TAG_FOCUS = TAG + POSTFIX_FOCUS;
401     private static final String TAG_IMMERSIVE = TAG + POSTFIX_IMMERSIVE;
402     private static final String TAG_LOCKSCREEN = TAG + POSTFIX_LOCKSCREEN;
403     private static final String TAG_LOCKTASK = TAG + POSTFIX_LOCKTASK;
404     private static final String TAG_LRU = TAG + POSTFIX_LRU;
405     private static final String TAG_MU = TAG + POSTFIX_MU;
406     private static final String TAG_OOM_ADJ = TAG + POSTFIX_OOM_ADJ;
407     private static final String TAG_POWER = TAG + POSTFIX_POWER;
408     private static final String TAG_PROCESS_OBSERVERS = TAG + POSTFIX_PROCESS_OBSERVERS;
409     private static final String TAG_PROCESSES = TAG + POSTFIX_PROCESSES;
410     private static final String TAG_PROVIDER = TAG + POSTFIX_PROVIDER;
411     private static final String TAG_PSS = TAG + POSTFIX_PSS;
412     private static final String TAG_RECENTS = TAG + POSTFIX_RECENTS;
413     private static final String TAG_SERVICE = TAG + POSTFIX_SERVICE;
414     private static final String TAG_STACK = TAG + POSTFIX_STACK;
415     private static final String TAG_SWITCH = TAG + POSTFIX_SWITCH;
416     private static final String TAG_UID_OBSERVERS = TAG + POSTFIX_UID_OBSERVERS;
417     private static final String TAG_URI_PERMISSION = TAG + POSTFIX_URI_PERMISSION;
418     private static final String TAG_VISIBILITY = TAG + POSTFIX_VISIBILITY;
419     private static final String TAG_VISIBLE_BEHIND = TAG + POSTFIX_VISIBLE_BEHIND;
420
421     /** Control over CPU and battery monitoring */
422     // write battery stats every 30 minutes.
423     static final long BATTERY_STATS_TIME = 30 * 60 * 1000;
424     static final boolean MONITOR_CPU_USAGE = true;
425     // don't sample cpu less than every 5 seconds.
426     static final long MONITOR_CPU_MIN_TIME = 5 * 1000;
427     // wait possibly forever for next cpu sample.
428     static final long MONITOR_CPU_MAX_TIME = 0x0fffffff;
429     static final boolean MONITOR_THREAD_CPU_USAGE = false;
430
431     // The flags that are set for all calls we make to the package manager.
432     static final int STOCK_PM_FLAGS = PackageManager.GET_SHARED_LIBRARY_FILES;
433
434     private static final String SYSTEM_DEBUGGABLE = "ro.debuggable";
435
436     static final boolean IS_USER_BUILD = "user".equals(Build.TYPE);
437
438     // Amount of time after a call to stopAppSwitches() during which we will
439     // prevent further untrusted switches from happening.
440     static final long APP_SWITCH_DELAY_TIME = 5*1000;
441
442     // How long we wait for a launched process to attach to the activity manager
443     // before we decide it's never going to come up for real.
444     static final int PROC_START_TIMEOUT = 10*1000;
445     // How long we wait for an attached process to publish its content providers
446     // before we decide it must be hung.
447     static final int CONTENT_PROVIDER_PUBLISH_TIMEOUT = 10*1000;
448
449     // How long we will retain processes hosting content providers in the "last activity"
450     // state before allowing them to drop down to the regular cached LRU list.  This is
451     // to avoid thrashing of provider processes under low memory situations.
452     static final int CONTENT_PROVIDER_RETAIN_TIME = 20*1000;
453
454     // How long we wait for a launched process to attach to the activity manager
455     // before we decide it's never going to come up for real, when the process was
456     // started with a wrapper for instrumentation (such as Valgrind) because it
457     // could take much longer than usual.
458     static final int PROC_START_TIMEOUT_WITH_WRAPPER = 1200*1000;
459
460     // How long to wait after going idle before forcing apps to GC.
461     static final int GC_TIMEOUT = 5*1000;
462
463     // The minimum amount of time between successive GC requests for a process.
464     static final int GC_MIN_INTERVAL = 60*1000;
465
466     // The minimum amount of time between successive PSS requests for a process.
467     static final int FULL_PSS_MIN_INTERVAL = 10*60*1000;
468
469     // The minimum amount of time between successive PSS requests for a process
470     // when the request is due to the memory state being lowered.
471     static final int FULL_PSS_LOWERED_INTERVAL = 2*60*1000;
472
473     // The rate at which we check for apps using excessive power -- 15 mins.
474     static final int POWER_CHECK_DELAY = (DEBUG_POWER_QUICK ? 2 : 15) * 60*1000;
475
476     // The minimum sample duration we will allow before deciding we have
477     // enough data on wake locks to start killing things.
478     static final int WAKE_LOCK_MIN_CHECK_DURATION = (DEBUG_POWER_QUICK ? 1 : 5) * 60*1000;
479
480     // The minimum sample duration we will allow before deciding we have
481     // enough data on CPU usage to start killing things.
482     static final int CPU_MIN_CHECK_DURATION = (DEBUG_POWER_QUICK ? 1 : 5) * 60*1000;
483
484     // How long we allow a receiver to run before giving up on it.
485     static final int BROADCAST_FG_TIMEOUT = 10*1000;
486     static final int BROADCAST_BG_TIMEOUT = 60*1000;
487
488     // How long we wait until we timeout on key dispatching.
489     static final int KEY_DISPATCHING_TIMEOUT = 5*1000;
490
491     // How long we wait until we timeout on key dispatching during instrumentation.
492     static final int INSTRUMENTATION_KEY_DISPATCHING_TIMEOUT = 60*1000;
493
494     // This is the amount of time an app needs to be running a foreground service before
495     // we will consider it to be doing interaction for usage stats.
496     static final int SERVICE_USAGE_INTERACTION_TIME = 30*60*1000;
497
498     // Maximum amount of time we will allow to elapse before re-reporting usage stats
499     // interaction with foreground processes.
500     static final long USAGE_STATS_INTERACTION_INTERVAL = 24*60*60*1000L;
501
502     // Maximum number of users we allow to be running at a time.
503     static final int MAX_RUNNING_USERS = 3;
504
505     // This is the amount of time we allow an app to settle after it goes into the background,
506     // before we start restricting what it can do.
507     static final int BACKGROUND_SETTLE_TIME = 1*60*1000;
508
509     // How long to wait in getAssistContextExtras for the activity and foreground services
510     // to respond with the result.
511     static final int PENDING_ASSIST_EXTRAS_TIMEOUT = 500;
512
513     // How long top wait when going through the modern assist (which doesn't need to block
514     // on getting this result before starting to launch its UI).
515     static final int PENDING_ASSIST_EXTRAS_LONG_TIMEOUT = 2000;
516
517     // Maximum number of persisted Uri grants a package is allowed
518     static final int MAX_PERSISTED_URI_GRANTS = 128;
519
520     static final int MY_PID = Process.myPid();
521
522     static final String[] EMPTY_STRING_ARRAY = new String[0];
523
524     // How many bytes to write into the dropbox log before truncating
525     static final int DROPBOX_MAX_SIZE = 256 * 1024;
526
527     // Access modes for handleIncomingUser.
528     static final int ALLOW_NON_FULL = 0;
529     static final int ALLOW_NON_FULL_IN_PROFILE = 1;
530     static final int ALLOW_FULL_ONLY = 2;
531
532     static final int LAST_PREBOOT_DELIVERED_FILE_VERSION = 10000;
533
534     // Delay in notifying task stack change listeners (in millis)
535     static final int NOTIFY_TASK_STACK_CHANGE_LISTENERS_DELAY = 100;
536
537     // Necessary ApplicationInfo flags to mark an app as persistent
538     private static final int PERSISTENT_MASK =
539             ApplicationInfo.FLAG_SYSTEM|ApplicationInfo.FLAG_PERSISTENT;
540
541
542     // Delay to disable app launch boost
543     static final int APP_BOOST_MESSAGE_DELAY = 3000;
544     // Lower delay than APP_BOOST_MESSAGE_DELAY to disable the boost
545     static final int APP_BOOST_TIMEOUT = 2500;
546
547     // Used to indicate that a task is removed it should also be removed from recents.
548     private static final boolean REMOVE_FROM_RECENTS = true;
549
550     private static native int nativeMigrateToBoost();
551     private static native int nativeMigrateFromBoost();
552     private boolean mIsBoosted = false;
553     private long mBoostStartTime = 0;
554
555     /** All system services */
556     SystemServiceManager mSystemServiceManager;
557
558     private Installer mInstaller;
559
560     /** Run all ActivityStacks through this */
561     ActivityStackSupervisor mStackSupervisor;
562
563     /** Task stack change listeners. */
564     private RemoteCallbackList<ITaskStackListener> mTaskStackListeners =
565             new RemoteCallbackList<ITaskStackListener>();
566
567     public IntentFirewall mIntentFirewall;
568
569     // Whether we should show our dialogs (ANR, crash, etc) or just perform their
570     // default actuion automatically.  Important for devices without direct input
571     // devices.
572     private boolean mShowDialogs = true;
573
574     BroadcastQueue mFgBroadcastQueue;
575     BroadcastQueue mBgBroadcastQueue;
576     // Convenient for easy iteration over the queues. Foreground is first
577     // so that dispatch of foreground broadcasts gets precedence.
578     final BroadcastQueue[] mBroadcastQueues = new BroadcastQueue[2];
579
580     BroadcastQueue broadcastQueueForIntent(Intent intent) {
581         final boolean isFg = (intent.getFlags() & Intent.FLAG_RECEIVER_FOREGROUND) != 0;
582         if (DEBUG_BROADCAST_BACKGROUND) Slog.i(TAG_BROADCAST,
583                 "Broadcast intent " + intent + " on "
584                 + (isFg ? "foreground" : "background") + " queue");
585         return (isFg) ? mFgBroadcastQueue : mBgBroadcastQueue;
586     }
587
588     /**
589      * Activity we have told the window manager to have key focus.
590      */
591     ActivityRecord mFocusedActivity = null;
592
593     /**
594      * User id of the last activity mFocusedActivity was set to.
595      */
596     private int mLastFocusedUserId;
597
598     /**
599      * If non-null, we are tracking the time the user spends in the currently focused app.
600      */
601     private AppTimeTracker mCurAppTimeTracker;
602
603     /**
604      * List of intents that were used to start the most recent tasks.
605      */
606     private final RecentTasks mRecentTasks;
607
608     /**
609      * For addAppTask: cached of the last activity component that was added.
610      */
611     ComponentName mLastAddedTaskComponent;
612
613     /**
614      * For addAppTask: cached of the last activity uid that was added.
615      */
616     int mLastAddedTaskUid;
617
618     /**
619      * For addAppTask: cached of the last ActivityInfo that was added.
620      */
621     ActivityInfo mLastAddedTaskActivity;
622
623     /**
624      * List of packages whitelisted by DevicePolicyManager for locktask. Indexed by userId.
625      */
626     SparseArray<String[]> mLockTaskPackages = new SparseArray<>();
627
628     /**
629      * The package name of the DeviceOwner. This package is not permitted to have its data cleared.
630      */
631     String mDeviceOwnerName;
632
633     final UserController mUserController;
634
635     public class PendingAssistExtras extends Binder implements Runnable {
636         public final ActivityRecord activity;
637         public final Bundle extras;
638         public final Intent intent;
639         public final String hint;
640         public final IResultReceiver receiver;
641         public final int userHandle;
642         public boolean haveResult = false;
643         public Bundle result = null;
644         public AssistStructure structure = null;
645         public AssistContent content = null;
646         public PendingAssistExtras(ActivityRecord _activity, Bundle _extras, Intent _intent,
647                 String _hint, IResultReceiver _receiver, int _userHandle) {
648             activity = _activity;
649             extras = _extras;
650             intent = _intent;
651             hint = _hint;
652             receiver = _receiver;
653             userHandle = _userHandle;
654         }
655         @Override
656         public void run() {
657             Slog.w(TAG, "getAssistContextExtras failed: timeout retrieving from " + activity);
658             synchronized (this) {
659                 haveResult = true;
660                 notifyAll();
661             }
662             pendingAssistExtrasTimedOut(this);
663         }
664     }
665
666     final ArrayList<PendingAssistExtras> mPendingAssistExtras
667             = new ArrayList<PendingAssistExtras>();
668
669     /**
670      * Process management.
671      */
672     final ProcessList mProcessList = new ProcessList();
673
674     /**
675      * All of the applications we currently have running organized by name.
676      * The keys are strings of the application package name (as
677      * returned by the package manager), and the keys are ApplicationRecord
678      * objects.
679      */
680     final ProcessMap<ProcessRecord> mProcessNames = new ProcessMap<ProcessRecord>();
681
682     /**
683      * Tracking long-term execution of processes to look for abuse and other
684      * bad app behavior.
685      */
686     final ProcessStatsService mProcessStats;
687
688     /**
689      * The currently running isolated processes.
690      */
691     final SparseArray<ProcessRecord> mIsolatedProcesses = new SparseArray<ProcessRecord>();
692
693     /**
694      * Counter for assigning isolated process uids, to avoid frequently reusing the
695      * same ones.
696      */
697     int mNextIsolatedProcessUid = 0;
698
699     /**
700      * The currently running heavy-weight process, if any.
701      */
702     ProcessRecord mHeavyWeightProcess = null;
703
704     /**
705      * The last time that various processes have crashed.
706      */
707     final ProcessMap<Long> mProcessCrashTimes = new ProcessMap<Long>();
708
709     /**
710      * Information about a process that is currently marked as bad.
711      */
712     static final class BadProcessInfo {
713         BadProcessInfo(long time, String shortMsg, String longMsg, String stack) {
714             this.time = time;
715             this.shortMsg = shortMsg;
716             this.longMsg = longMsg;
717             this.stack = stack;
718         }
719
720         final long time;
721         final String shortMsg;
722         final String longMsg;
723         final String stack;
724     }
725
726     /**
727      * Set of applications that we consider to be bad, and will reject
728      * incoming broadcasts from (which the user has no control over).
729      * Processes are added to this set when they have crashed twice within
730      * a minimum amount of time; they are removed from it when they are
731      * later restarted (hopefully due to some user action).  The value is the
732      * time it was added to the list.
733      */
734     final ProcessMap<BadProcessInfo> mBadProcesses = new ProcessMap<BadProcessInfo>();
735
736     /**
737      * All of the processes we currently have running organized by pid.
738      * The keys are the pid running the application.
739      *
740      * <p>NOTE: This object is protected by its own lock, NOT the global
741      * activity manager lock!
742      */
743     final SparseArray<ProcessRecord> mPidsSelfLocked = new SparseArray<ProcessRecord>();
744
745     /**
746      * All of the processes that have been forced to be foreground.  The key
747      * is the pid of the caller who requested it (we hold a death
748      * link on it).
749      */
750     abstract class ForegroundToken implements IBinder.DeathRecipient {
751         int pid;
752         IBinder token;
753     }
754     final SparseArray<ForegroundToken> mForegroundProcesses = new SparseArray<ForegroundToken>();
755
756     /**
757      * List of records for processes that someone had tried to start before the
758      * system was ready.  We don't start them at that point, but ensure they
759      * are started by the time booting is complete.
760      */
761     final ArrayList<ProcessRecord> mProcessesOnHold = new ArrayList<ProcessRecord>();
762
763     /**
764      * List of persistent applications that are in the process
765      * of being started.
766      */
767     final ArrayList<ProcessRecord> mPersistentStartingProcesses = new ArrayList<ProcessRecord>();
768
769     /**
770      * Processes that are being forcibly torn down.
771      */
772     final ArrayList<ProcessRecord> mRemovedProcesses = new ArrayList<ProcessRecord>();
773
774     /**
775      * List of running applications, sorted by recent usage.
776      * The first entry in the list is the least recently used.
777      */
778     final ArrayList<ProcessRecord> mLruProcesses = new ArrayList<ProcessRecord>();
779
780     /**
781      * Where in mLruProcesses that the processes hosting activities start.
782      */
783     int mLruProcessActivityStart = 0;
784
785     /**
786      * Where in mLruProcesses that the processes hosting services start.
787      * This is after (lower index) than mLruProcessesActivityStart.
788      */
789     int mLruProcessServiceStart = 0;
790
791     /**
792      * List of processes that should gc as soon as things are idle.
793      */
794     final ArrayList<ProcessRecord> mProcessesToGc = new ArrayList<ProcessRecord>();
795
796     /**
797      * Processes we want to collect PSS data from.
798      */
799     final ArrayList<ProcessRecord> mPendingPssProcesses = new ArrayList<ProcessRecord>();
800
801     private boolean mBinderTransactionTrackingEnabled = false;
802
803     /**
804      * Last time we requested PSS data of all processes.
805      */
806     long mLastFullPssTime = SystemClock.uptimeMillis();
807
808     /**
809      * If set, the next time we collect PSS data we should do a full collection
810      * with data from native processes and the kernel.
811      */
812     boolean mFullPssPending = false;
813
814     /**
815      * This is the process holding what we currently consider to be
816      * the "home" activity.
817      */
818     ProcessRecord mHomeProcess;
819
820     /**
821      * This is the process holding the activity the user last visited that
822      * is in a different process from the one they are currently in.
823      */
824     ProcessRecord mPreviousProcess;
825
826     /**
827      * The time at which the previous process was last visible.
828      */
829     long mPreviousProcessVisibleTime;
830
831     /**
832      * Track all uids that have actively running processes.
833      */
834     final SparseArray<UidRecord> mActiveUids = new SparseArray<>();
835
836     /**
837      * This is for verifying the UID report flow.
838      */
839     static final boolean VALIDATE_UID_STATES = true;
840     final SparseArray<UidRecord> mValidateUids = new SparseArray<>();
841
842     /**
843      * Packages that the user has asked to have run in screen size
844      * compatibility mode instead of filling the screen.
845      */
846     final CompatModePackages mCompatModePackages;
847
848     /**
849      * Set of IntentSenderRecord objects that are currently active.
850      */
851     final HashMap<PendingIntentRecord.Key, WeakReference<PendingIntentRecord>> mIntentSenderRecords
852             = new HashMap<PendingIntentRecord.Key, WeakReference<PendingIntentRecord>>();
853
854     /**
855      * Fingerprints (hashCode()) of stack traces that we've
856      * already logged DropBox entries for.  Guarded by itself.  If
857      * something (rogue user app) forces this over
858      * MAX_DUP_SUPPRESSED_STACKS entries, the contents are cleared.
859      */
860     private final HashSet<Integer> mAlreadyLoggedViolatedStacks = new HashSet<Integer>();
861     private static final int MAX_DUP_SUPPRESSED_STACKS = 5000;
862
863     /**
864      * Strict Mode background batched logging state.
865      *
866      * The string buffer is guarded by itself, and its lock is also
867      * used to determine if another batched write is already
868      * in-flight.
869      */
870     private final StringBuilder mStrictModeBuffer = new StringBuilder();
871
872     /**
873      * Keeps track of all IIntentReceivers that have been registered for broadcasts.
874      * Hash keys are the receiver IBinder, hash value is a ReceiverList.
875      */
876     final HashMap<IBinder, ReceiverList> mRegisteredReceivers = new HashMap<>();
877
878     /**
879      * Resolver for broadcast intents to registered receivers.
880      * Holds BroadcastFilter (subclass of IntentFilter).
881      */
882     final IntentResolver<BroadcastFilter, BroadcastFilter> mReceiverResolver
883             = new IntentResolver<BroadcastFilter, BroadcastFilter>() {
884         @Override
885         protected boolean allowFilterResult(
886                 BroadcastFilter filter, List<BroadcastFilter> dest) {
887             IBinder target = filter.receiverList.receiver.asBinder();
888             for (int i = dest.size() - 1; i >= 0; i--) {
889                 if (dest.get(i).receiverList.receiver.asBinder() == target) {
890                     return false;
891                 }
892             }
893             return true;
894         }
895
896         @Override
897         protected BroadcastFilter newResult(BroadcastFilter filter, int match, int userId) {
898             if (userId == UserHandle.USER_ALL || filter.owningUserId == UserHandle.USER_ALL
899                     || userId == filter.owningUserId) {
900                 return super.newResult(filter, match, userId);
901             }
902             return null;
903         }
904
905         @Override
906         protected BroadcastFilter[] newArray(int size) {
907             return new BroadcastFilter[size];
908         }
909
910         @Override
911         protected boolean isPackageForFilter(String packageName, BroadcastFilter filter) {
912             return packageName.equals(filter.packageName);
913         }
914     };
915
916     /**
917      * State of all active sticky broadcasts per user.  Keys are the action of the
918      * sticky Intent, values are an ArrayList of all broadcasted intents with
919      * that action (which should usually be one).  The SparseArray is keyed
920      * by the user ID the sticky is for, and can include UserHandle.USER_ALL
921      * for stickies that are sent to all users.
922      */
923     final SparseArray<ArrayMap<String, ArrayList<Intent>>> mStickyBroadcasts =
924             new SparseArray<ArrayMap<String, ArrayList<Intent>>>();
925
926     final ActiveServices mServices;
927
928     final static class Association {
929         final int mSourceUid;
930         final String mSourceProcess;
931         final int mTargetUid;
932         final ComponentName mTargetComponent;
933         final String mTargetProcess;
934
935         int mCount;
936         long mTime;
937
938         int mNesting;
939         long mStartTime;
940
941         Association(int sourceUid, String sourceProcess, int targetUid,
942                 ComponentName targetComponent, String targetProcess) {
943             mSourceUid = sourceUid;
944             mSourceProcess = sourceProcess;
945             mTargetUid = targetUid;
946             mTargetComponent = targetComponent;
947             mTargetProcess = targetProcess;
948         }
949     }
950
951     /**
952      * When service association tracking is enabled, this is all of the associations we
953      * have seen.  Mapping is target uid -> target component -> source uid -> source process name
954      * -> association data.
955      */
956     final SparseArray<ArrayMap<ComponentName, SparseArray<ArrayMap<String, Association>>>>
957             mAssociations = new SparseArray<>();
958     boolean mTrackingAssociations;
959
960     /**
961      * Backup/restore process management
962      */
963     String mBackupAppName = null;
964     BackupRecord mBackupTarget = null;
965
966     final ProviderMap mProviderMap;
967
968     /**
969      * List of content providers who have clients waiting for them.  The
970      * application is currently being launched and the provider will be
971      * removed from this list once it is published.
972      */
973     final ArrayList<ContentProviderRecord> mLaunchingProviders
974             = new ArrayList<ContentProviderRecord>();
975
976     /**
977      * File storing persisted {@link #mGrantedUriPermissions}.
978      */
979     private final AtomicFile mGrantFile;
980
981     /** XML constants used in {@link #mGrantFile} */
982     private static final String TAG_URI_GRANTS = "uri-grants";
983     private static final String TAG_URI_GRANT = "uri-grant";
984     private static final String ATTR_USER_HANDLE = "userHandle";
985     private static final String ATTR_SOURCE_USER_ID = "sourceUserId";
986     private static final String ATTR_TARGET_USER_ID = "targetUserId";
987     private static final String ATTR_SOURCE_PKG = "sourcePkg";
988     private static final String ATTR_TARGET_PKG = "targetPkg";
989     private static final String ATTR_URI = "uri";
990     private static final String ATTR_MODE_FLAGS = "modeFlags";
991     private static final String ATTR_CREATED_TIME = "createdTime";
992     private static final String ATTR_PREFIX = "prefix";
993
994     /**
995      * Global set of specific {@link Uri} permissions that have been granted.
996      * This optimized lookup structure maps from {@link UriPermission#targetUid}
997      * to {@link UriPermission#uri} to {@link UriPermission}.
998      */
999     @GuardedBy("this")
1000     private final SparseArray<ArrayMap<GrantUri, UriPermission>>
1001             mGrantedUriPermissions = new SparseArray<ArrayMap<GrantUri, UriPermission>>();
1002
1003     public static class GrantUri {
1004         public final int sourceUserId;
1005         public final Uri uri;
1006         public boolean prefix;
1007
1008         public GrantUri(int sourceUserId, Uri uri, boolean prefix) {
1009             this.sourceUserId = sourceUserId;
1010             this.uri = uri;
1011             this.prefix = prefix;
1012         }
1013
1014         @Override
1015         public int hashCode() {
1016             int hashCode = 1;
1017             hashCode = 31 * hashCode + sourceUserId;
1018             hashCode = 31 * hashCode + uri.hashCode();
1019             hashCode = 31 * hashCode + (prefix ? 1231 : 1237);
1020             return hashCode;
1021         }
1022
1023         @Override
1024         public boolean equals(Object o) {
1025             if (o instanceof GrantUri) {
1026                 GrantUri other = (GrantUri) o;
1027                 return uri.equals(other.uri) && (sourceUserId == other.sourceUserId)
1028                         && prefix == other.prefix;
1029             }
1030             return false;
1031         }
1032
1033         @Override
1034         public String toString() {
1035             String result = Integer.toString(sourceUserId) + " @ " + uri.toString();
1036             if (prefix) result += " [prefix]";
1037             return result;
1038         }
1039
1040         public String toSafeString() {
1041             String result = Integer.toString(sourceUserId) + " @ " + uri.toSafeString();
1042             if (prefix) result += " [prefix]";
1043             return result;
1044         }
1045
1046         public static GrantUri resolve(int defaultSourceUserHandle, Uri uri) {
1047             return new GrantUri(ContentProvider.getUserIdFromUri(uri, defaultSourceUserHandle),
1048                     ContentProvider.getUriWithoutUserId(uri), false);
1049         }
1050     }
1051
1052     CoreSettingsObserver mCoreSettingsObserver;
1053
1054     /**
1055      * Thread-local storage used to carry caller permissions over through
1056      * indirect content-provider access.
1057      */
1058     private class Identity {
1059         public final IBinder token;
1060         public final int pid;
1061         public final int uid;
1062
1063         Identity(IBinder _token, int _pid, int _uid) {
1064             token = _token;
1065             pid = _pid;
1066             uid = _uid;
1067         }
1068     }
1069
1070     private static final ThreadLocal<Identity> sCallerIdentity = new ThreadLocal<Identity>();
1071
1072     /**
1073      * All information we have collected about the runtime performance of
1074      * any user id that can impact battery performance.
1075      */
1076     final BatteryStatsService mBatteryStatsService;
1077
1078     /**
1079      * Information about component usage
1080      */
1081     UsageStatsManagerInternal mUsageStatsService;
1082
1083     /**
1084      * Access to DeviceIdleController service.
1085      */
1086     DeviceIdleController.LocalService mLocalDeviceIdleController;
1087
1088     /**
1089      * Information about and control over application operations
1090      */
1091     final AppOpsService mAppOpsService;
1092
1093     /**
1094      * Save recent tasks information across reboots.
1095      */
1096     final TaskPersister mTaskPersister;
1097
1098     /**
1099      * Current configuration information.  HistoryRecord objects are given
1100      * a reference to this object to indicate which configuration they are
1101      * currently running in, so this object must be kept immutable.
1102      */
1103     Configuration mConfiguration = new Configuration();
1104
1105     /**
1106      * Current sequencing integer of the configuration, for skipping old
1107      * configurations.
1108      */
1109     int mConfigurationSeq = 0;
1110
1111     boolean mSuppressResizeConfigChanges = false;
1112
1113     /**
1114      * Hardware-reported OpenGLES version.
1115      */
1116     final int GL_ES_VERSION;
1117
1118     /**
1119      * List of initialization arguments to pass to all processes when binding applications to them.
1120      * For example, references to the commonly used services.
1121      */
1122     HashMap<String, IBinder> mAppBindArgs;
1123
1124     /**
1125      * Temporary to avoid allocations.  Protected by main lock.
1126      */
1127     final StringBuilder mStringBuilder = new StringBuilder(256);
1128
1129     /**
1130      * Used to control how we initialize the service.
1131      */
1132     ComponentName mTopComponent;
1133     String mTopAction = Intent.ACTION_MAIN;
1134     String mTopData;
1135     boolean mProcessesReady = false;
1136     boolean mSystemReady = false;
1137     boolean mBooting = false;
1138     boolean mCallFinishBooting = false;
1139     boolean mBootAnimationComplete = false;
1140     boolean mWaitingUpdate = false;
1141     boolean mDidUpdate = false;
1142     boolean mOnBattery = false;
1143     boolean mLaunchWarningShown = false;
1144
1145     Context mContext;
1146
1147     int mFactoryTest;
1148
1149     boolean mCheckedForSetup;
1150
1151     /**
1152      * The time at which we will allow normal application switches again,
1153      * after a call to {@link #stopAppSwitches()}.
1154      */
1155     long mAppSwitchesAllowedTime;
1156
1157     /**
1158      * This is set to true after the first switch after mAppSwitchesAllowedTime
1159      * is set; any switches after that will clear the time.
1160      */
1161     boolean mDidAppSwitch;
1162
1163     /**
1164      * Last time (in realtime) at which we checked for power usage.
1165      */
1166     long mLastPowerCheckRealtime;
1167
1168     /**
1169      * Last time (in uptime) at which we checked for power usage.
1170      */
1171     long mLastPowerCheckUptime;
1172
1173     /**
1174      * Set while we are wanting to sleep, to prevent any
1175      * activities from being started/resumed.
1176      */
1177     private boolean mSleeping = false;
1178
1179     /**
1180      * The process state used for processes that are running the top activities.
1181      * This changes between TOP and TOP_SLEEPING to following mSleeping.
1182      */
1183     int mTopProcessState = ActivityManager.PROCESS_STATE_TOP;
1184
1185     /**
1186      * Set while we are running a voice interaction.  This overrides
1187      * sleeping while it is active.
1188      */
1189     private IVoiceInteractionSession mRunningVoice;
1190
1191     /**
1192      * For some direct access we need to power manager.
1193      */
1194     PowerManagerInternal mLocalPowerManager;
1195
1196     /**
1197      * We want to hold a wake lock while running a voice interaction session, since
1198      * this may happen with the screen off and we need to keep the CPU running to
1199      * be able to continue to interact with the user.
1200      */
1201     PowerManager.WakeLock mVoiceWakeLock;
1202
1203     /**
1204      * State of external calls telling us if the device is awake or asleep.
1205      */
1206     private int mWakefulness = PowerManagerInternal.WAKEFULNESS_AWAKE;
1207
1208     /**
1209      * A list of tokens that cause the top activity to be put to sleep.
1210      * They are used by components that may hide and block interaction with underlying
1211      * activities.
1212      */
1213     final ArrayList<SleepToken> mSleepTokens = new ArrayList<SleepToken>();
1214
1215     static final int LOCK_SCREEN_HIDDEN = 0;
1216     static final int LOCK_SCREEN_LEAVING = 1;
1217     static final int LOCK_SCREEN_SHOWN = 2;
1218     /**
1219      * State of external call telling us if the lock screen is shown.
1220      */
1221     int mLockScreenShown = LOCK_SCREEN_HIDDEN;
1222
1223     /**
1224      * Set if we are shutting down the system, similar to sleeping.
1225      */
1226     boolean mShuttingDown = false;
1227
1228     /**
1229      * Current sequence id for oom_adj computation traversal.
1230      */
1231     int mAdjSeq = 0;
1232
1233     /**
1234      * Current sequence id for process LRU updating.
1235      */
1236     int mLruSeq = 0;
1237
1238     /**
1239      * Keep track of the non-cached/empty process we last found, to help
1240      * determine how to distribute cached/empty processes next time.
1241      */
1242     int mNumNonCachedProcs = 0;
1243
1244     /**
1245      * Keep track of the number of cached hidden procs, to balance oom adj
1246      * distribution between those and empty procs.
1247      */
1248     int mNumCachedHiddenProcs = 0;
1249
1250     /**
1251      * Keep track of the number of service processes we last found, to
1252      * determine on the next iteration which should be B services.
1253      */
1254     int mNumServiceProcs = 0;
1255     int mNewNumAServiceProcs = 0;
1256     int mNewNumServiceProcs = 0;
1257
1258     /**
1259      * Allow the current computed overall memory level of the system to go down?
1260      * This is set to false when we are killing processes for reasons other than
1261      * memory management, so that the now smaller process list will not be taken as
1262      * an indication that memory is tighter.
1263      */
1264     boolean mAllowLowerMemLevel = false;
1265
1266     /**
1267      * The last computed memory level, for holding when we are in a state that
1268      * processes are going away for other reasons.
1269      */
1270     int mLastMemoryLevel = ProcessStats.ADJ_MEM_FACTOR_NORMAL;
1271
1272     /**
1273      * The last total number of process we have, to determine if changes actually look
1274      * like a shrinking number of process due to lower RAM.
1275      */
1276     int mLastNumProcesses;
1277
1278     /**
1279      * The uptime of the last time we performed idle maintenance.
1280      */
1281     long mLastIdleTime = SystemClock.uptimeMillis();
1282
1283     /**
1284      * Total time spent with RAM that has been added in the past since the last idle time.
1285      */
1286     long mLowRamTimeSinceLastIdle = 0;
1287
1288     /**
1289      * If RAM is currently low, when that horrible situation started.
1290      */
1291     long mLowRamStartTime = 0;
1292
1293     /**
1294      * For reporting to battery stats the current top application.
1295      */
1296     private String mCurResumedPackage = null;
1297     private int mCurResumedUid = -1;
1298
1299     /**
1300      * For reporting to battery stats the apps currently running foreground
1301      * service.  The ProcessMap is package/uid tuples; each of these contain
1302      * an array of the currently foreground processes.
1303      */
1304     final ProcessMap<ArrayList<ProcessRecord>> mForegroundPackages
1305             = new ProcessMap<ArrayList<ProcessRecord>>();
1306
1307     /**
1308      * This is set if we had to do a delayed dexopt of an app before launching
1309      * it, to increase the ANR timeouts in that case.
1310      */
1311     boolean mDidDexOpt;
1312
1313     /**
1314      * Set if the systemServer made a call to enterSafeMode.
1315      */
1316     boolean mSafeMode;
1317
1318     /**
1319      * If true, we are running under a test environment so will sample PSS from processes
1320      * much more rapidly to try to collect better data when the tests are rapidly
1321      * running through apps.
1322      */
1323     boolean mTestPssMode = false;
1324
1325     String mDebugApp = null;
1326     boolean mWaitForDebugger = false;
1327     boolean mDebugTransient = false;
1328     String mOrigDebugApp = null;
1329     boolean mOrigWaitForDebugger = false;
1330     boolean mAlwaysFinishActivities = false;
1331     boolean mForceResizableActivities;
1332     boolean mSupportsFreeformWindowManagement;
1333     boolean mTakeFullscreenScreenshots;
1334     IActivityController mController = null;
1335     String mProfileApp = null;
1336     ProcessRecord mProfileProc = null;
1337     String mProfileFile;
1338     ParcelFileDescriptor mProfileFd;
1339     int mSamplingInterval = 0;
1340     boolean mAutoStopProfiler = false;
1341     int mProfileType = 0;
1342     final ProcessMap<Pair<Long, String>> mMemWatchProcesses = new ProcessMap<>();
1343     String mMemWatchDumpProcName;
1344     String mMemWatchDumpFile;
1345     int mMemWatchDumpPid;
1346     int mMemWatchDumpUid;
1347     String mTrackAllocationApp = null;
1348
1349     final long[] mTmpLong = new long[1];
1350
1351     static final class ProcessChangeItem {
1352         static final int CHANGE_ACTIVITIES = 1<<0;
1353         static final int CHANGE_PROCESS_STATE = 1<<1;
1354         int changes;
1355         int uid;
1356         int pid;
1357         int processState;
1358         boolean foregroundActivities;
1359     }
1360
1361     final RemoteCallbackList<IProcessObserver> mProcessObservers = new RemoteCallbackList<>();
1362     ProcessChangeItem[] mActiveProcessChanges = new ProcessChangeItem[5];
1363
1364     final ArrayList<ProcessChangeItem> mPendingProcessChanges = new ArrayList<>();
1365     final ArrayList<ProcessChangeItem> mAvailProcessChanges = new ArrayList<>();
1366
1367     final RemoteCallbackList<IUidObserver> mUidObservers = new RemoteCallbackList<>();
1368     UidRecord.ChangeItem[] mActiveUidChanges = new UidRecord.ChangeItem[5];
1369
1370     final ArrayList<UidRecord.ChangeItem> mPendingUidChanges = new ArrayList<>();
1371     final ArrayList<UidRecord.ChangeItem> mAvailUidChanges = new ArrayList<>();
1372
1373     ArraySet<String> mAppsNotReportingCrashes;
1374
1375     /**
1376      * Runtime CPU use collection thread.  This object's lock is used to
1377      * perform synchronization with the thread (notifying it to run).
1378      */
1379     final Thread mProcessCpuThread;
1380
1381     /**
1382      * Used to collect per-process CPU use for ANRs, battery stats, etc.
1383      * Must acquire this object's lock when accessing it.
1384      * NOTE: this lock will be held while doing long operations (trawling
1385      * through all processes in /proc), so it should never be acquired by
1386      * any critical paths such as when holding the main activity manager lock.
1387      */
1388     final ProcessCpuTracker mProcessCpuTracker = new ProcessCpuTracker(
1389             MONITOR_THREAD_CPU_USAGE);
1390     final AtomicLong mLastCpuTime = new AtomicLong(0);
1391     final AtomicBoolean mProcessCpuMutexFree = new AtomicBoolean(true);
1392
1393     long mLastWriteTime = 0;
1394
1395     /**
1396      * Used to retain an update lock when the foreground activity is in
1397      * immersive mode.
1398      */
1399     final UpdateLock mUpdateLock = new UpdateLock("immersive");
1400
1401     /**
1402      * Set to true after the system has finished booting.
1403      */
1404     boolean mBooted = false;
1405
1406     int mProcessLimit = ProcessList.MAX_CACHED_APPS;
1407     int mProcessLimitOverride = -1;
1408
1409     WindowManagerService mWindowManager;
1410
1411     final ActivityThread mSystemThread;
1412
1413     private final class AppDeathRecipient implements IBinder.DeathRecipient {
1414         final ProcessRecord mApp;
1415         final int mPid;
1416         final IApplicationThread mAppThread;
1417
1418         AppDeathRecipient(ProcessRecord app, int pid,
1419                 IApplicationThread thread) {
1420             if (DEBUG_ALL) Slog.v(
1421                 TAG, "New death recipient " + this
1422                 + " for thread " + thread.asBinder());
1423             mApp = app;
1424             mPid = pid;
1425             mAppThread = thread;
1426         }
1427
1428         @Override
1429         public void binderDied() {
1430             if (DEBUG_ALL) Slog.v(
1431                 TAG, "Death received in " + this
1432                 + " for thread " + mAppThread.asBinder());
1433             synchronized(ActivityManagerService.this) {
1434                 appDiedLocked(mApp, mPid, mAppThread, true);
1435             }
1436         }
1437     }
1438
1439     static final int SHOW_ERROR_UI_MSG = 1;
1440     static final int SHOW_NOT_RESPONDING_UI_MSG = 2;
1441     static final int SHOW_FACTORY_ERROR_UI_MSG = 3;
1442     static final int UPDATE_CONFIGURATION_MSG = 4;
1443     static final int GC_BACKGROUND_PROCESSES_MSG = 5;
1444     static final int WAIT_FOR_DEBUGGER_UI_MSG = 6;
1445     static final int SERVICE_TIMEOUT_MSG = 12;
1446     static final int UPDATE_TIME_ZONE = 13;
1447     static final int SHOW_UID_ERROR_UI_MSG = 14;
1448     static final int SHOW_FINGERPRINT_ERROR_UI_MSG = 15;
1449     static final int PROC_START_TIMEOUT_MSG = 20;
1450     static final int DO_PENDING_ACTIVITY_LAUNCHES_MSG = 21;
1451     static final int KILL_APPLICATION_MSG = 22;
1452     static final int FINALIZE_PENDING_INTENT_MSG = 23;
1453     static final int POST_HEAVY_NOTIFICATION_MSG = 24;
1454     static final int CANCEL_HEAVY_NOTIFICATION_MSG = 25;
1455     static final int SHOW_STRICT_MODE_VIOLATION_UI_MSG = 26;
1456     static final int CHECK_EXCESSIVE_WAKE_LOCKS_MSG = 27;
1457     static final int CLEAR_DNS_CACHE_MSG = 28;
1458     static final int UPDATE_HTTP_PROXY_MSG = 29;
1459     static final int SHOW_COMPAT_MODE_DIALOG_UI_MSG = 30;
1460     static final int DISPATCH_PROCESSES_CHANGED_UI_MSG = 31;
1461     static final int DISPATCH_PROCESS_DIED_UI_MSG = 32;
1462     static final int REPORT_MEM_USAGE_MSG = 33;
1463     static final int REPORT_USER_SWITCH_MSG = 34;
1464     static final int CONTINUE_USER_SWITCH_MSG = 35;
1465     static final int USER_SWITCH_TIMEOUT_MSG = 36;
1466     static final int IMMERSIVE_MODE_LOCK_MSG = 37;
1467     static final int PERSIST_URI_GRANTS_MSG = 38;
1468     static final int REQUEST_ALL_PSS_MSG = 39;
1469     static final int START_PROFILES_MSG = 40;
1470     static final int UPDATE_TIME = 41;
1471     static final int SYSTEM_USER_START_MSG = 42;
1472     static final int SYSTEM_USER_CURRENT_MSG = 43;
1473     static final int ENTER_ANIMATION_COMPLETE_MSG = 44;
1474     static final int FINISH_BOOTING_MSG = 45;
1475     static final int START_USER_SWITCH_UI_MSG = 46;
1476     static final int SEND_LOCALE_TO_MOUNT_DAEMON_MSG = 47;
1477     static final int DISMISS_DIALOG_UI_MSG = 48;
1478     static final int NOTIFY_TASK_STACK_CHANGE_LISTENERS_MSG = 49;
1479     static final int NOTIFY_CLEARTEXT_NETWORK_MSG = 50;
1480     static final int POST_DUMP_HEAP_NOTIFICATION_MSG = 51;
1481     static final int DELETE_DUMPHEAP_MSG = 52;
1482     static final int FOREGROUND_PROFILE_CHANGED_MSG = 53;
1483     static final int DISPATCH_UIDS_CHANGED_UI_MSG = 54;
1484     static final int REPORT_TIME_TRACKER_MSG = 55;
1485     static final int REPORT_USER_SWITCH_COMPLETE_MSG = 56;
1486     static final int SHUTDOWN_UI_AUTOMATION_CONNECTION_MSG = 57;
1487     static final int APP_BOOST_DEACTIVATE_MSG = 58;
1488     static final int CONTENT_PROVIDER_PUBLISH_TIMEOUT_MSG = 59;
1489     static final int IDLE_UIDS_MSG = 60;
1490
1491     static final int FIRST_ACTIVITY_STACK_MSG = 100;
1492     static final int FIRST_BROADCAST_QUEUE_MSG = 200;
1493     static final int FIRST_COMPAT_MODE_MSG = 300;
1494     static final int FIRST_SUPERVISOR_STACK_MSG = 100;
1495
1496     CompatModeDialog mCompatModeDialog;
1497     long mLastMemUsageReportTime = 0;
1498
1499     /**
1500      * Flag whether the current user is a "monkey", i.e. whether
1501      * the UI is driven by a UI automation tool.
1502      */
1503     private boolean mUserIsMonkey;
1504
1505     /** Flag whether the device has a Recents UI */
1506     boolean mHasRecents;
1507
1508     /** The dimensions of the thumbnails in the Recents UI. */
1509     int mThumbnailWidth;
1510     int mThumbnailHeight;
1511
1512     final ServiceThread mHandlerThread;
1513     final MainHandler mHandler;
1514     final UiHandler mUiHandler;
1515
1516     PackageManagerInternal mPackageManagerInt;
1517
1518     final class UiHandler extends Handler {
1519         public UiHandler() {
1520             super(com.android.server.UiThread.get().getLooper(), null, true);
1521         }
1522
1523         @Override
1524         public void handleMessage(Message msg) {
1525             switch (msg.what) {
1526             case SHOW_ERROR_UI_MSG: {
1527                 HashMap<String, Object> data = (HashMap<String, Object>) msg.obj;
1528                 boolean showBackground = Settings.Secure.getInt(mContext.getContentResolver(),
1529                         Settings.Secure.ANR_SHOW_BACKGROUND, 0) != 0;
1530                 synchronized (ActivityManagerService.this) {
1531                     ProcessRecord proc = (ProcessRecord)data.get("app");
1532                     AppErrorResult res = (AppErrorResult) data.get("result");
1533                     if (proc != null && proc.crashDialog != null) {
1534                         Slog.e(TAG, "App already has crash dialog: " + proc);
1535                         if (res != null) {
1536                             res.set(0);
1537                         }
1538                         return;
1539                     }
1540                     boolean isBackground = (UserHandle.getAppId(proc.uid)
1541                             >= Process.FIRST_APPLICATION_UID
1542                             && proc.pid != MY_PID);
1543                     for (int userId : mUserController.getCurrentProfileIdsLocked()) {
1544                         isBackground &= (proc.userId != userId);
1545                     }
1546                     if (isBackground && !showBackground) {
1547                         Slog.w(TAG, "Skipping crash dialog of " + proc + ": background");
1548                         if (res != null) {
1549                             res.set(0);
1550                         }
1551                         return;
1552                     }
1553                     final boolean crashSilenced = mAppsNotReportingCrashes != null &&
1554                             mAppsNotReportingCrashes.contains(proc.info.packageName);
1555                     if (mShowDialogs && !mSleeping && !mShuttingDown && !crashSilenced) {
1556                         Dialog d = new AppErrorDialog(mContext,
1557                                 ActivityManagerService.this, res, proc);
1558                         d.show();
1559                         proc.crashDialog = d;
1560                     } else {
1561                         // The device is asleep, so just pretend that the user
1562                         // saw a crash dialog and hit "force quit".
1563                         if (res != null) {
1564                             res.set(0);
1565                         }
1566                     }
1567                 }
1568
1569                 ensureBootCompleted();
1570             } break;
1571             case SHOW_NOT_RESPONDING_UI_MSG: {
1572                 synchronized (ActivityManagerService.this) {
1573                     HashMap<String, Object> data = (HashMap<String, Object>) msg.obj;
1574                     ProcessRecord proc = (ProcessRecord)data.get("app");
1575                     if (proc != null && proc.anrDialog != null) {
1576                         Slog.e(TAG, "App already has anr dialog: " + proc);
1577                         return;
1578                     }
1579
1580                     Intent intent = new Intent("android.intent.action.ANR");
1581                     if (!mProcessesReady) {
1582                         intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY
1583                                 | Intent.FLAG_RECEIVER_FOREGROUND);
1584                     }
1585                     broadcastIntentLocked(null, null, intent,
1586                             null, null, 0, null, null, null, AppOpsManager.OP_NONE,
1587                             null, false, false, MY_PID, Process.SYSTEM_UID, 0 /* TODO: Verify */);
1588
1589                     if (mShowDialogs) {
1590                         Dialog d = new AppNotRespondingDialog(ActivityManagerService.this,
1591                                 mContext, proc, (ActivityRecord)data.get("activity"),
1592                                 msg.arg1 != 0);
1593                         d.show();
1594                         proc.anrDialog = d;
1595                     } else {
1596                         // Just kill the app if there is no dialog to be shown.
1597                         killAppAtUsersRequest(proc, null);
1598                     }
1599                 }
1600
1601                 ensureBootCompleted();
1602             } break;
1603             case SHOW_STRICT_MODE_VIOLATION_UI_MSG: {
1604                 HashMap<String, Object> data = (HashMap<String, Object>) msg.obj;
1605                 synchronized (ActivityManagerService.this) {
1606                     ProcessRecord proc = (ProcessRecord) data.get("app");
1607                     if (proc == null) {
1608                         Slog.e(TAG, "App not found when showing strict mode dialog.");
1609                         break;
1610                     }
1611                     if (proc.crashDialog != null) {
1612                         Slog.e(TAG, "App already has strict mode dialog: " + proc);
1613                         return;
1614                     }
1615                     AppErrorResult res = (AppErrorResult) data.get("result");
1616                     if (mShowDialogs && !mSleeping && !mShuttingDown) {
1617                         Dialog d = new StrictModeViolationDialog(mContext,
1618                                 ActivityManagerService.this, res, proc);
1619                         d.show();
1620                         proc.crashDialog = d;
1621                     } else {
1622                         // The device is asleep, so just pretend that the user
1623                         // saw a crash dialog and hit "force quit".
1624                         res.set(0);
1625                     }
1626                 }
1627                 ensureBootCompleted();
1628             } break;
1629             case SHOW_FACTORY_ERROR_UI_MSG: {
1630                 Dialog d = new FactoryErrorDialog(
1631                     mContext, msg.getData().getCharSequence("msg"));
1632                 d.show();
1633                 ensureBootCompleted();
1634             } break;
1635             case WAIT_FOR_DEBUGGER_UI_MSG: {
1636                 synchronized (ActivityManagerService.this) {
1637                     ProcessRecord app = (ProcessRecord)msg.obj;
1638                     if (msg.arg1 != 0) {
1639                         if (!app.waitedForDebugger) {
1640                             Dialog d = new AppWaitingForDebuggerDialog(
1641                                     ActivityManagerService.this,
1642                                     mContext, app);
1643                             app.waitDialog = d;
1644                             app.waitedForDebugger = true;
1645                             d.show();
1646                         }
1647                     } else {
1648                         if (app.waitDialog != null) {
1649                             app.waitDialog.dismiss();
1650                             app.waitDialog = null;
1651                         }
1652                     }
1653                 }
1654             } break;
1655             case SHOW_UID_ERROR_UI_MSG: {
1656                 if (mShowDialogs) {
1657                     AlertDialog d = new BaseErrorDialog(mContext);
1658                     d.getWindow().setType(WindowManager.LayoutParams.TYPE_SYSTEM_ERROR);
1659                     d.setCancelable(false);
1660                     d.setTitle(mContext.getText(R.string.android_system_label));
1661                     d.setMessage(mContext.getText(R.string.system_error_wipe_data));
1662                     d.setButton(DialogInterface.BUTTON_POSITIVE, mContext.getText(R.string.ok),
1663                             obtainMessage(DISMISS_DIALOG_UI_MSG, d));
1664                     d.show();
1665                 }
1666             } break;
1667             case SHOW_FINGERPRINT_ERROR_UI_MSG: {
1668                 if (mShowDialogs) {
1669                     AlertDialog d = new BaseErrorDialog(mContext);
1670                     d.getWindow().setType(WindowManager.LayoutParams.TYPE_SYSTEM_ERROR);
1671                     d.setCancelable(false);
1672                     d.setTitle(mContext.getText(R.string.android_system_label));
1673                     d.setMessage(mContext.getText(R.string.system_error_manufacturer));
1674                     d.setButton(DialogInterface.BUTTON_POSITIVE, mContext.getText(R.string.ok),
1675                             obtainMessage(DISMISS_DIALOG_UI_MSG, d));
1676                     d.show();
1677                 }
1678             } break;
1679             case SHOW_COMPAT_MODE_DIALOG_UI_MSG: {
1680                 synchronized (ActivityManagerService.this) {
1681                     ActivityRecord ar = (ActivityRecord) msg.obj;
1682                     if (mCompatModeDialog != null) {
1683                         if (mCompatModeDialog.mAppInfo.packageName.equals(
1684                                 ar.info.applicationInfo.packageName)) {
1685                             return;
1686                         }
1687                         mCompatModeDialog.dismiss();
1688                         mCompatModeDialog = null;
1689                     }
1690                     if (ar != null && false) {
1691                         if (mCompatModePackages.getPackageAskCompatModeLocked(
1692                                 ar.packageName)) {
1693                             int mode = mCompatModePackages.computeCompatModeLocked(
1694                                     ar.info.applicationInfo);
1695                             if (mode == ActivityManager.COMPAT_MODE_DISABLED
1696                                     || mode == ActivityManager.COMPAT_MODE_ENABLED) {
1697                                 mCompatModeDialog = new CompatModeDialog(
1698                                         ActivityManagerService.this, mContext,
1699                                         ar.info.applicationInfo);
1700                                 mCompatModeDialog.show();
1701                             }
1702                         }
1703                     }
1704                 }
1705                 break;
1706             }
1707             case START_USER_SWITCH_UI_MSG: {
1708                 mUserController.showUserSwitchDialog((Pair<UserInfo, UserInfo>) msg.obj);
1709                 break;
1710             }
1711             case DISMISS_DIALOG_UI_MSG: {
1712                 final Dialog d = (Dialog) msg.obj;
1713                 d.dismiss();
1714                 break;
1715             }
1716             case DISPATCH_PROCESSES_CHANGED_UI_MSG: {
1717                 dispatchProcessesChanged();
1718                 break;
1719             }
1720             case DISPATCH_PROCESS_DIED_UI_MSG: {
1721                 final int pid = msg.arg1;
1722                 final int uid = msg.arg2;
1723                 dispatchProcessDied(pid, uid);
1724                 break;
1725             }
1726             case DISPATCH_UIDS_CHANGED_UI_MSG: {
1727                 dispatchUidsChanged();
1728             } break;
1729             }
1730         }
1731     }
1732
1733     final class MainHandler extends Handler {
1734         public MainHandler(Looper looper) {
1735             super(looper, null, true);
1736         }
1737
1738         @Override
1739         public void handleMessage(Message msg) {
1740             switch (msg.what) {
1741             case UPDATE_CONFIGURATION_MSG: {
1742                 final ContentResolver resolver = mContext.getContentResolver();
1743                 Settings.System.putConfigurationForUser(resolver, (Configuration) msg.obj,
1744                         msg.arg1);
1745             } break;
1746             case GC_BACKGROUND_PROCESSES_MSG: {
1747                 synchronized (ActivityManagerService.this) {
1748                     performAppGcsIfAppropriateLocked();
1749                 }
1750             } break;
1751             case SERVICE_TIMEOUT_MSG: {
1752                 if (mDidDexOpt) {
1753                     mDidDexOpt = false;
1754                     Message nmsg = mHandler.obtainMessage(SERVICE_TIMEOUT_MSG);
1755                     nmsg.obj = msg.obj;
1756                     mHandler.sendMessageDelayed(nmsg, ActiveServices.SERVICE_TIMEOUT);
1757                     return;
1758                 }
1759                 mServices.serviceTimeout((ProcessRecord)msg.obj);
1760             } break;
1761             case UPDATE_TIME_ZONE: {
1762                 synchronized (ActivityManagerService.this) {
1763                     for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) {
1764                         ProcessRecord r = mLruProcesses.get(i);
1765                         if (r.thread != null) {
1766                             try {
1767                                 r.thread.updateTimeZone();
1768                             } catch (RemoteException ex) {
1769                                 Slog.w(TAG, "Failed to update time zone for: " + r.info.processName);
1770                             }
1771                         }
1772                     }
1773                 }
1774             } break;
1775             case CLEAR_DNS_CACHE_MSG: {
1776                 synchronized (ActivityManagerService.this) {
1777                     for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) {
1778                         ProcessRecord r = mLruProcesses.get(i);
1779                         if (r.thread != null) {
1780                             try {
1781                                 r.thread.clearDnsCache();
1782                             } catch (RemoteException ex) {
1783                                 Slog.w(TAG, "Failed to clear dns cache for: " + r.info.processName);
1784                             }
1785                         }
1786                     }
1787                 }
1788             } break;
1789             case UPDATE_HTTP_PROXY_MSG: {
1790                 ProxyInfo proxy = (ProxyInfo)msg.obj;
1791                 String host = "";
1792                 String port = "";
1793                 String exclList = "";
1794                 Uri pacFileUrl = Uri.EMPTY;
1795                 if (proxy != null) {
1796                     host = proxy.getHost();
1797                     port = Integer.toString(proxy.getPort());
1798                     exclList = proxy.getExclusionListAsString();
1799                     pacFileUrl = proxy.getPacFileUrl();
1800                 }
1801                 synchronized (ActivityManagerService.this) {
1802                     for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) {
1803                         ProcessRecord r = mLruProcesses.get(i);
1804                         if (r.thread != null) {
1805                             try {
1806                                 r.thread.setHttpProxy(host, port, exclList, pacFileUrl);
1807                             } catch (RemoteException ex) {
1808                                 Slog.w(TAG, "Failed to update http proxy for: " +
1809                                         r.info.processName);
1810                             }
1811                         }
1812                     }
1813                 }
1814             } break;
1815             case PROC_START_TIMEOUT_MSG: {
1816                 if (mDidDexOpt) {
1817                     mDidDexOpt = false;
1818                     Message nmsg = mHandler.obtainMessage(PROC_START_TIMEOUT_MSG);
1819                     nmsg.obj = msg.obj;
1820                     mHandler.sendMessageDelayed(nmsg, PROC_START_TIMEOUT);
1821                     return;
1822                 }
1823                 ProcessRecord app = (ProcessRecord)msg.obj;
1824                 synchronized (ActivityManagerService.this) {
1825                     processStartTimedOutLocked(app);
1826                 }
1827             } break;
1828             case CONTENT_PROVIDER_PUBLISH_TIMEOUT_MSG: {
1829                 ProcessRecord app = (ProcessRecord)msg.obj;
1830                 synchronized (ActivityManagerService.this) {
1831                     processContentProviderPublishTimedOutLocked(app);
1832                 }
1833             } break;
1834             case DO_PENDING_ACTIVITY_LAUNCHES_MSG: {
1835                 synchronized (ActivityManagerService.this) {
1836                     mStackSupervisor.doPendingActivityLaunchesLocked(true);
1837                 }
1838             } break;
1839             case KILL_APPLICATION_MSG: {
1840                 synchronized (ActivityManagerService.this) {
1841                     int appid = msg.arg1;
1842                     boolean restart = (msg.arg2 == 1);
1843                     Bundle bundle = (Bundle)msg.obj;
1844                     String pkg = bundle.getString("pkg");
1845                     String reason = bundle.getString("reason");
1846                     forceStopPackageLocked(pkg, appid, restart, false, true, false,
1847                             false, UserHandle.USER_ALL, reason);
1848                 }
1849             } break;
1850             case FINALIZE_PENDING_INTENT_MSG: {
1851                 ((PendingIntentRecord)msg.obj).completeFinalize();
1852             } break;
1853             case POST_HEAVY_NOTIFICATION_MSG: {
1854                 INotificationManager inm = NotificationManager.getService();
1855                 if (inm == null) {
1856                     return;
1857                 }
1858
1859                 ActivityRecord root = (ActivityRecord)msg.obj;
1860                 ProcessRecord process = root.app;
1861                 if (process == null) {
1862                     return;
1863                 }
1864
1865                 try {
1866                     Context context = mContext.createPackageContext(process.info.packageName, 0);
1867                     String text = mContext.getString(R.string.heavy_weight_notification,
1868                             context.getApplicationInfo().loadLabel(context.getPackageManager()));
1869                     Notification notification = new Notification.Builder(context)
1870                             .setSmallIcon(com.android.internal.R.drawable.stat_sys_adb)
1871                             .setWhen(0)
1872                             .setOngoing(true)
1873                             .setTicker(text)
1874                             .setColor(mContext.getColor(
1875                                     com.android.internal.R.color.system_notification_accent_color))
1876                             .setContentTitle(text)
1877                             .setContentText(
1878                                     mContext.getText(R.string.heavy_weight_notification_detail))
1879                             .setContentIntent(PendingIntent.getActivityAsUser(mContext, 0,
1880                                     root.intent, PendingIntent.FLAG_CANCEL_CURRENT, null,
1881                                     new UserHandle(root.userId)))
1882                             .build();
1883                     try {
1884                         int[] outId = new int[1];
1885                         inm.enqueueNotificationWithTag("android", "android", null,
1886                                 R.string.heavy_weight_notification,
1887                                 notification, outId, root.userId);
1888                     } catch (RuntimeException e) {
1889                         Slog.w(ActivityManagerService.TAG,
1890                                 "Error showing notification for heavy-weight app", e);
1891                     } catch (RemoteException e) {
1892                     }
1893                 } catch (NameNotFoundException e) {
1894                     Slog.w(TAG, "Unable to create context for heavy notification", e);
1895                 }
1896             } break;
1897             case CANCEL_HEAVY_NOTIFICATION_MSG: {
1898                 INotificationManager inm = NotificationManager.getService();
1899                 if (inm == null) {
1900                     return;
1901                 }
1902                 try {
1903                     inm.cancelNotificationWithTag("android", null,
1904                             R.string.heavy_weight_notification,  msg.arg1);
1905                 } catch (RuntimeException e) {
1906                     Slog.w(ActivityManagerService.TAG,
1907                             "Error canceling notification for service", e);
1908                 } catch (RemoteException e) {
1909                 }
1910             } break;
1911             case CHECK_EXCESSIVE_WAKE_LOCKS_MSG: {
1912                 synchronized (ActivityManagerService.this) {
1913                     checkExcessivePowerUsageLocked(true);
1914                     removeMessages(CHECK_EXCESSIVE_WAKE_LOCKS_MSG);
1915                     Message nmsg = obtainMessage(CHECK_EXCESSIVE_WAKE_LOCKS_MSG);
1916                     sendMessageDelayed(nmsg, POWER_CHECK_DELAY);
1917                 }
1918             } break;
1919             case REPORT_MEM_USAGE_MSG: {
1920                 final ArrayList<ProcessMemInfo> memInfos = (ArrayList<ProcessMemInfo>)msg.obj;
1921                 Thread thread = new Thread() {
1922                     @Override public void run() {
1923                         reportMemUsage(memInfos);
1924                     }
1925                 };
1926                 thread.start();
1927                 break;
1928             }
1929             case REPORT_USER_SWITCH_MSG: {
1930                 mUserController.dispatchUserSwitch((UserState) msg.obj, msg.arg1, msg.arg2);
1931                 break;
1932             }
1933             case CONTINUE_USER_SWITCH_MSG: {
1934                 mUserController.continueUserSwitch((UserState) msg.obj, msg.arg1, msg.arg2);
1935                 break;
1936             }
1937             case USER_SWITCH_TIMEOUT_MSG: {
1938                 mUserController.timeoutUserSwitch((UserState) msg.obj, msg.arg1, msg.arg2);
1939                 break;
1940             }
1941             case IMMERSIVE_MODE_LOCK_MSG: {
1942                 final boolean nextState = (msg.arg1 != 0);
1943                 if (mUpdateLock.isHeld() != nextState) {
1944                     if (DEBUG_IMMERSIVE) Slog.d(TAG_IMMERSIVE,
1945                             "Applying new update lock state '" + nextState
1946                             + "' for " + (ActivityRecord)msg.obj);
1947                     if (nextState) {
1948                         mUpdateLock.acquire();
1949                     } else {
1950                         mUpdateLock.release();
1951                     }
1952                 }
1953                 break;
1954             }
1955             case PERSIST_URI_GRANTS_MSG: {
1956                 writeGrantedUriPermissions();
1957                 break;
1958             }
1959             case REQUEST_ALL_PSS_MSG: {
1960                 synchronized (ActivityManagerService.this) {
1961                     requestPssAllProcsLocked(SystemClock.uptimeMillis(), true, false);
1962                 }
1963                 break;
1964             }
1965             case START_PROFILES_MSG: {
1966                 synchronized (ActivityManagerService.this) {
1967                     mUserController.startProfilesLocked();
1968                 }
1969                 break;
1970             }
1971             case UPDATE_TIME: {
1972                 synchronized (ActivityManagerService.this) {
1973                     for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) {
1974                         ProcessRecord r = mLruProcesses.get(i);
1975                         if (r.thread != null) {
1976                             try {
1977                                 r.thread.updateTimePrefs(msg.arg1 == 0 ? false : true);
1978                             } catch (RemoteException ex) {
1979                                 Slog.w(TAG, "Failed to update preferences for: " + r.info.processName);
1980                             }
1981                         }
1982                     }
1983                 }
1984                 break;
1985             }
1986             case SYSTEM_USER_START_MSG: {
1987                 mBatteryStatsService.noteEvent(BatteryStats.HistoryItem.EVENT_USER_RUNNING_START,
1988                         Integer.toString(msg.arg1), msg.arg1);
1989                 mSystemServiceManager.startUser(msg.arg1);
1990                 break;
1991             }
1992             case SYSTEM_USER_CURRENT_MSG: {
1993                 mBatteryStatsService.noteEvent(
1994                         BatteryStats.HistoryItem.EVENT_USER_FOREGROUND_FINISH,
1995                         Integer.toString(msg.arg2), msg.arg2);
1996                 mBatteryStatsService.noteEvent(
1997                         BatteryStats.HistoryItem.EVENT_USER_FOREGROUND_START,
1998                         Integer.toString(msg.arg1), msg.arg1);
1999                 mSystemServiceManager.switchUser(msg.arg1);
2000                 break;
2001             }
2002             case ENTER_ANIMATION_COMPLETE_MSG: {
2003                 synchronized (ActivityManagerService.this) {
2004                     ActivityRecord r = ActivityRecord.forTokenLocked((IBinder) msg.obj);
2005                     if (r != null && r.app != null && r.app.thread != null) {
2006                         try {
2007                             r.app.thread.scheduleEnterAnimationComplete(r.appToken);
2008                         } catch (RemoteException e) {
2009                         }
2010                     }
2011                 }
2012                 break;
2013             }
2014             case FINISH_BOOTING_MSG: {
2015                 if (msg.arg1 != 0) {
2016                     Trace.traceBegin(Trace.TRACE_TAG_ACTIVITY_MANAGER, "FinishBooting");
2017                     finishBooting();
2018                     Trace.traceEnd(Trace.TRACE_TAG_ACTIVITY_MANAGER);
2019                 }
2020                 if (msg.arg2 != 0) {
2021                     enableScreenAfterBoot();
2022                 }
2023                 break;
2024             }
2025             case SEND_LOCALE_TO_MOUNT_DAEMON_MSG: {
2026                 try {
2027                     Locale l = (Locale) msg.obj;
2028                     IBinder service = ServiceManager.getService("mount");
2029                     IMountService mountService = IMountService.Stub.asInterface(service);
2030                     Log.d(TAG, "Storing locale " + l.toLanguageTag() + " for decryption UI");
2031                     mountService.setField(StorageManager.SYSTEM_LOCALE_KEY, l.toLanguageTag());
2032                 } catch (RemoteException e) {
2033                     Log.e(TAG, "Error storing locale for decryption UI", e);
2034                 }
2035                 break;
2036             }
2037             case NOTIFY_TASK_STACK_CHANGE_LISTENERS_MSG: {
2038                 synchronized (ActivityManagerService.this) {
2039                     int i = mTaskStackListeners.beginBroadcast();
2040                     while (i > 0) {
2041                         i--;
2042                         try {
2043                             // Make a one-way callback to the listener
2044                             mTaskStackListeners.getBroadcastItem(i).onTaskStackChanged();
2045                         } catch (RemoteException e){
2046                             // Handled by the RemoteCallbackList
2047                         }
2048                     }
2049                     mTaskStackListeners.finishBroadcast();
2050                 }
2051                 break;
2052             }
2053             case NOTIFY_CLEARTEXT_NETWORK_MSG: {
2054                 final int uid = msg.arg1;
2055                 final byte[] firstPacket = (byte[]) msg.obj;
2056
2057                 synchronized (mPidsSelfLocked) {
2058                     for (int i = 0; i < mPidsSelfLocked.size(); i++) {
2059                         final ProcessRecord p = mPidsSelfLocked.valueAt(i);
2060                         if (p.uid == uid) {
2061                             try {
2062                                 p.thread.notifyCleartextNetwork(firstPacket);
2063                             } catch (RemoteException ignored) {
2064                             }
2065                         }
2066                     }
2067                 }
2068                 break;
2069             }
2070             case POST_DUMP_HEAP_NOTIFICATION_MSG: {
2071                 final String procName;
2072                 final int uid;
2073                 final long memLimit;
2074                 final String reportPackage;
2075                 synchronized (ActivityManagerService.this) {
2076                     procName = mMemWatchDumpProcName;
2077                     uid = mMemWatchDumpUid;
2078                     Pair<Long, String> val = mMemWatchProcesses.get(procName, uid);
2079                     if (val == null) {
2080                         val = mMemWatchProcesses.get(procName, 0);
2081                     }
2082                     if (val != null) {
2083                         memLimit = val.first;
2084                         reportPackage = val.second;
2085                     } else {
2086                         memLimit = 0;
2087                         reportPackage = null;
2088                     }
2089                 }
2090                 if (procName == null) {
2091                     return;
2092                 }
2093
2094                 if (DEBUG_PSS) Slog.d(TAG_PSS,
2095                         "Showing dump heap notification from " + procName + "/" + uid);
2096
2097                 INotificationManager inm = NotificationManager.getService();
2098                 if (inm == null) {
2099                     return;
2100                 }
2101
2102                 String text = mContext.getString(R.string.dump_heap_notification, procName);
2103
2104
2105                 Intent deleteIntent = new Intent();
2106                 deleteIntent.setAction(DumpHeapActivity.ACTION_DELETE_DUMPHEAP);
2107                 Intent intent = new Intent();
2108                 intent.setClassName("android", DumpHeapActivity.class.getName());
2109                 intent.putExtra(DumpHeapActivity.KEY_PROCESS, procName);
2110                 intent.putExtra(DumpHeapActivity.KEY_SIZE, memLimit);
2111                 if (reportPackage != null) {
2112                     intent.putExtra(DumpHeapActivity.KEY_DIRECT_LAUNCH, reportPackage);
2113                 }
2114                 int userId = UserHandle.getUserId(uid);
2115                 Notification notification = new Notification.Builder(mContext)
2116                         .setSmallIcon(com.android.internal.R.drawable.stat_sys_adb)
2117                         .setWhen(0)
2118                         .setOngoing(true)
2119                         .setAutoCancel(true)
2120                         .setTicker(text)
2121                         .setColor(mContext.getColor(
2122                                 com.android.internal.R.color.system_notification_accent_color))
2123                         .setContentTitle(text)
2124                         .setContentText(
2125                                 mContext.getText(R.string.dump_heap_notification_detail))
2126                         .setContentIntent(PendingIntent.getActivityAsUser(mContext, 0,
2127                                 intent, PendingIntent.FLAG_CANCEL_CURRENT, null,
2128                                 new UserHandle(userId)))
2129                         .setDeleteIntent(PendingIntent.getBroadcastAsUser(mContext, 0,
2130                                 deleteIntent, 0, UserHandle.SYSTEM))
2131                         .build();
2132
2133                 try {
2134                     int[] outId = new int[1];
2135                     inm.enqueueNotificationWithTag("android", "android", null,
2136                             R.string.dump_heap_notification,
2137                             notification, outId, userId);
2138                 } catch (RuntimeException e) {
2139                     Slog.w(ActivityManagerService.TAG,
2140                             "Error showing notification for dump heap", e);
2141                 } catch (RemoteException e) {
2142                 }
2143             } break;
2144             case DELETE_DUMPHEAP_MSG: {
2145                 revokeUriPermission(ActivityThread.currentActivityThread().getApplicationThread(),
2146                         DumpHeapActivity.JAVA_URI,
2147                         Intent.FLAG_GRANT_READ_URI_PERMISSION
2148                                 | Intent.FLAG_GRANT_WRITE_URI_PERMISSION,
2149                         UserHandle.myUserId());
2150                 synchronized (ActivityManagerService.this) {
2151                     mMemWatchDumpFile = null;
2152                     mMemWatchDumpProcName = null;
2153                     mMemWatchDumpPid = -1;
2154                     mMemWatchDumpUid = -1;
2155                 }
2156             } break;
2157             case FOREGROUND_PROFILE_CHANGED_MSG: {
2158                 mUserController.dispatchForegroundProfileChanged(msg.arg1);
2159             } break;
2160             case REPORT_TIME_TRACKER_MSG: {
2161                 AppTimeTracker tracker = (AppTimeTracker)msg.obj;
2162                 tracker.deliverResult(mContext);
2163             } break;
2164             case REPORT_USER_SWITCH_COMPLETE_MSG: {
2165                 mUserController.dispatchUserSwitchComplete(msg.arg1);
2166             } break;
2167             case SHUTDOWN_UI_AUTOMATION_CONNECTION_MSG: {
2168                 IUiAutomationConnection connection = (IUiAutomationConnection) msg.obj;
2169                 try {
2170                     connection.shutdown();
2171                 } catch (RemoteException e) {
2172                     Slog.w(TAG, "Error shutting down UiAutomationConnection");
2173                 }
2174                 // Only a UiAutomation can set this flag and now that
2175                 // it is finished we make sure it is reset to its default.
2176                 mUserIsMonkey = false;
2177             } break;
2178             case APP_BOOST_DEACTIVATE_MSG: {
2179                 synchronized(ActivityManagerService.this) {
2180                     if (mIsBoosted) {
2181                         if (mBoostStartTime < (SystemClock.uptimeMillis() - APP_BOOST_TIMEOUT)) {
2182                             nativeMigrateFromBoost();
2183                             mIsBoosted = false;
2184                             mBoostStartTime = 0;
2185                         } else {
2186                             Message newmsg = mHandler.obtainMessage(APP_BOOST_DEACTIVATE_MSG);
2187                             mHandler.sendMessageDelayed(newmsg, APP_BOOST_TIMEOUT);
2188                         }
2189                     }
2190                 }
2191             } break;
2192             case IDLE_UIDS_MSG: {
2193                 idleUids();
2194             } break;
2195             }
2196         }
2197     };
2198
2199     static final int COLLECT_PSS_BG_MSG = 1;
2200
2201     final Handler mBgHandler = new Handler(BackgroundThread.getHandler().getLooper()) {
2202         @Override
2203         public void handleMessage(Message msg) {
2204             switch (msg.what) {
2205             case COLLECT_PSS_BG_MSG: {
2206                 long start = SystemClock.uptimeMillis();
2207                 MemInfoReader memInfo = null;
2208                 synchronized (ActivityManagerService.this) {
2209                     if (mFullPssPending) {
2210                         mFullPssPending = false;
2211                         memInfo = new MemInfoReader();
2212                     }
2213                 }
2214                 if (memInfo != null) {
2215                     updateCpuStatsNow();
2216                     long nativeTotalPss = 0;
2217                     synchronized (mProcessCpuTracker) {
2218                         final int N = mProcessCpuTracker.countStats();
2219                         for (int j=0; j<N; j++) {
2220                             ProcessCpuTracker.Stats st = mProcessCpuTracker.getStats(j);
2221                             if (st.vsize <= 0 || st.uid >= Process.FIRST_APPLICATION_UID) {
2222                                 // This is definitely an application process; skip it.
2223                                 continue;
2224                             }
2225                             synchronized (mPidsSelfLocked) {
2226                                 if (mPidsSelfLocked.indexOfKey(st.pid) >= 0) {
2227                                     // This is one of our own processes; skip it.
2228                                     continue;
2229                                 }
2230                             }
2231                             nativeTotalPss += Debug.getPss(st.pid, null, null);
2232                         }
2233                     }
2234                     memInfo.readMemInfo();
2235                     synchronized (ActivityManagerService.this) {
2236                         if (DEBUG_PSS) Slog.d(TAG_PSS, "Collected native and kernel memory in "
2237                                 + (SystemClock.uptimeMillis()-start) + "ms");
2238                         final long cachedKb = memInfo.getCachedSizeKb();
2239                         final long freeKb = memInfo.getFreeSizeKb();
2240                         final long zramKb = memInfo.getZramTotalSizeKb();
2241                         final long kernelKb = memInfo.getKernelUsedSizeKb();
2242                         EventLogTags.writeAmMeminfo(cachedKb*1024, freeKb*1024, zramKb*1024,
2243                                 kernelKb*1024, nativeTotalPss*1024);
2244                         mProcessStats.addSysMemUsageLocked(cachedKb, freeKb, zramKb, kernelKb,
2245                                 nativeTotalPss);
2246                     }
2247                 }
2248
2249                 int num = 0;
2250                 long[] tmp = new long[1];
2251                 do {
2252                     ProcessRecord proc;
2253                     int procState;
2254                     int pid;
2255                     long lastPssTime;
2256                     synchronized (ActivityManagerService.this) {
2257                         if (mPendingPssProcesses.size() <= 0) {
2258                             if (mTestPssMode || DEBUG_PSS) Slog.d(TAG_PSS,
2259                                     "Collected PSS of " + num + " processes in "
2260                                     + (SystemClock.uptimeMillis() - start) + "ms");
2261                             mPendingPssProcesses.clear();
2262                             return;
2263                         }
2264                         proc = mPendingPssProcesses.remove(0);
2265                         procState = proc.pssProcState;
2266                         lastPssTime = proc.lastPssTime;
2267                         if (proc.thread != null && procState == proc.setProcState
2268                                 && (lastPssTime+ProcessList.PSS_SAFE_TIME_FROM_STATE_CHANGE)
2269                                         < SystemClock.uptimeMillis()) {
2270                             pid = proc.pid;
2271                         } else {
2272                             proc = null;
2273                             pid = 0;
2274                         }
2275                     }
2276                     if (proc != null) {
2277                         long pss = Debug.getPss(pid, tmp, null);
2278                         synchronized (ActivityManagerService.this) {
2279                             if (pss != 0 && proc.thread != null && proc.setProcState == procState
2280                                     && proc.pid == pid && proc.lastPssTime == lastPssTime) {
2281                                 num++;
2282                                 recordPssSampleLocked(proc, procState, pss, tmp[0],
2283                                         SystemClock.uptimeMillis());
2284                             }
2285                         }
2286                     }
2287                 } while (true);
2288             }
2289             }
2290         }
2291     };
2292
2293     public void setSystemProcess() {
2294         try {
2295             ServiceManager.addService(Context.ACTIVITY_SERVICE, this, true);
2296             ServiceManager.addService(ProcessStats.SERVICE_NAME, mProcessStats);
2297             ServiceManager.addService("meminfo", new MemBinder(this));
2298             ServiceManager.addService("gfxinfo", new GraphicsBinder(this));
2299             ServiceManager.addService("dbinfo", new DbBinder(this));
2300             if (MONITOR_CPU_USAGE) {
2301                 ServiceManager.addService("cpuinfo", new CpuBinder(this));
2302             }
2303             ServiceManager.addService("permission", new PermissionController(this));
2304             ServiceManager.addService("processinfo", new ProcessInfoService(this));
2305
2306             ApplicationInfo info = mContext.getPackageManager().getApplicationInfo(
2307                     "android", STOCK_PM_FLAGS);
2308             mSystemThread.installSystemApplicationInfo(info, getClass().getClassLoader());
2309
2310             synchronized (this) {
2311                 ProcessRecord app = newProcessRecordLocked(info, info.processName, false, 0);
2312                 app.persistent = true;
2313                 app.pid = MY_PID;
2314                 app.maxAdj = ProcessList.SYSTEM_ADJ;
2315                 app.makeActive(mSystemThread.getApplicationThread(), mProcessStats);
2316                 synchronized (mPidsSelfLocked) {
2317                     mPidsSelfLocked.put(app.pid, app);
2318                 }
2319                 updateLruProcessLocked(app, false, null);
2320                 updateOomAdjLocked();
2321             }
2322         } catch (PackageManager.NameNotFoundException e) {
2323             throw new RuntimeException(
2324                     "Unable to find android system package", e);
2325         }
2326     }
2327
2328     public void setWindowManager(WindowManagerService wm) {
2329         mWindowManager = wm;
2330         mStackSupervisor.setWindowManager(wm);
2331     }
2332
2333     public void setUsageStatsManager(UsageStatsManagerInternal usageStatsManager) {
2334         mUsageStatsService = usageStatsManager;
2335     }
2336
2337     public void startObservingNativeCrashes() {
2338         final NativeCrashListener ncl = new NativeCrashListener(this);
2339         ncl.start();
2340     }
2341
2342     public IAppOpsService getAppOpsService() {
2343         return mAppOpsService;
2344     }
2345
2346     static class MemBinder extends Binder {
2347         ActivityManagerService mActivityManagerService;
2348         MemBinder(ActivityManagerService activityManagerService) {
2349             mActivityManagerService = activityManagerService;
2350         }
2351
2352         @Override
2353         protected void dump(FileDescriptor fd, PrintWriter pw, String[] args) {
2354             if (mActivityManagerService.checkCallingPermission(android.Manifest.permission.DUMP)
2355                     != PackageManager.PERMISSION_GRANTED) {
2356                 pw.println("Permission Denial: can't dump meminfo from from pid="
2357                         + Binder.getCallingPid() + ", uid=" + Binder.getCallingUid()
2358                         + " without permission " + android.Manifest.permission.DUMP);
2359                 return;
2360             }
2361
2362             mActivityManagerService.dumpApplicationMemoryUsage(fd, pw, "  ", args, false, null);
2363         }
2364     }
2365
2366     static class GraphicsBinder extends Binder {
2367         ActivityManagerService mActivityManagerService;
2368         GraphicsBinder(ActivityManagerService activityManagerService) {
2369             mActivityManagerService = activityManagerService;
2370         }
2371
2372         @Override
2373         protected void dump(FileDescriptor fd, PrintWriter pw, String[] args) {
2374             if (mActivityManagerService.checkCallingPermission(android.Manifest.permission.DUMP)
2375                     != PackageManager.PERMISSION_GRANTED) {
2376                 pw.println("Permission Denial: can't dump gfxinfo from from pid="
2377                         + Binder.getCallingPid() + ", uid=" + Binder.getCallingUid()
2378                         + " without permission " + android.Manifest.permission.DUMP);
2379                 return;
2380             }
2381
2382             mActivityManagerService.dumpGraphicsHardwareUsage(fd, pw, args);
2383         }
2384     }
2385
2386     static class DbBinder extends Binder {
2387         ActivityManagerService mActivityManagerService;
2388         DbBinder(ActivityManagerService activityManagerService) {
2389             mActivityManagerService = activityManagerService;
2390         }
2391
2392         @Override
2393         protected void dump(FileDescriptor fd, PrintWriter pw, String[] args) {
2394             if (mActivityManagerService.checkCallingPermission(android.Manifest.permission.DUMP)
2395                     != PackageManager.PERMISSION_GRANTED) {
2396                 pw.println("Permission Denial: can't dump dbinfo from from pid="
2397                         + Binder.getCallingPid() + ", uid=" + Binder.getCallingUid()
2398                         + " without permission " + android.Manifest.permission.DUMP);
2399                 return;
2400             }
2401
2402             mActivityManagerService.dumpDbInfo(fd, pw, args);
2403         }
2404     }
2405
2406     static class CpuBinder extends Binder {
2407         ActivityManagerService mActivityManagerService;
2408         CpuBinder(ActivityManagerService activityManagerService) {
2409             mActivityManagerService = activityManagerService;
2410         }
2411
2412         @Override
2413         protected void dump(FileDescriptor fd, PrintWriter pw, String[] args) {
2414             if (mActivityManagerService.checkCallingPermission(android.Manifest.permission.DUMP)
2415                     != PackageManager.PERMISSION_GRANTED) {
2416                 pw.println("Permission Denial: can't dump cpuinfo from from pid="
2417                         + Binder.getCallingPid() + ", uid=" + Binder.getCallingUid()
2418                         + " without permission " + android.Manifest.permission.DUMP);
2419                 return;
2420             }
2421
2422             synchronized (mActivityManagerService.mProcessCpuTracker) {
2423                 pw.print(mActivityManagerService.mProcessCpuTracker.printCurrentLoad());
2424                 pw.print(mActivityManagerService.mProcessCpuTracker.printCurrentState(
2425                         SystemClock.uptimeMillis()));
2426             }
2427         }
2428     }
2429
2430     public static final class Lifecycle extends SystemService {
2431         private final ActivityManagerService mService;
2432
2433         public Lifecycle(Context context) {
2434             super(context);
2435             mService = new ActivityManagerService(context);
2436         }
2437
2438         @Override
2439         public void onStart() {
2440             mService.start();
2441         }
2442
2443         public ActivityManagerService getService() {
2444             return mService;
2445         }
2446     }
2447
2448     // Note: This method is invoked on the main thread but may need to attach various
2449     // handlers to other threads.  So take care to be explicit about the looper.
2450     public ActivityManagerService(Context systemContext) {
2451         mContext = systemContext;
2452         mFactoryTest = FactoryTest.getMode();
2453         mSystemThread = ActivityThread.currentActivityThread();
2454
2455         Slog.i(TAG, "Memory class: " + ActivityManager.staticGetMemoryClass());
2456
2457         mHandlerThread = new ServiceThread(TAG,
2458                 android.os.Process.THREAD_PRIORITY_FOREGROUND, false /*allowIo*/);
2459         mHandlerThread.start();
2460         mHandler = new MainHandler(mHandlerThread.getLooper());
2461         mUiHandler = new UiHandler();
2462
2463         mFgBroadcastQueue = new BroadcastQueue(this, mHandler,
2464                 "foreground", BROADCAST_FG_TIMEOUT, false);
2465         mBgBroadcastQueue = new BroadcastQueue(this, mHandler,
2466                 "background", BROADCAST_BG_TIMEOUT, true);
2467         mBroadcastQueues[0] = mFgBroadcastQueue;
2468         mBroadcastQueues[1] = mBgBroadcastQueue;
2469
2470         mServices = new ActiveServices(this);
2471         mProviderMap = new ProviderMap(this);
2472
2473         // TODO: Move creation of battery stats service outside of activity manager service.
2474         File dataDir = Environment.getDataDirectory();
2475         File systemDir = new File(dataDir, "system");
2476         systemDir.mkdirs();
2477         mBatteryStatsService = new BatteryStatsService(systemDir, mHandler);
2478         mBatteryStatsService.getActiveStatistics().readLocked();
2479         mBatteryStatsService.scheduleWriteToDisk();
2480         mOnBattery = DEBUG_POWER ? true
2481                 : mBatteryStatsService.getActiveStatistics().getIsOnBattery();
2482         mBatteryStatsService.getActiveStatistics().setCallback(this);
2483
2484         mProcessStats = new ProcessStatsService(this, new File(systemDir, "procstats"));
2485
2486         mAppOpsService = new AppOpsService(new File(systemDir, "appops.xml"), mHandler);
2487         mAppOpsService.startWatchingMode(AppOpsManager.OP_RUN_IN_BACKGROUND, null,
2488                 new IAppOpsCallback.Stub() {
2489                     @Override public void opChanged(int op, int uid, String packageName) {
2490                         if (op == AppOpsManager.OP_RUN_IN_BACKGROUND && packageName != null) {
2491                             if (mAppOpsService.checkOperation(op, uid, packageName)
2492                                     != AppOpsManager.MODE_ALLOWED) {
2493                                 runInBackgroundDisabled(uid);
2494                             }
2495                         }
2496                     }
2497                 });
2498
2499         mGrantFile = new AtomicFile(new File(systemDir, "urigrants.xml"));
2500
2501         mUserController = new UserController(this);
2502
2503         GL_ES_VERSION = SystemProperties.getInt("ro.opengles.version",
2504             ConfigurationInfo.GL_ES_VERSION_UNDEFINED);
2505
2506         mTrackingAssociations = "1".equals(SystemProperties.get("debug.track-associations"));
2507
2508         mConfiguration.setToDefaults();
2509         mConfiguration.setLocales(LocaleList.getDefault());
2510
2511         mConfigurationSeq = mConfiguration.seq = 1;
2512         mProcessCpuTracker.init();
2513
2514         mCompatModePackages = new CompatModePackages(this, systemDir, mHandler);
2515         mIntentFirewall = new IntentFirewall(new IntentFirewallInterface(), mHandler);
2516         mRecentTasks = new RecentTasks(this);
2517         mStackSupervisor = new ActivityStackSupervisor(this, mRecentTasks);
2518         mTaskPersister = new TaskPersister(systemDir, mStackSupervisor, mRecentTasks);
2519
2520         mProcessCpuThread = new Thread("CpuTracker") {
2521             @Override
2522             public void run() {
2523                 while (true) {
2524                     try {
2525                         try {
2526                             synchronized(this) {
2527                                 final long now = SystemClock.uptimeMillis();
2528                                 long nextCpuDelay = (mLastCpuTime.get()+MONITOR_CPU_MAX_TIME)-now;
2529                                 long nextWriteDelay = (mLastWriteTime+BATTERY_STATS_TIME)-now;
2530                                 //Slog.i(TAG, "Cpu delay=" + nextCpuDelay
2531                                 //        + ", write delay=" + nextWriteDelay);
2532                                 if (nextWriteDelay < nextCpuDelay) {
2533                                     nextCpuDelay = nextWriteDelay;
2534                                 }
2535                                 if (nextCpuDelay > 0) {
2536                                     mProcessCpuMutexFree.set(true);
2537                                     this.wait(nextCpuDelay);
2538                                 }
2539                             }
2540                         } catch (InterruptedException e) {
2541                         }
2542                         updateCpuStatsNow();
2543                     } catch (Exception e) {
2544                         Slog.e(TAG, "Unexpected exception collecting process stats", e);
2545                     }
2546                 }
2547             }
2548         };
2549
2550         Watchdog.getInstance().addMonitor(this);
2551         Watchdog.getInstance().addThread(mHandler);
2552     }
2553
2554     public void setSystemServiceManager(SystemServiceManager mgr) {
2555         mSystemServiceManager = mgr;
2556     }
2557
2558     public void setInstaller(Installer installer) {
2559         mInstaller = installer;
2560     }
2561
2562     private void start() {
2563         Process.removeAllProcessGroups();
2564         mProcessCpuThread.start();
2565
2566         mBatteryStatsService.publish(mContext);
2567         mAppOpsService.publish(mContext);
2568         Slog.d("AppOps", "AppOpsService published");
2569         LocalServices.addService(ActivityManagerInternal.class, new LocalService());
2570     }
2571
2572     public void initPowerManagement() {
2573         mStackSupervisor.initPowerManagement();
2574         mBatteryStatsService.initPowerManagement();
2575         mLocalPowerManager = LocalServices.getService(PowerManagerInternal.class);
2576         PowerManager pm = (PowerManager)mContext.getSystemService(Context.POWER_SERVICE);
2577         mVoiceWakeLock = pm.newWakeLock(PowerManager.PARTIAL_WAKE_LOCK, "*voice*");
2578         mVoiceWakeLock.setReferenceCounted(false);
2579     }
2580
2581     @Override
2582     public boolean onTransact(int code, Parcel data, Parcel reply, int flags)
2583             throws RemoteException {
2584         if (code == SYSPROPS_TRANSACTION) {
2585             // We need to tell all apps about the system property change.
2586             ArrayList<IBinder> procs = new ArrayList<IBinder>();
2587             synchronized(this) {
2588                 final int NP = mProcessNames.getMap().size();
2589                 for (int ip=0; ip<NP; ip++) {
2590                     SparseArray<ProcessRecord> apps = mProcessNames.getMap().valueAt(ip);
2591                     final int NA = apps.size();
2592                     for (int ia=0; ia<NA; ia++) {
2593                         ProcessRecord app = apps.valueAt(ia);
2594                         if (app.thread != null) {
2595                             procs.add(app.thread.asBinder());
2596                         }
2597                     }
2598                 }
2599             }
2600
2601             int N = procs.size();
2602             for (int i=0; i<N; i++) {
2603                 Parcel data2 = Parcel.obtain();
2604                 try {
2605                     procs.get(i).transact(IBinder.SYSPROPS_TRANSACTION, data2, null, 0);
2606                 } catch (RemoteException e) {
2607                 }
2608                 data2.recycle();
2609             }
2610         }
2611         try {
2612             return super.onTransact(code, data, reply, flags);
2613         } catch (RuntimeException e) {
2614             // The activity manager only throws security exceptions, so let's
2615             // log all others.
2616             if (!(e instanceof SecurityException)) {
2617                 Slog.wtf(TAG, "Activity Manager Crash", e);
2618             }
2619             throw e;
2620         }
2621     }
2622
2623     void updateCpuStats() {
2624         final long now = SystemClock.uptimeMillis();
2625         if (mLastCpuTime.get() >= now - MONITOR_CPU_MIN_TIME) {
2626             return;
2627         }
2628         if (mProcessCpuMutexFree.compareAndSet(true, false)) {
2629             synchronized (mProcessCpuThread) {
2630                 mProcessCpuThread.notify();
2631             }
2632         }
2633     }
2634
2635     void updateCpuStatsNow() {
2636         synchronized (mProcessCpuTracker) {
2637             mProcessCpuMutexFree.set(false);
2638             final long now = SystemClock.uptimeMillis();
2639             boolean haveNewCpuStats = false;
2640
2641             if (MONITOR_CPU_USAGE &&
2642                     mLastCpuTime.get() < (now-MONITOR_CPU_MIN_TIME)) {
2643                 mLastCpuTime.set(now);
2644                 mProcessCpuTracker.update();
2645                 if (mProcessCpuTracker.hasGoodLastStats()) {
2646                     haveNewCpuStats = true;
2647                     //Slog.i(TAG, mProcessCpu.printCurrentState());
2648                     //Slog.i(TAG, "Total CPU usage: "
2649                     //        + mProcessCpu.getTotalCpuPercent() + "%");
2650
2651                     // Slog the cpu usage if the property is set.
2652                     if ("true".equals(SystemProperties.get("events.cpu"))) {
2653                         int user = mProcessCpuTracker.getLastUserTime();
2654                         int system = mProcessCpuTracker.getLastSystemTime();
2655                         int iowait = mProcessCpuTracker.getLastIoWaitTime();
2656                         int irq = mProcessCpuTracker.getLastIrqTime();
2657                         int softIrq = mProcessCpuTracker.getLastSoftIrqTime();
2658                         int idle = mProcessCpuTracker.getLastIdleTime();
2659
2660                         int total = user + system + iowait + irq + softIrq + idle;
2661                         if (total == 0) total = 1;
2662
2663                         EventLog.writeEvent(EventLogTags.CPU,
2664                                 ((user+system+iowait+irq+softIrq) * 100) / total,
2665                                 (user * 100) / total,
2666                                 (system * 100) / total,
2667                                 (iowait * 100) / total,
2668                                 (irq * 100) / total,
2669                                 (softIrq * 100) / total);
2670                     }
2671                 }
2672             }
2673
2674             final BatteryStatsImpl bstats = mBatteryStatsService.getActiveStatistics();
2675             synchronized(bstats) {
2676                 synchronized(mPidsSelfLocked) {
2677                     if (haveNewCpuStats) {
2678                         if (bstats.startAddingCpuLocked()) {
2679                             int totalUTime = 0;
2680                             int totalSTime = 0;
2681                             final int N = mProcessCpuTracker.countStats();
2682                             for (int i=0; i<N; i++) {
2683                                 ProcessCpuTracker.Stats st = mProcessCpuTracker.getStats(i);
2684                                 if (!st.working) {
2685                                     continue;
2686                                 }
2687                                 ProcessRecord pr = mPidsSelfLocked.get(st.pid);
2688                                 totalUTime += st.rel_utime;
2689                                 totalSTime += st.rel_stime;
2690                                 if (pr != null) {
2691                                     BatteryStatsImpl.Uid.Proc ps = pr.curProcBatteryStats;
2692                                     if (ps == null || !ps.isActive()) {
2693                                         pr.curProcBatteryStats = ps = bstats.getProcessStatsLocked(
2694                                                 pr.info.uid, pr.processName);
2695                                     }
2696                                     ps.addCpuTimeLocked(st.rel_utime, st.rel_stime);
2697                                     pr.curCpuTime += st.rel_utime + st.rel_stime;
2698                                 } else {
2699                                     BatteryStatsImpl.Uid.Proc ps = st.batteryStats;
2700                                     if (ps == null || !ps.isActive()) {
2701                                         st.batteryStats = ps = bstats.getProcessStatsLocked(
2702                                                 bstats.mapUid(st.uid), st.name);
2703                                     }
2704                                     ps.addCpuTimeLocked(st.rel_utime, st.rel_stime);
2705                                 }
2706                             }
2707                             final int userTime = mProcessCpuTracker.getLastUserTime();
2708                             final int systemTime = mProcessCpuTracker.getLastSystemTime();
2709                             final int iowaitTime = mProcessCpuTracker.getLastIoWaitTime();
2710                             final int irqTime = mProcessCpuTracker.getLastIrqTime();
2711                             final int softIrqTime = mProcessCpuTracker.getLastSoftIrqTime();
2712                             final int idleTime = mProcessCpuTracker.getLastIdleTime();
2713                             bstats.finishAddingCpuLocked(totalUTime, totalSTime, userTime,
2714                                     systemTime, iowaitTime, irqTime, softIrqTime, idleTime);
2715                         }
2716                     }
2717                 }
2718
2719                 if (mLastWriteTime < (now-BATTERY_STATS_TIME)) {
2720                     mLastWriteTime = now;
2721                     mBatteryStatsService.scheduleWriteToDisk();
2722                 }
2723             }
2724         }
2725     }
2726
2727     @Override
2728     public void batteryNeedsCpuUpdate() {
2729         updateCpuStatsNow();
2730     }
2731
2732     @Override
2733     public void batteryPowerChanged(boolean onBattery) {
2734         // When plugging in, update the CPU stats first before changing
2735         // the plug state.
2736         updateCpuStatsNow();
2737         synchronized (this) {
2738             synchronized(mPidsSelfLocked) {
2739                 mOnBattery = DEBUG_POWER ? true : onBattery;
2740             }
2741         }
2742     }
2743
2744     @Override
2745     public void batterySendBroadcast(Intent intent) {
2746         broadcastIntentLocked(null, null, intent, null, null, 0, null, null, null,
2747                 AppOpsManager.OP_NONE, null, false, false,
2748                 -1, Process.SYSTEM_UID, UserHandle.USER_ALL);
2749     }
2750
2751     /**
2752      * Initialize the application bind args. These are passed to each
2753      * process when the bindApplication() IPC is sent to the process. They're
2754      * lazily setup to make sure the services are running when they're asked for.
2755      */
2756     private HashMap<String, IBinder> getCommonServicesLocked(boolean isolated) {
2757         if (mAppBindArgs == null) {
2758             mAppBindArgs = new HashMap<>();
2759
2760             // Isolated processes won't get this optimization, so that we don't
2761             // violate the rules about which services they have access to.
2762             if (!isolated) {
2763                 // Setup the application init args
2764                 mAppBindArgs.put("package", ServiceManager.getService("package"));
2765                 mAppBindArgs.put("window", ServiceManager.getService("window"));
2766                 mAppBindArgs.put(Context.ALARM_SERVICE,
2767                         ServiceManager.getService(Context.ALARM_SERVICE));
2768             }
2769         }
2770         return mAppBindArgs;
2771     }
2772
2773     final void setFocusedActivityLocked(ActivityRecord r, String reason) {
2774         if (r == null || mFocusedActivity == r) {
2775             return;
2776         }
2777
2778         if (DEBUG_FOCUS) Slog.d(TAG_FOCUS, "setFocusedActivityLocked: r=" + r);
2779         final ActivityRecord last = mFocusedActivity;
2780         mFocusedActivity = r;
2781         if (r.task.isApplicationTask()) {
2782             if (mCurAppTimeTracker != r.appTimeTracker) {
2783                 // We are switching app tracking.  Complete the current one.
2784                 if (mCurAppTimeTracker != null) {
2785                     mCurAppTimeTracker.stop();
2786                     mHandler.obtainMessage(
2787                             REPORT_TIME_TRACKER_MSG, mCurAppTimeTracker).sendToTarget();
2788                     mStackSupervisor.clearOtherAppTimeTrackers(r.appTimeTracker);
2789                     mCurAppTimeTracker = null;
2790                 }
2791                 if (r.appTimeTracker != null) {
2792                     mCurAppTimeTracker = r.appTimeTracker;
2793                     startTimeTrackingFocusedActivityLocked();
2794                 }
2795             } else {
2796                 startTimeTrackingFocusedActivityLocked();
2797             }
2798         } else {
2799             r.appTimeTracker = null;
2800         }
2801         if (r.task.voiceInteractor != null) {
2802             startRunningVoiceLocked(r.task.voiceSession, r.info.applicationInfo.uid);
2803         } else {
2804             finishRunningVoiceLocked();
2805             if (last != null && last.task.voiceSession != null) {
2806                 // We had been in a voice interaction session, but now focused has
2807                 // move to something different.  Just finish the session, we can't
2808                 // return to it and retain the proper state and synchronization with
2809                 // the voice interaction service.
2810                 finishVoiceTask(last.task.voiceSession);
2811             }
2812         }
2813         if (mStackSupervisor.setFocusedStack(r, reason + " setFocusedActivity")) {
2814             mWindowManager.setFocusedApp(r.appToken, true);
2815         }
2816         applyUpdateLockStateLocked(r);
2817         if (mFocusedActivity.userId != mLastFocusedUserId) {
2818             mHandler.removeMessages(FOREGROUND_PROFILE_CHANGED_MSG);
2819             mHandler.obtainMessage(
2820                     FOREGROUND_PROFILE_CHANGED_MSG, mFocusedActivity.userId, 0).sendToTarget();
2821             mLastFocusedUserId = mFocusedActivity.userId;
2822         }
2823
2824         EventLogTags.writeAmFocusedActivity(
2825                 mFocusedActivity == null ? -1 : mFocusedActivity.userId,
2826                 mFocusedActivity == null ? "NULL" : mFocusedActivity.shortComponentName,
2827                 reason);
2828     }
2829
2830     final void clearFocusedActivity(ActivityRecord r) {
2831         if (mFocusedActivity == r) {
2832             ActivityStack stack = mStackSupervisor.getFocusedStack();
2833             if (stack != null) {
2834                 ActivityRecord top = stack.topActivity();
2835                 if (top != null && top.userId != mLastFocusedUserId) {
2836                     mHandler.removeMessages(FOREGROUND_PROFILE_CHANGED_MSG);
2837                     mHandler.sendMessage(mHandler.obtainMessage(FOREGROUND_PROFILE_CHANGED_MSG,
2838                                     top.userId, 0));
2839                     mLastFocusedUserId = top.userId;
2840                 }
2841             }
2842             mFocusedActivity = null;
2843             EventLogTags.writeAmFocusedActivity(-1, "NULL", "clearFocusedActivity");
2844         }
2845     }
2846
2847     @Override
2848     public void setFocusedStack(int stackId) {
2849         if (DEBUG_FOCUS) Slog.d(TAG_FOCUS, "setFocusedStack: stackId=" + stackId);
2850         synchronized (ActivityManagerService.this) {
2851             ActivityStack stack = mStackSupervisor.getStack(stackId);
2852             if (stack != null) {
2853                 ActivityRecord r = stack.topRunningActivityLocked();
2854                 if (r != null) {
2855                     setFocusedActivityLocked(r, "setFocusedStack");
2856                     mStackSupervisor.resumeTopActivitiesLocked(stack, null, null);
2857                 }
2858             }
2859         }
2860     }
2861
2862     @Override
2863     public void setFocusedTask(int taskId) {
2864         if (DEBUG_FOCUS) Slog.d(TAG_FOCUS, "setFocusedTask: taskId=" + taskId);
2865         long callingId = Binder.clearCallingIdentity();
2866         try {
2867             synchronized (ActivityManagerService.this) {
2868                 TaskRecord task = mStackSupervisor.anyTaskForIdLocked(taskId);
2869                 if (task != null) {
2870                     ActivityRecord r = task.topRunningActivityLocked();
2871                     if (r != null) {
2872                         setFocusedActivityLocked(r, "setFocusedTask");
2873                         mStackSupervisor.resumeTopActivitiesLocked(task.stack, null, null);
2874                     }
2875                 }
2876             }
2877         } finally {
2878             Binder.restoreCallingIdentity(callingId);
2879         }
2880     }
2881
2882     /** Sets the task stack listener that gets callbacks when a task stack changes. */
2883     @Override
2884     public void registerTaskStackListener(ITaskStackListener listener) throws RemoteException {
2885         synchronized (ActivityManagerService.this) {
2886             if (listener != null) {
2887                 mTaskStackListeners.register(listener);
2888             }
2889         }
2890     }
2891
2892     @Override
2893     public void notifyActivityDrawn(IBinder token) {
2894         if (DEBUG_VISIBILITY) Slog.d(TAG_VISIBILITY, "notifyActivityDrawn: token=" + token);
2895         synchronized (this) {
2896             ActivityRecord r = mStackSupervisor.isInAnyStackLocked(token);
2897             if (r != null) {
2898                 r.task.stack.notifyActivityDrawnLocked(r);
2899             }
2900         }
2901     }
2902
2903     final void applyUpdateLockStateLocked(ActivityRecord r) {
2904         // Modifications to the UpdateLock state are done on our handler, outside
2905         // the activity manager's locks.  The new state is determined based on the
2906         // state *now* of the relevant activity record.  The object is passed to
2907         // the handler solely for logging detail, not to be consulted/modified.
2908         final boolean nextState = r != null && r.immersive;
2909         mHandler.sendMessage(
2910                 mHandler.obtainMessage(IMMERSIVE_MODE_LOCK_MSG, (nextState) ? 1 : 0, 0, r));
2911     }
2912
2913     final void showAskCompatModeDialogLocked(ActivityRecord r) {
2914         Message msg = Message.obtain();
2915         msg.what = SHOW_COMPAT_MODE_DIALOG_UI_MSG;
2916         msg.obj = r.task.askedCompatMode ? null : r;
2917         mUiHandler.sendMessage(msg);
2918     }
2919
2920     private int updateLruProcessInternalLocked(ProcessRecord app, long now, int index,
2921             String what, Object obj, ProcessRecord srcApp) {
2922         app.lastActivityTime = now;
2923
2924         if (app.activities.size() > 0) {
2925             // Don't want to touch dependent processes that are hosting activities.
2926             return index;
2927         }
2928
2929         int lrui = mLruProcesses.lastIndexOf(app);
2930         if (lrui < 0) {
2931             Slog.wtf(TAG, "Adding dependent process " + app + " not on LRU list: "
2932                     + what + " " + obj + " from " + srcApp);
2933             return index;
2934         }
2935
2936         if (lrui >= index) {
2937             // Don't want to cause this to move dependent processes *back* in the
2938             // list as if they were less frequently used.
2939             return index;
2940         }
2941
2942         if (lrui >= mLruProcessActivityStart) {
2943             // Don't want to touch dependent processes that are hosting activities.
2944             return index;
2945         }
2946
2947         mLruProcesses.remove(lrui);
2948         if (index > 0) {
2949             index--;
2950         }
2951         if (DEBUG_LRU) Slog.d(TAG_LRU, "Moving dep from " + lrui + " to " + index
2952                 + " in LRU list: " + app);
2953         mLruProcesses.add(index, app);
2954         return index;
2955     }
2956
2957     private static void killProcessGroup(int uid, int pid) {
2958         Trace.traceBegin(Trace.TRACE_TAG_ACTIVITY_MANAGER, "killProcessGroup");
2959         Process.killProcessGroup(uid, pid);
2960         Trace.traceEnd(Trace.TRACE_TAG_ACTIVITY_MANAGER);
2961     }
2962
2963     final void removeLruProcessLocked(ProcessRecord app) {
2964         int lrui = mLruProcesses.lastIndexOf(app);
2965         if (lrui >= 0) {
2966             if (!app.killed) {
2967                 Slog.wtfStack(TAG, "Removing process that hasn't been killed: " + app);
2968                 Process.killProcessQuiet(app.pid);
2969                 killProcessGroup(app.info.uid, app.pid);
2970             }
2971             if (lrui <= mLruProcessActivityStart) {
2972                 mLruProcessActivityStart--;
2973             }
2974             if (lrui <= mLruProcessServiceStart) {
2975                 mLruProcessServiceStart--;
2976             }
2977             mLruProcesses.remove(lrui);
2978         }
2979     }
2980
2981     final void updateLruProcessLocked(ProcessRecord app, boolean activityChange,
2982             ProcessRecord client) {
2983         final boolean hasActivity = app.activities.size() > 0 || app.hasClientActivities
2984                 || app.treatLikeActivity;
2985         final boolean hasService = false; // not impl yet. app.services.size() > 0;
2986         if (!activityChange && hasActivity) {
2987             // The process has activities, so we are only allowing activity-based adjustments
2988             // to move it.  It should be kept in the front of the list with other
2989             // processes that have activities, and we don't want those to change their
2990             // order except due to activity operations.
2991             return;
2992         }
2993
2994         mLruSeq++;
2995         final long now = SystemClock.uptimeMillis();
2996         app.lastActivityTime = now;
2997
2998         // First a quick reject: if the app is already at the position we will
2999         // put it, then there is nothing to do.
3000         if (hasActivity) {
3001             final int N = mLruProcesses.size();
3002             if (N > 0 && mLruProcesses.get(N-1) == app) {
3003                 if (DEBUG_LRU) Slog.d(TAG_LRU, "Not moving, already top activity: " + app);
3004                 return;
3005             }
3006         } else {
3007             if (mLruProcessServiceStart > 0
3008                     && mLruProcesses.get(mLruProcessServiceStart-1) == app) {
3009                 if (DEBUG_LRU) Slog.d(TAG_LRU, "Not moving, already top other: " + app);
3010                 return;
3011             }
3012         }
3013
3014         int lrui = mLruProcesses.lastIndexOf(app);
3015
3016         if (app.persistent && lrui >= 0) {
3017             // We don't care about the position of persistent processes, as long as
3018             // they are in the list.
3019             if (DEBUG_LRU) Slog.d(TAG_LRU, "Not moving, persistent: " + app);
3020             return;
3021         }
3022
3023         /* In progress: compute new position first, so we can avoid doing work
3024            if the process is not actually going to move.  Not yet working.
3025         int addIndex;
3026         int nextIndex;
3027         boolean inActivity = false, inService = false;
3028         if (hasActivity) {
3029             // Process has activities, put it at the very tipsy-top.
3030             addIndex = mLruProcesses.size();
3031             nextIndex = mLruProcessServiceStart;
3032             inActivity = true;
3033         } else if (hasService) {
3034             // Process has services, put it at the top of the service list.
3035             addIndex = mLruProcessActivityStart;
3036             nextIndex = mLruProcessServiceStart;
3037             inActivity = true;
3038             inService = true;
3039         } else  {
3040             // Process not otherwise of interest, it goes to the top of the non-service area.
3041             addIndex = mLruProcessServiceStart;
3042             if (client != null) {
3043                 int clientIndex = mLruProcesses.lastIndexOf(client);
3044                 if (clientIndex < 0) Slog.d(TAG, "Unknown client " + client + " when updating "
3045                         + app);
3046                 if (clientIndex >= 0 && addIndex > clientIndex) {
3047                     addIndex = clientIndex;
3048                 }
3049             }
3050             nextIndex = addIndex > 0 ? addIndex-1 : addIndex;
3051         }
3052
3053         Slog.d(TAG, "Update LRU at " + lrui + " to " + addIndex + " (act="
3054                 + mLruProcessActivityStart + "): " + app);
3055         */
3056
3057         if (lrui >= 0) {
3058             if (lrui < mLruProcessActivityStart) {
3059                 mLruProcessActivityStart--;
3060             }
3061             if (lrui < mLruProcessServiceStart) {
3062                 mLruProcessServiceStart--;
3063             }
3064             /*
3065             if (addIndex > lrui) {
3066                 addIndex--;
3067             }
3068             if (nextIndex > lrui) {
3069                 nextIndex--;
3070             }
3071             */
3072             mLruProcesses.remove(lrui);
3073         }
3074
3075         /*
3076         mLruProcesses.add(addIndex, app);
3077         if (inActivity) {
3078             mLruProcessActivityStart++;
3079         }
3080         if (inService) {
3081             mLruProcessActivityStart++;
3082         }
3083         */
3084
3085         int nextIndex;
3086         if (hasActivity) {
3087             final int N = mLruProcesses.size();
3088             if (app.activities.size() == 0 && mLruProcessActivityStart < (N - 1)) {
3089                 // Process doesn't have activities, but has clients with
3090                 // activities...  move it up, but one below the top (the top
3091                 // should always have a real activity).
3092                 if (DEBUG_LRU) Slog.d(TAG_LRU,
3093                         "Adding to second-top of LRU activity list: " + app);
3094                 mLruProcesses.add(N - 1, app);
3095                 // To keep it from spamming the LRU list (by making a bunch of clients),
3096                 // we will push down any other entries owned by the app.
3097                 final int uid = app.info.uid;
3098                 for (int i = N - 2; i > mLruProcessActivityStart; i--) {
3099                     ProcessRecord subProc = mLruProcesses.get(i);
3100                     if (subProc.info.uid == uid) {
3101                         // We want to push this one down the list.  If the process after
3102                         // it is for the same uid, however, don't do so, because we don't
3103                         // want them internally to be re-ordered.
3104                         if (mLruProcesses.get(i - 1).info.uid != uid) {
3105                             if (DEBUG_LRU) Slog.d(TAG_LRU,
3106                                     "Pushing uid " + uid + " swapping at " + i + ": "
3107                                     + mLruProcesses.get(i) + " : " + mLruProcesses.get(i - 1));
3108                             ProcessRecord tmp = mLruProcesses.get(i);
3109                             mLruProcesses.set(i, mLruProcesses.get(i - 1));
3110                             mLruProcesses.set(i - 1, tmp);
3111                             i--;
3112                         }
3113                     } else {
3114                         // A gap, we can stop here.
3115                         break;
3116                     }
3117                 }
3118             } else {
3119                 // Process has activities, put it at the very tipsy-top.
3120                 if (DEBUG_LRU) Slog.d(TAG_LRU, "Adding to top of LRU activity list: " + app);
3121                 mLruProcesses.add(app);
3122             }
3123             nextIndex = mLruProcessServiceStart;
3124         } else if (hasService) {
3125             // Process has services, put it at the top of the service list.
3126             if (DEBUG_LRU) Slog.d(TAG_LRU, "Adding to top of LRU service list: " + app);
3127             mLruProcesses.add(mLruProcessActivityStart, app);
3128             nextIndex = mLruProcessServiceStart;
3129             mLruProcessActivityStart++;
3130         } else  {
3131             // Process not otherwise of interest, it goes to the top of the non-service area.
3132             int index = mLruProcessServiceStart;
3133             if (client != null) {
3134                 // If there is a client, don't allow the process to be moved up higher
3135                 // in the list than that client.
3136                 int clientIndex = mLruProcesses.lastIndexOf(client);
3137                 if (DEBUG_LRU && clientIndex < 0) Slog.d(TAG_LRU, "Unknown client " + client
3138                         + " when updating " + app);
3139                 if (clientIndex <= lrui) {
3140                     // Don't allow the client index restriction to push it down farther in the
3141                     // list than it already is.
3142                     clientIndex = lrui;
3143                 }
3144                 if (clientIndex >= 0 && index > clientIndex) {
3145                     index = clientIndex;
3146                 }
3147             }
3148             if (DEBUG_LRU) Slog.d(TAG_LRU, "Adding at " + index + " of LRU list: " + app);
3149             mLruProcesses.add(index, app);
3150             nextIndex = index-1;
3151             mLruProcessActivityStart++;
3152             mLruProcessServiceStart++;
3153         }
3154
3155         // If the app is currently using a content provider or service,
3156         // bump those processes as well.
3157         for (int j=app.connections.size()-1; j>=0; j--) {
3158             ConnectionRecord cr = app.connections.valueAt(j);
3159             if (cr.binding != null && !cr.serviceDead && cr.binding.service != null
3160                     && cr.binding.service.app != null
3161                     && cr.binding.service.app.lruSeq != mLruSeq
3162                     && !cr.binding.service.app.persistent) {
3163                 nextIndex = updateLruProcessInternalLocked(cr.binding.service.app, now, nextIndex,
3164                         "service connection", cr, app);
3165             }
3166         }
3167         for (int j=app.conProviders.size()-1; j>=0; j--) {
3168             ContentProviderRecord cpr = app.conProviders.get(j).provider;
3169             if (cpr.proc != null && cpr.proc.lruSeq != mLruSeq && !cpr.proc.persistent) {
3170                 nextIndex = updateLruProcessInternalLocked(cpr.proc, now, nextIndex,
3171                         "provider reference", cpr, app);
3172             }
3173         }
3174     }
3175
3176     final ProcessRecord getProcessRecordLocked(String processName, int uid, boolean keepIfLarge) {
3177         if (uid == Process.SYSTEM_UID) {
3178             // The system gets to run in any process.  If there are multiple
3179             // processes with the same uid, just pick the first (this
3180             // should never happen).
3181             SparseArray<ProcessRecord> procs = mProcessNames.getMap().get(processName);
3182             if (procs == null) return null;
3183             final int procCount = procs.size();
3184             for (int i = 0; i < procCount; i++) {
3185                 final int procUid = procs.keyAt(i);
3186                 if (UserHandle.isApp(procUid) || !UserHandle.isSameUser(procUid, uid)) {
3187                     // Don't use an app process or different user process for system component.
3188                     continue;
3189                 }
3190                 return procs.valueAt(i);
3191             }
3192         }
3193         ProcessRecord proc = mProcessNames.get(processName, uid);
3194         if (false && proc != null && !keepIfLarge
3195                 && proc.setProcState >= ActivityManager.PROCESS_STATE_CACHED_EMPTY
3196                 && proc.lastCachedPss >= 4000) {
3197             // Turn this condition on to cause killing to happen regularly, for testing.
3198             if (proc.baseProcessTracker != null) {
3199                 proc.baseProcessTracker.reportCachedKill(proc.pkgList, proc.lastCachedPss);
3200             }
3201             proc.kill(Long.toString(proc.lastCachedPss) + "k from cached", true);
3202         } else if (proc != null && !keepIfLarge
3203                 && mLastMemoryLevel > ProcessStats.ADJ_MEM_FACTOR_NORMAL
3204                 && proc.setProcState >= ActivityManager.PROCESS_STATE_CACHED_EMPTY) {
3205             if (DEBUG_PSS) Slog.d(TAG_PSS, "May not keep " + proc + ": pss=" + proc.lastCachedPss);
3206             if (proc.lastCachedPss >= mProcessList.getCachedRestoreThresholdKb()) {
3207                 if (proc.baseProcessTracker != null) {
3208                     proc.baseProcessTracker.reportCachedKill(proc.pkgList, proc.lastCachedPss);
3209                 }
3210                 proc.kill(Long.toString(proc.lastCachedPss) + "k from cached", true);
3211             }
3212         }
3213         return proc;
3214     }
3215
3216     void notifyPackageUse(String packageName) {
3217         IPackageManager pm = AppGlobals.getPackageManager();
3218         try {
3219             pm.notifyPackageUse(packageName);
3220         } catch (RemoteException e) {
3221         }
3222     }
3223
3224     boolean isNextTransitionForward() {
3225         int transit = mWindowManager.getPendingAppTransition();
3226         return transit == AppTransition.TRANSIT_ACTIVITY_OPEN
3227                 || transit == AppTransition.TRANSIT_TASK_OPEN
3228                 || transit == AppTransition.TRANSIT_TASK_TO_FRONT;
3229     }
3230
3231     int startIsolatedProcess(String entryPoint, String[] entryPointArgs,
3232             String processName, String abiOverride, int uid, Runnable crashHandler) {
3233         synchronized(this) {
3234             ApplicationInfo info = new ApplicationInfo();
3235             // In general the ApplicationInfo.uid isn't neccesarily equal to ProcessRecord.uid.
3236             // For isolated processes, the former contains the parent's uid and the latter the
3237             // actual uid of the isolated process.
3238             // In the special case introduced by this method (which is, starting an isolated
3239             // process directly from the SystemServer without an actual parent app process) the
3240             // closest thing to a parent's uid is SYSTEM_UID.
3241             // The only important thing here is to keep AI.uid != PR.uid, in order to trigger
3242             // the |isolated| logic in the ProcessRecord constructor.
3243             info.uid = Process.SYSTEM_UID;
3244             info.processName = processName;
3245             info.className = entryPoint;
3246             info.packageName = "android";
3247             ProcessRecord proc = startProcessLocked(processName, info /* info */,
3248                     false /* knownToBeDead */, 0 /* intentFlags */, ""  /* hostingType */,
3249                     null /* hostingName */, true /* allowWhileBooting */, true /* isolated */,
3250                     uid, true /* keepIfLarge */, abiOverride, entryPoint, entryPointArgs,
3251                     crashHandler);
3252             return proc != null ? proc.pid : 0;
3253         }
3254     }
3255
3256     final ProcessRecord startProcessLocked(String processName,
3257             ApplicationInfo info, boolean knownToBeDead, int intentFlags,
3258             String hostingType, ComponentName hostingName, boolean allowWhileBooting,
3259             boolean isolated, boolean keepIfLarge) {
3260         return startProcessLocked(processName, info, knownToBeDead, intentFlags, hostingType,
3261                 hostingName, allowWhileBooting, isolated, 0 /* isolatedUid */, keepIfLarge,
3262                 null /* ABI override */, null /* entryPoint */, null /* entryPointArgs */,
3263                 null /* crashHandler */);
3264     }
3265
3266     final ProcessRecord startProcessLocked(String processName, ApplicationInfo info,
3267             boolean knownToBeDead, int intentFlags, String hostingType, ComponentName hostingName,
3268             boolean allowWhileBooting, boolean isolated, int isolatedUid, boolean keepIfLarge,
3269             String abiOverride, String entryPoint, String[] entryPointArgs, Runnable crashHandler) {
3270         long startTime = SystemClock.elapsedRealtime();
3271         ProcessRecord app;
3272         if (!isolated) {
3273             app = getProcessRecordLocked(processName, info.uid, keepIfLarge);
3274             checkTime(startTime, "startProcess: after getProcessRecord");
3275
3276             if ((intentFlags & Intent.FLAG_FROM_BACKGROUND) != 0) {
3277                 // If we are in the background, then check to see if this process
3278                 // is bad.  If so, we will just silently fail.
3279                 if (mBadProcesses.get(info.processName, info.uid) != null) {
3280                     if (DEBUG_PROCESSES) Slog.v(TAG, "Bad process: " + info.uid
3281                             + "/" + info.processName);
3282                     return null;
3283                 }
3284             } else {
3285                 // When the user is explicitly starting a process, then clear its
3286                 // crash count so that we won't make it bad until they see at
3287                 // least one crash dialog again, and make the process good again
3288                 // if it had been bad.
3289                 if (DEBUG_PROCESSES) Slog.v(TAG, "Clearing bad process: " + info.uid
3290                         + "/" + info.processName);
3291                 mProcessCrashTimes.remove(info.processName, info.uid);
3292                 if (mBadProcesses.get(info.processName, info.uid) != null) {
3293                     EventLog.writeEvent(EventLogTags.AM_PROC_GOOD,
3294                             UserHandle.getUserId(info.uid), info.uid,
3295                             info.processName);
3296                     mBadProcesses.remove(info.processName, info.uid);
3297                     if (app != null) {
3298                         app.bad = false;
3299                     }
3300                 }
3301             }
3302         } else {
3303             // If this is an isolated process, it can't re-use an existing process.
3304             app = null;
3305         }
3306
3307         // app launch boost for big.little configurations
3308         // use cpusets to migrate freshly launched tasks to big cores
3309         synchronized(ActivityManagerService.this) {
3310             nativeMigrateToBoost();
3311             mIsBoosted = true;
3312             mBoostStartTime = SystemClock.uptimeMillis();
3313             Message msg = mHandler.obtainMessage(APP_BOOST_DEACTIVATE_MSG);
3314             mHandler.sendMessageDelayed(msg, APP_BOOST_MESSAGE_DELAY);
3315         }
3316
3317         // We don't have to do anything more if:
3318         // (1) There is an existing application record; and
3319         // (2) The caller doesn't think it is dead, OR there is no thread
3320         //     object attached to it so we know it couldn't have crashed; and
3321         // (3) There is a pid assigned to it, so it is either starting or
3322         //     already running.
3323         if (DEBUG_PROCESSES) Slog.v(TAG_PROCESSES, "startProcess: name=" + processName
3324                 + " app=" + app + " knownToBeDead=" + knownToBeDead
3325                 + " thread=" + (app != null ? app.thread : null)
3326                 + " pid=" + (app != null ? app.pid : -1));
3327         if (app != null && app.pid > 0) {
3328             if (!knownToBeDead || app.thread == null) {
3329                 // We already have the app running, or are waiting for it to
3330                 // come up (we have a pid but not yet its thread), so keep it.
3331                 if (DEBUG_PROCESSES) Slog.v(TAG_PROCESSES, "App already running: " + app);
3332                 // If this is a new package in the process, add the package to the list
3333                 app.addPackage(info.packageName, info.versionCode, mProcessStats);
3334                 checkTime(startTime, "startProcess: done, added package to proc");
3335                 return app;
3336             }
3337
3338             // An application record is attached to a previous process,
3339             // clean it up now.
3340             if (DEBUG_PROCESSES || DEBUG_CLEANUP) Slog.v(TAG_PROCESSES, "App died: " + app);
3341             checkTime(startTime, "startProcess: bad proc running, killing");
3342             killProcessGroup(app.info.uid, app.pid);
3343             handleAppDiedLocked(app, true, true);
3344             checkTime(startTime, "startProcess: done killing old proc");
3345         }
3346
3347         String hostingNameStr = hostingName != null
3348                 ? hostingName.flattenToShortString() : null;
3349
3350         if (app == null) {
3351             checkTime(startTime, "startProcess: creating new process record");
3352             app = newProcessRecordLocked(info, processName, isolated, isolatedUid);
3353             if (app == null) {
3354                 Slog.w(TAG, "Failed making new process record for "
3355                         + processName + "/" + info.uid + " isolated=" + isolated);
3356                 return null;
3357             }
3358             app.crashHandler = crashHandler;
3359             checkTime(startTime, "startProcess: done creating new process record");
3360         } else {
3361             // If this is a new package in the process, add the package to the list
3362             app.addPackage(info.packageName, info.versionCode, mProcessStats);
3363             checkTime(startTime, "startProcess: added package to existing proc");
3364         }
3365
3366         // If the system is not ready yet, then hold off on starting this
3367         // process until it is.
3368         if (!mProcessesReady
3369                 && !isAllowedWhileBooting(info)
3370                 && !allowWhileBooting) {
3371             if (!mProcessesOnHold.contains(app)) {
3372                 mProcessesOnHold.add(app);
3373             }
3374             if (DEBUG_PROCESSES) Slog.v(TAG_PROCESSES,
3375                     "System not ready, putting on hold: " + app);
3376             checkTime(startTime, "startProcess: returning with proc on hold");
3377             return app;
3378         }
3379
3380         checkTime(startTime, "startProcess: stepping in to startProcess");
3381         startProcessLocked(
3382                 app, hostingType, hostingNameStr, abiOverride, entryPoint, entryPointArgs);
3383         checkTime(startTime, "startProcess: done starting proc!");
3384         return (app.pid != 0) ? app : null;
3385     }
3386
3387     boolean isAllowedWhileBooting(ApplicationInfo ai) {
3388         return (ai.flags&ApplicationInfo.FLAG_PERSISTENT) != 0;
3389     }
3390
3391     private final void startProcessLocked(ProcessRecord app,
3392             String hostingType, String hostingNameStr) {
3393         startProcessLocked(app, hostingType, hostingNameStr, null /* abiOverride */,
3394                 null /* entryPoint */, null /* entryPointArgs */);
3395     }
3396
3397     private final void startProcessLocked(ProcessRecord app, String hostingType,
3398             String hostingNameStr, String abiOverride, String entryPoint, String[] entryPointArgs) {
3399         long startTime = SystemClock.elapsedRealtime();
3400         if (app.pid > 0 && app.pid != MY_PID) {
3401             checkTime(startTime, "startProcess: removing from pids map");
3402             synchronized (mPidsSelfLocked) {
3403                 mPidsSelfLocked.remove(app.pid);
3404                 mHandler.removeMessages(PROC_START_TIMEOUT_MSG, app);
3405             }
3406             checkTime(startTime, "startProcess: done removing from pids map");
3407             app.setPid(0);
3408         }
3409
3410         if (DEBUG_PROCESSES && mProcessesOnHold.contains(app)) Slog.v(TAG_PROCESSES,
3411                 "startProcessLocked removing on hold: " + app);
3412         mProcessesOnHold.remove(app);
3413
3414         checkTime(startTime, "startProcess: starting to update cpu stats");
3415         updateCpuStats();
3416         checkTime(startTime, "startProcess: done updating cpu stats");
3417
3418         try {
3419             try {
3420                 final int userId = UserHandle.getUserId(app.uid);
3421                 AppGlobals.getPackageManager().checkPackageStartable(app.info.packageName, userId);
3422             } catch (RemoteException e) {
3423                 throw e.rethrowAsRuntimeException();
3424             }
3425
3426             int uid = app.uid;
3427             int[] gids = null;
3428             int mountExternal = Zygote.MOUNT_EXTERNAL_NONE;
3429             if (!app.isolated) {
3430                 int[] permGids = null;
3431                 try {
3432                     checkTime(startTime, "startProcess: getting gids from package manager");
3433                     final IPackageManager pm = AppGlobals.getPackageManager();
3434                     permGids = pm.getPackageGids(app.info.packageName, app.userId);
3435                     MountServiceInternal mountServiceInternal = LocalServices.getService(
3436                             MountServiceInternal.class);
3437                     mountExternal = mountServiceInternal.getExternalStorageMountMode(uid,
3438                             app.info.packageName);
3439                 } catch (RemoteException e) {
3440                     throw e.rethrowAsRuntimeException();
3441                 }
3442
3443                 /*
3444                  * Add shared application and profile GIDs so applications can share some
3445                  * resources like shared libraries and access user-wide resources
3446                  */
3447                 if (ArrayUtils.isEmpty(permGids)) {
3448                     gids = new int[2];
3449                 } else {
3450                     gids = new int[permGids.length + 2];
3451                     System.arraycopy(permGids, 0, gids, 2, permGids.length);
3452                 }
3453                 gids[0] = UserHandle.getSharedAppGid(UserHandle.getAppId(uid));
3454                 gids[1] = UserHandle.getUserGid(UserHandle.getUserId(uid));
3455             }
3456             checkTime(startTime, "startProcess: building args");
3457             if (mFactoryTest != FactoryTest.FACTORY_TEST_OFF) {
3458                 if (mFactoryTest == FactoryTest.FACTORY_TEST_LOW_LEVEL
3459                         && mTopComponent != null
3460                         && app.processName.equals(mTopComponent.getPackageName())) {
3461                     uid = 0;
3462                 }
3463                 if (mFactoryTest == FactoryTest.FACTORY_TEST_HIGH_LEVEL
3464                         && (app.info.flags&ApplicationInfo.FLAG_FACTORY_TEST) != 0) {
3465                     uid = 0;
3466                 }
3467             }
3468             int debugFlags = 0;
3469             if ((app.info.flags & ApplicationInfo.FLAG_DEBUGGABLE) != 0) {
3470                 debugFlags |= Zygote.DEBUG_ENABLE_DEBUGGER;
3471                 // Also turn on CheckJNI for debuggable apps. It's quite
3472                 // awkward to turn on otherwise.
3473                 debugFlags |= Zygote.DEBUG_ENABLE_CHECKJNI;
3474             }
3475             // Run the app in safe mode if its manifest requests so or the
3476             // system is booted in safe mode.
3477             if ((app.info.flags & ApplicationInfo.FLAG_VM_SAFE_MODE) != 0 ||
3478                 mSafeMode == true) {
3479                 debugFlags |= Zygote.DEBUG_ENABLE_SAFEMODE;
3480             }
3481             if ("1".equals(SystemProperties.get("debug.checkjni"))) {
3482                 debugFlags |= Zygote.DEBUG_ENABLE_CHECKJNI;
3483             }
3484             String genDebugInfoProperty = SystemProperties.get("debug.generate-debug-info");
3485             if ("true".equals(genDebugInfoProperty)) {
3486                 debugFlags |= Zygote.DEBUG_GENERATE_DEBUG_INFO;
3487             }
3488             if ("1".equals(SystemProperties.get("debug.jni.logging"))) {
3489                 debugFlags |= Zygote.DEBUG_ENABLE_JNI_LOGGING;
3490             }
3491             if ("1".equals(SystemProperties.get("debug.assert"))) {
3492                 debugFlags |= Zygote.DEBUG_ENABLE_ASSERT;
3493             }
3494
3495             String requiredAbi = (abiOverride != null) ? abiOverride : app.info.primaryCpuAbi;
3496             if (requiredAbi == null) {
3497                 requiredAbi = Build.SUPPORTED_ABIS[0];
3498             }
3499
3500             String instructionSet = null;
3501             if (app.info.primaryCpuAbi != null) {
3502                 instructionSet = VMRuntime.getInstructionSet(app.info.primaryCpuAbi);
3503             }
3504
3505             app.gids = gids;
3506             app.requiredAbi = requiredAbi;
3507             app.instructionSet = instructionSet;
3508
3509             // Start the process.  It will either succeed and return a result containing
3510             // the PID of the new process, or else throw a RuntimeException.
3511             boolean isActivityProcess = (entryPoint == null);
3512             if (entryPoint == null) entryPoint = "android.app.ActivityThread";
3513             Trace.traceBegin(Trace.TRACE_TAG_ACTIVITY_MANAGER, "Start proc: " +
3514                     app.processName);
3515             checkTime(startTime, "startProcess: asking zygote to start proc");
3516             Process.ProcessStartResult startResult = Process.start(entryPoint,
3517                     app.processName, uid, uid, gids, debugFlags, mountExternal,
3518                     app.info.targetSdkVersion, app.info.seinfo, requiredAbi, instructionSet,
3519                     app.info.dataDir, entryPointArgs);
3520             checkTime(startTime, "startProcess: returned from zygote!");
3521             Trace.traceEnd(Trace.TRACE_TAG_ACTIVITY_MANAGER);
3522
3523             if (app.isolated) {
3524                 mBatteryStatsService.addIsolatedUid(app.uid, app.info.uid);
3525             }
3526             mBatteryStatsService.noteProcessStart(app.processName, app.info.uid);
3527             checkTime(startTime, "startProcess: done updating battery stats");
3528
3529             EventLog.writeEvent(EventLogTags.AM_PROC_START,
3530                     UserHandle.getUserId(uid), startResult.pid, uid,
3531                     app.processName, hostingType,
3532                     hostingNameStr != null ? hostingNameStr : "");
3533
3534             if (app.persistent) {
3535                 Watchdog.getInstance().processStarted(app.processName, startResult.pid);
3536             }
3537
3538             checkTime(startTime, "startProcess: building log message");
3539             StringBuilder buf = mStringBuilder;
3540             buf.setLength(0);
3541             buf.append("Start proc ");
3542             buf.append(startResult.pid);
3543             buf.append(':');
3544             buf.append(app.processName);
3545             buf.append('/');
3546             UserHandle.formatUid(buf, uid);
3547             if (!isActivityProcess) {
3548                 buf.append(" [");
3549                 buf.append(entryPoint);
3550                 buf.append("]");
3551             }
3552             buf.append(" for ");
3553             buf.append(hostingType);
3554             if (hostingNameStr != null) {
3555                 buf.append(" ");
3556                 buf.append(hostingNameStr);
3557             }
3558             Slog.i(TAG, buf.toString());
3559             app.setPid(startResult.pid);
3560             app.usingWrapper = startResult.usingWrapper;
3561             app.removed = false;
3562             app.killed = false;
3563             app.killedByAm = false;
3564             checkTime(startTime, "startProcess: starting to update pids map");
3565             synchronized (mPidsSelfLocked) {
3566                 this.mPidsSelfLocked.put(startResult.pid, app);
3567                 if (isActivityProcess) {
3568                     Message msg = mHandler.obtainMessage(PROC_START_TIMEOUT_MSG);
3569                     msg.obj = app;
3570                     mHandler.sendMessageDelayed(msg, startResult.usingWrapper
3571                             ? PROC_START_TIMEOUT_WITH_WRAPPER : PROC_START_TIMEOUT);
3572                 }
3573             }
3574             checkTime(startTime, "startProcess: done updating pids map");
3575         } catch (RuntimeException e) {
3576             // XXX do better error recovery.
3577             app.setPid(0);
3578             mBatteryStatsService.noteProcessFinish(app.processName, app.info.uid);
3579             if (app.isolated) {
3580                 mBatteryStatsService.removeIsolatedUid(app.uid, app.info.uid);
3581             }
3582             Slog.e(TAG, "Failure starting process " + app.processName, e);
3583         }
3584     }
3585
3586     void updateUsageStats(ActivityRecord component, boolean resumed) {
3587         if (DEBUG_SWITCH) Slog.d(TAG_SWITCH,
3588                 "updateUsageStats: comp=" + component + "res=" + resumed);
3589         final BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
3590         if (resumed) {
3591             if (mUsageStatsService != null) {
3592                 mUsageStatsService.reportEvent(component.realActivity, component.userId,
3593                         UsageEvents.Event.MOVE_TO_FOREGROUND);
3594             }
3595             synchronized (stats) {
3596                 stats.noteActivityResumedLocked(component.app.uid);
3597             }
3598         } else {
3599             if (mUsageStatsService != null) {
3600                 mUsageStatsService.reportEvent(component.realActivity, component.userId,
3601                         UsageEvents.Event.MOVE_TO_BACKGROUND);
3602             }
3603             synchronized (stats) {
3604                 stats.noteActivityPausedLocked(component.app.uid);
3605             }
3606         }
3607     }
3608
3609     Intent getHomeIntent() {
3610         Intent intent = new Intent(mTopAction, mTopData != null ? Uri.parse(mTopData) : null);
3611         intent.setComponent(mTopComponent);
3612         if (mFactoryTest != FactoryTest.FACTORY_TEST_LOW_LEVEL) {
3613             intent.addCategory(Intent.CATEGORY_HOME);
3614         }
3615         return intent;
3616     }
3617
3618     boolean startHomeActivityLocked(int userId, String reason) {
3619         if (mFactoryTest == FactoryTest.FACTORY_TEST_LOW_LEVEL
3620                 && mTopAction == null) {
3621             // We are running in factory test mode, but unable to find
3622             // the factory test app, so just sit around displaying the
3623             // error message and don't try to start anything.
3624             return false;
3625         }
3626         Intent intent = getHomeIntent();
3627         ActivityInfo aInfo =
3628             resolveActivityInfo(intent, STOCK_PM_FLAGS, userId);
3629         if (aInfo != null) {
3630             intent.setComponent(new ComponentName(
3631                     aInfo.applicationInfo.packageName, aInfo.name));
3632             // Don't do this if the home app is currently being
3633             // instrumented.
3634             aInfo = new ActivityInfo(aInfo);
3635             aInfo.applicationInfo = getAppInfoForUser(aInfo.applicationInfo, userId);
3636             ProcessRecord app = getProcessRecordLocked(aInfo.processName,
3637                     aInfo.applicationInfo.uid, true);
3638             if (app == null || app.instrumentationClass == null) {
3639                 intent.setFlags(intent.getFlags() | Intent.FLAG_ACTIVITY_NEW_TASK);
3640                 mStackSupervisor.startHomeActivity(intent, aInfo, reason);
3641             }
3642         }
3643
3644         return true;
3645     }
3646
3647     private ActivityInfo resolveActivityInfo(Intent intent, int flags, int userId) {
3648         ActivityInfo ai = null;
3649         ComponentName comp = intent.getComponent();
3650         try {
3651             if (comp != null) {
3652                 // Factory test.
3653                 ai = AppGlobals.getPackageManager().getActivityInfo(comp, flags, userId);
3654             } else {
3655                 ResolveInfo info = AppGlobals.getPackageManager().resolveIntent(
3656                         intent,
3657                         intent.resolveTypeIfNeeded(mContext.getContentResolver()),
3658                         flags, userId);
3659
3660                 if (info != null) {
3661                     ai = info.activityInfo;
3662                 }
3663             }
3664         } catch (RemoteException e) {
3665             // ignore
3666         }
3667
3668         return ai;
3669     }
3670
3671     /**
3672      * Starts the "new version setup screen" if appropriate.
3673      */
3674     void startSetupActivityLocked() {
3675         // Only do this once per boot.
3676         if (mCheckedForSetup) {
3677             return;
3678         }
3679
3680         // We will show this screen if the current one is a different
3681         // version than the last one shown, and we are not running in
3682         // low-level factory test mode.
3683         final ContentResolver resolver = mContext.getContentResolver();
3684         if (mFactoryTest != FactoryTest.FACTORY_TEST_LOW_LEVEL &&
3685                 Settings.Global.getInt(resolver,
3686                         Settings.Global.DEVICE_PROVISIONED, 0) != 0) {
3687             mCheckedForSetup = true;
3688
3689             // See if we should be showing the platform update setup UI.
3690             Intent intent = new Intent(Intent.ACTION_UPGRADE_SETUP);
3691             List<ResolveInfo> ris = mContext.getPackageManager()
3692                     .queryIntentActivities(intent, PackageManager.GET_META_DATA);
3693
3694             // We don't allow third party apps to replace this.
3695             ResolveInfo ri = null;
3696             for (int i=0; ris != null && i<ris.size(); i++) {
3697                 if ((ris.get(i).activityInfo.applicationInfo.flags
3698                         & ApplicationInfo.FLAG_SYSTEM) != 0) {
3699                     ri = ris.get(i);
3700                     break;
3701                 }
3702             }
3703
3704             if (ri != null) {
3705                 String vers = ri.activityInfo.metaData != null
3706                         ? ri.activityInfo.metaData.getString(Intent.METADATA_SETUP_VERSION)
3707                         : null;
3708                 if (vers == null && ri.activityInfo.applicationInfo.metaData != null) {
3709                     vers = ri.activityInfo.applicationInfo.metaData.getString(
3710                             Intent.METADATA_SETUP_VERSION);
3711                 }
3712                 String lastVers = Settings.Secure.getString(
3713                         resolver, Settings.Secure.LAST_SETUP_SHOWN);
3714                 if (vers != null && !vers.equals(lastVers)) {
3715                     intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
3716                     intent.setComponent(new ComponentName(
3717                             ri.activityInfo.packageName, ri.activityInfo.name));
3718                     mStackSupervisor.startActivityLocked(null, intent, null, ri.activityInfo,
3719                             null, null, null, null, 0, 0, 0, null, 0, 0, 0, null, false, false,
3720                             null, null, null);
3721                 }
3722             }
3723         }
3724     }
3725
3726     CompatibilityInfo compatibilityInfoForPackageLocked(ApplicationInfo ai) {
3727         return mCompatModePackages.compatibilityInfoForPackageLocked(ai);
3728     }
3729
3730     void enforceNotIsolatedCaller(String caller) {
3731         if (UserHandle.isIsolated(Binder.getCallingUid())) {
3732             throw new SecurityException("Isolated process not allowed to call " + caller);
3733         }
3734     }
3735
3736     void enforceShellRestriction(String restriction, int userHandle) {
3737         if (Binder.getCallingUid() == Process.SHELL_UID) {
3738             if (userHandle < 0 || mUserController.hasUserRestriction(restriction, userHandle)) {
3739                 throw new SecurityException("Shell does not have permission to access user "
3740                         + userHandle);
3741             }
3742         }
3743     }
3744
3745     @Override
3746     public int getFrontActivityScreenCompatMode() {
3747         enforceNotIsolatedCaller("getFrontActivityScreenCompatMode");
3748         synchronized (this) {
3749             return mCompatModePackages.getFrontActivityScreenCompatModeLocked();
3750         }
3751     }
3752
3753     @Override
3754     public void setFrontActivityScreenCompatMode(int mode) {
3755         enforceCallingPermission(android.Manifest.permission.SET_SCREEN_COMPATIBILITY,
3756                 "setFrontActivityScreenCompatMode");
3757         synchronized (this) {
3758             mCompatModePackages.setFrontActivityScreenCompatModeLocked(mode);
3759         }
3760     }
3761
3762     @Override
3763     public int getPackageScreenCompatMode(String packageName) {
3764         enforceNotIsolatedCaller("getPackageScreenCompatMode");
3765         synchronized (this) {
3766             return mCompatModePackages.getPackageScreenCompatModeLocked(packageName);
3767         }
3768     }
3769
3770     @Override
3771     public void setPackageScreenCompatMode(String packageName, int mode) {
3772         enforceCallingPermission(android.Manifest.permission.SET_SCREEN_COMPATIBILITY,
3773                 "setPackageScreenCompatMode");
3774         synchronized (this) {
3775             mCompatModePackages.setPackageScreenCompatModeLocked(packageName, mode);
3776         }
3777     }
3778
3779     @Override
3780     public boolean getPackageAskScreenCompat(String packageName) {
3781         enforceNotIsolatedCaller("getPackageAskScreenCompat");
3782         synchronized (this) {
3783             return mCompatModePackages.getPackageAskCompatModeLocked(packageName);
3784         }
3785     }
3786
3787     @Override
3788     public void setPackageAskScreenCompat(String packageName, boolean ask) {
3789         enforceCallingPermission(android.Manifest.permission.SET_SCREEN_COMPATIBILITY,
3790                 "setPackageAskScreenCompat");
3791         synchronized (this) {
3792             mCompatModePackages.setPackageAskCompatModeLocked(packageName, ask);
3793         }
3794     }
3795
3796     private boolean hasUsageStatsPermission(String callingPackage) {
3797         final int mode = mAppOpsService.checkOperation(AppOpsManager.OP_GET_USAGE_STATS,
3798                 Binder.getCallingUid(), callingPackage);
3799         if (mode == AppOpsManager.MODE_DEFAULT) {
3800             return checkCallingPermission(Manifest.permission.PACKAGE_USAGE_STATS)
3801                     == PackageManager.PERMISSION_GRANTED;
3802         }
3803         return mode == AppOpsManager.MODE_ALLOWED;
3804     }
3805
3806     @Override
3807     public int getPackageProcessState(String packageName, String callingPackage) {
3808         if (!hasUsageStatsPermission(callingPackage)) {
3809             enforceCallingPermission(android.Manifest.permission.GET_PACKAGE_IMPORTANCE,
3810                     "getPackageProcessState");
3811         }
3812
3813         int procState = ActivityManager.PROCESS_STATE_NONEXISTENT;
3814         synchronized (this) {
3815             for (int i=mLruProcesses.size()-1; i>=0; i--) {
3816                 final ProcessRecord proc = mLruProcesses.get(i);
3817                 if (procState == ActivityManager.PROCESS_STATE_NONEXISTENT
3818                         || procState > proc.setProcState) {
3819                     boolean found = false;
3820                     for (int j=proc.pkgList.size()-1; j>=0 && !found; j--) {
3821                         if (proc.pkgList.keyAt(j).equals(packageName)) {
3822                             procState = proc.setProcState;
3823                             found = true;
3824                         }
3825                     }
3826                     if (proc.pkgDeps != null && !found) {
3827                         for (int j=proc.pkgDeps.size()-1; j>=0; j--) {
3828                             if (proc.pkgDeps.valueAt(j).equals(packageName)) {
3829                                 procState = proc.setProcState;
3830                                 break;
3831                             }
3832                         }
3833                     }
3834                 }
3835             }
3836         }
3837         return procState;
3838     }
3839
3840     @Override
3841     public boolean setProcessMemoryTrimLevel(String process, int userId, int level) {
3842         synchronized (this) {
3843             final ProcessRecord app = findProcessLocked(process, userId, "setProcessMemoryTrimLevel");
3844             if (app == null) {
3845                 return false;
3846             }
3847             if (app.trimMemoryLevel < level && app.thread != null &&
3848                     (level < ComponentCallbacks2.TRIM_MEMORY_UI_HIDDEN ||
3849                             app.curProcState >= ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND)) {
3850                 try {
3851                     app.thread.scheduleTrimMemory(level);
3852                     app.trimMemoryLevel = level;
3853                     return true;
3854                 } catch (RemoteException e) {
3855                     // Fallthrough to failure case.
3856                 }
3857             }
3858         }
3859         return false;
3860     }
3861
3862     private void dispatchProcessesChanged() {
3863         int N;
3864         synchronized (this) {
3865             N = mPendingProcessChanges.size();
3866             if (mActiveProcessChanges.length < N) {
3867                 mActiveProcessChanges = new ProcessChangeItem[N];
3868             }
3869             mPendingProcessChanges.toArray(mActiveProcessChanges);
3870             mPendingProcessChanges.clear();
3871             if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG_PROCESS_OBSERVERS,
3872                     "*** Delivering " + N + " process changes");
3873         }
3874
3875         int i = mProcessObservers.beginBroadcast();
3876         while (i > 0) {
3877             i--;
3878             final IProcessObserver observer = mProcessObservers.getBroadcastItem(i);
3879             if (observer != null) {
3880                 try {
3881                     for (int j=0; j<N; j++) {
3882                         ProcessChangeItem item = mActiveProcessChanges[j];
3883                         if ((item.changes&ProcessChangeItem.CHANGE_ACTIVITIES) != 0) {
3884                             if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG_PROCESS_OBSERVERS,
3885                                     "ACTIVITIES CHANGED pid=" + item.pid + " uid="
3886                                     + item.uid + ": " + item.foregroundActivities);
3887                             observer.onForegroundActivitiesChanged(item.pid, item.uid,
3888                                     item.foregroundActivities);
3889                         }
3890                         if ((item.changes&ProcessChangeItem.CHANGE_PROCESS_STATE) != 0) {
3891                             if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG_PROCESS_OBSERVERS,
3892                                     "PROCSTATE CHANGED pid=" + item.pid + " uid=" + item.uid
3893                                     + ": " + item.processState);
3894                             observer.onProcessStateChanged(item.pid, item.uid, item.processState);
3895                         }
3896                     }
3897                 } catch (RemoteException e) {
3898                 }
3899             }
3900         }
3901         mProcessObservers.finishBroadcast();
3902
3903         synchronized (this) {
3904             for (int j=0; j<N; j++) {
3905                 mAvailProcessChanges.add(mActiveProcessChanges[j]);
3906             }
3907         }
3908     }
3909
3910     private void dispatchProcessDied(int pid, int uid) {
3911         int i = mProcessObservers.beginBroadcast();
3912         while (i > 0) {
3913             i--;
3914             final IProcessObserver observer = mProcessObservers.getBroadcastItem(i);
3915             if (observer != null) {
3916                 try {
3917                     observer.onProcessDied(pid, uid);
3918                 } catch (RemoteException e) {
3919                 }
3920             }
3921         }
3922         mProcessObservers.finishBroadcast();
3923     }
3924
3925     private void dispatchUidsChanged() {
3926         int N;
3927         synchronized (this) {
3928             N = mPendingUidChanges.size();
3929             if (mActiveUidChanges.length < N) {
3930                 mActiveUidChanges = new UidRecord.ChangeItem[N];
3931             }
3932             for (int i=0; i<N; i++) {
3933                 final UidRecord.ChangeItem change = mPendingUidChanges.get(i);
3934                 mActiveUidChanges[i] = change;
3935                 if (change.uidRecord != null) {
3936                     change.uidRecord.pendingChange = null;
3937                     change.uidRecord = null;
3938                 }
3939             }
3940             mPendingUidChanges.clear();
3941             if (DEBUG_UID_OBSERVERS) Slog.i(TAG_UID_OBSERVERS,
3942                     "*** Delivering " + N + " uid changes");
3943         }
3944
3945         if (mLocalPowerManager != null) {
3946             for (int j=0; j<N; j++) {
3947                 UidRecord.ChangeItem item = mActiveUidChanges[j];
3948                 if (item.change == UidRecord.CHANGE_GONE
3949                         || item.change == UidRecord.CHANGE_GONE_IDLE) {
3950                     mLocalPowerManager.uidGone(item.uid);
3951                 } else {
3952                     mLocalPowerManager.updateUidProcState(item.uid, item.processState);
3953                 }
3954             }
3955         }
3956
3957         int i = mUidObservers.beginBroadcast();
3958         while (i > 0) {
3959             i--;
3960             final IUidObserver observer = mUidObservers.getBroadcastItem(i);
3961             final int which = (Integer)mUidObservers.getBroadcastCookie(i);
3962             if (observer != null) {
3963                 try {
3964                     for (int j=0; j<N; j++) {
3965                         UidRecord.ChangeItem item = mActiveUidChanges[j];
3966                         final int change = item.change;
3967                         UidRecord validateUid = null;
3968                         if (VALIDATE_UID_STATES && i == 0) {
3969                             validateUid = mValidateUids.get(item.uid);
3970                             if (validateUid == null && change != UidRecord.CHANGE_GONE
3971                                     && change != UidRecord.CHANGE_GONE_IDLE) {
3972                                 validateUid = new UidRecord(item.uid);
3973                                 mValidateUids.put(item.uid, validateUid);
3974                             }
3975                         }
3976                         if (change == UidRecord.CHANGE_IDLE
3977                                 || change == UidRecord.CHANGE_GONE_IDLE) {
3978                             if ((which & ActivityManager.UID_OBSERVER_IDLE) != 0) {
3979                                 if (DEBUG_UID_OBSERVERS) Slog.i(TAG_UID_OBSERVERS,
3980                                         "UID idle uid=" + item.uid);
3981                                 observer.onUidIdle(item.uid);
3982                             }
3983                             if (VALIDATE_UID_STATES && i == 0) {
3984                                 if (validateUid != null) {
3985                                     validateUid.idle = true;
3986                                 }
3987                             }
3988                         } else if (change == UidRecord.CHANGE_ACTIVE) {
3989                             if ((which & ActivityManager.UID_OBSERVER_ACTIVE) != 0) {
3990                                 if (DEBUG_UID_OBSERVERS) Slog.i(TAG_UID_OBSERVERS,
3991                                         "UID active uid=" + item.uid);
3992                                 observer.onUidActive(item.uid);
3993                             }
3994                             if (VALIDATE_UID_STATES && i == 0) {
3995                                 validateUid.idle = false;
3996                             }
3997                         }
3998                         if (change == UidRecord.CHANGE_GONE
3999                                 || change == UidRecord.CHANGE_GONE_IDLE) {
4000                             if ((which & ActivityManager.UID_OBSERVER_GONE) != 0) {
4001                                 if (DEBUG_UID_OBSERVERS) Slog.i(TAG_UID_OBSERVERS,
4002                                         "UID gone uid=" + item.uid);
4003                                 observer.onUidGone(item.uid);
4004                             }
4005                             if (VALIDATE_UID_STATES && i == 0) {
4006                                 if (validateUid != null) {
4007                                     mValidateUids.remove(item.uid);
4008                                 }
4009                             }
4010                         } else {
4011                             if ((which & ActivityManager.UID_OBSERVER_PROCSTATE) != 0) {
4012                                 if (DEBUG_UID_OBSERVERS) Slog.i(TAG_UID_OBSERVERS,
4013                                         "UID CHANGED uid=" + item.uid
4014                                                 + ": " + item.processState);
4015                                 observer.onUidStateChanged(item.uid, item.processState);
4016                             }
4017                             if (VALIDATE_UID_STATES && i == 0) {
4018                                 validateUid.curProcState = validateUid.setProcState
4019                                         = item.processState;
4020                             }
4021                         }
4022                     }
4023                 } catch (RemoteException e) {
4024                 }
4025             }
4026         }
4027         mUidObservers.finishBroadcast();
4028
4029         synchronized (this) {
4030             for (int j=0; j<N; j++) {
4031                 mAvailUidChanges.add(mActiveUidChanges[j]);
4032             }
4033         }
4034     }
4035
4036     @Override
4037     public final int startActivity(IApplicationThread caller, String callingPackage,
4038             Intent intent, String resolvedType, IBinder resultTo, String resultWho, int requestCode,
4039             int startFlags, ProfilerInfo profilerInfo, Bundle bOptions) {
4040         return startActivityAsUser(caller, callingPackage, intent, resolvedType, resultTo,
4041                 resultWho, requestCode, startFlags, profilerInfo, bOptions,
4042                 UserHandle.getCallingUserId());
4043     }
4044
4045     @Override
4046     public final int startActivityAsUser(IApplicationThread caller, String callingPackage,
4047             Intent intent, String resolvedType, IBinder resultTo, String resultWho, int requestCode,
4048             int startFlags, ProfilerInfo profilerInfo, Bundle bOptions, int userId) {
4049         enforceNotIsolatedCaller("startActivity");
4050         userId = mUserController.handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(),
4051                 userId, false, ALLOW_FULL_ONLY, "startActivity", null);
4052         // TODO: Switch to user app stacks here.
4053         return mStackSupervisor.startActivityMayWait(caller, -1, callingPackage, intent,
4054                 resolvedType, null, null, resultTo, resultWho, requestCode, startFlags,
4055                 profilerInfo, null, null, bOptions, false, userId, null, null);
4056     }
4057
4058     @Override
4059     public final int startActivityAsCaller(IApplicationThread caller, String callingPackage,
4060             Intent intent, String resolvedType, IBinder resultTo, String resultWho, int requestCode,
4061             int startFlags, ProfilerInfo profilerInfo, Bundle bOptions, boolean ignoreTargetSecurity,
4062             int userId) {
4063
4064         // This is very dangerous -- it allows you to perform a start activity (including
4065         // permission grants) as any app that may launch one of your own activities.  So
4066         // we will only allow this to be done from activities that are part of the core framework,
4067         // and then only when they are running as the system.
4068         final ActivityRecord sourceRecord;
4069         final int targetUid;
4070         final String targetPackage;
4071         synchronized (this) {
4072             if (resultTo == null) {
4073                 throw new SecurityException("Must be called from an activity");
4074             }
4075             sourceRecord = mStackSupervisor.isInAnyStackLocked(resultTo);
4076             if (sourceRecord == null) {
4077                 throw new SecurityException("Called with bad activity token: " + resultTo);
4078             }
4079             if (!sourceRecord.info.packageName.equals("android")) {
4080                 throw new SecurityException(
4081                         "Must be called from an activity that is declared in the android package");
4082             }
4083             if (sourceRecord.app == null) {
4084                 throw new SecurityException("Called without a process attached to activity");
4085             }
4086             if (UserHandle.getAppId(sourceRecord.app.uid) != Process.SYSTEM_UID) {
4087                 // This is still okay, as long as this activity is running under the
4088                 // uid of the original calling activity.
4089                 if (sourceRecord.app.uid != sourceRecord.launchedFromUid) {
4090                     throw new SecurityException(
4091                             "Calling activity in uid " + sourceRecord.app.uid
4092                                     + " must be system uid or original calling uid "
4093                                     + sourceRecord.launchedFromUid);
4094                 }
4095             }
4096             if (ignoreTargetSecurity) {
4097                 if (intent.getComponent() == null) {
4098                     throw new SecurityException(
4099                             "Component must be specified with ignoreTargetSecurity");
4100                 }
4101                 if (intent.getSelector() != null) {
4102                     throw new SecurityException(
4103                             "Selector not allowed with ignoreTargetSecurity");
4104                 }
4105             }
4106             targetUid = sourceRecord.launchedFromUid;
4107             targetPackage = sourceRecord.launchedFromPackage;
4108         }
4109
4110         if (userId == UserHandle.USER_NULL) {
4111             userId = UserHandle.getUserId(sourceRecord.app.uid);
4112         }
4113
4114         // TODO: Switch to user app stacks here.
4115         try {
4116             int ret = mStackSupervisor.startActivityMayWait(null, targetUid, targetPackage, intent,
4117                     resolvedType, null, null, resultTo, resultWho, requestCode, startFlags, null,
4118                     null, null, bOptions, ignoreTargetSecurity, userId, null, null);
4119             return ret;
4120         } catch (SecurityException e) {
4121             // XXX need to figure out how to propagate to original app.
4122             // A SecurityException here is generally actually a fault of the original
4123             // calling activity (such as a fairly granting permissions), so propagate it
4124             // back to them.
4125             /*
4126             StringBuilder msg = new StringBuilder();
4127             msg.append("While launching");
4128             msg.append(intent.toString());
4129             msg.append(": ");
4130             msg.append(e.getMessage());
4131             */
4132             throw e;
4133         }
4134     }
4135
4136     @Override
4137     public final WaitResult startActivityAndWait(IApplicationThread caller, String callingPackage,
4138             Intent intent, String resolvedType, IBinder resultTo, String resultWho, int requestCode,
4139             int startFlags, ProfilerInfo profilerInfo, Bundle bOptions, int userId) {
4140         enforceNotIsolatedCaller("startActivityAndWait");
4141         userId = mUserController.handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(),
4142                 userId, false, ALLOW_FULL_ONLY, "startActivityAndWait", null);
4143         WaitResult res = new WaitResult();
4144         // TODO: Switch to user app stacks here.
4145         mStackSupervisor.startActivityMayWait(caller, -1, callingPackage, intent, resolvedType,
4146                 null, null, resultTo, resultWho, requestCode, startFlags, profilerInfo, res, null,
4147                 bOptions, false, userId, null, null);
4148         return res;
4149     }
4150
4151     @Override
4152     public final int startActivityWithConfig(IApplicationThread caller, String callingPackage,
4153             Intent intent, String resolvedType, IBinder resultTo, String resultWho, int requestCode,
4154             int startFlags, Configuration config, Bundle bOptions, int userId) {
4155         enforceNotIsolatedCaller("startActivityWithConfig");
4156         userId = mUserController.handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(),
4157                 userId, false, ALLOW_FULL_ONLY, "startActivityWithConfig", null);
4158         // TODO: Switch to user app stacks here.
4159         int ret = mStackSupervisor.startActivityMayWait(caller, -1, callingPackage, intent,
4160                 resolvedType, null, null, resultTo, resultWho, requestCode, startFlags,
4161                 null, null, config, bOptions, false, userId, null, null);
4162         return ret;
4163     }
4164
4165     @Override
4166     public int startActivityIntentSender(IApplicationThread caller, IntentSender intent,
4167             Intent fillInIntent, String resolvedType, IBinder resultTo, String resultWho,
4168             int requestCode, int flagsMask, int flagsValues, Bundle bOptions)
4169             throws TransactionTooLargeException {
4170         enforceNotIsolatedCaller("startActivityIntentSender");
4171         // Refuse possible leaked file descriptors
4172         if (fillInIntent != null && fillInIntent.hasFileDescriptors()) {
4173             throw new IllegalArgumentException("File descriptors passed in Intent");
4174         }
4175
4176         IIntentSender sender = intent.getTarget();
4177         if (!(sender instanceof PendingIntentRecord)) {
4178             throw new IllegalArgumentException("Bad PendingIntent object");
4179         }
4180
4181         PendingIntentRecord pir = (PendingIntentRecord)sender;
4182
4183         synchronized (this) {
4184             // If this is coming from the currently resumed activity, it is
4185             // effectively saying that app switches are allowed at this point.
4186             final ActivityStack stack = getFocusedStack();
4187             if (stack.mResumedActivity != null &&
4188                     stack.mResumedActivity.info.applicationInfo.uid == Binder.getCallingUid()) {
4189                 mAppSwitchesAllowedTime = 0;
4190             }
4191         }
4192         int ret = pir.sendInner(0, fillInIntent, resolvedType, null, null,
4193                 resultTo, resultWho, requestCode, flagsMask, flagsValues, bOptions, null);
4194         return ret;
4195     }
4196
4197     @Override
4198     public int startVoiceActivity(String callingPackage, int callingPid, int callingUid,
4199             Intent intent, String resolvedType, IVoiceInteractionSession session,
4200             IVoiceInteractor interactor, int startFlags, ProfilerInfo profilerInfo,
4201             Bundle bOptions, int userId) {
4202         if (checkCallingPermission(Manifest.permission.BIND_VOICE_INTERACTION)
4203                 != PackageManager.PERMISSION_GRANTED) {
4204             String msg = "Permission Denial: startVoiceActivity() from pid="
4205                     + Binder.getCallingPid()
4206                     + ", uid=" + Binder.getCallingUid()
4207                     + " requires " + android.Manifest.permission.BIND_VOICE_INTERACTION;
4208             Slog.w(TAG, msg);
4209             throw new SecurityException(msg);
4210         }
4211         if (session == null || interactor == null) {
4212             throw new NullPointerException("null session or interactor");
4213         }
4214         userId = mUserController.handleIncomingUser(callingPid, callingUid, userId, false,
4215                 ALLOW_FULL_ONLY, "startVoiceActivity", null);
4216         // TODO: Switch to user app stacks here.
4217         return mStackSupervisor.startActivityMayWait(null, callingUid, callingPackage, intent,
4218                 resolvedType, session, interactor, null, null, 0, startFlags, profilerInfo, null,
4219                 null, bOptions, false, userId, null, null);
4220     }
4221
4222     @Override
4223     public void setVoiceKeepAwake(IVoiceInteractionSession session, boolean keepAwake) {
4224         synchronized (this) {
4225             if (mRunningVoice != null && mRunningVoice.asBinder() == session.asBinder()) {
4226                 if (keepAwake) {
4227                     mVoiceWakeLock.acquire();
4228                 } else {
4229                     mVoiceWakeLock.release();
4230                 }
4231             }
4232         }
4233     }
4234
4235     @Override
4236     public boolean startNextMatchingActivity(IBinder callingActivity,
4237             Intent intent, Bundle bOptions) {
4238         // Refuse possible leaked file descriptors
4239         if (intent != null && intent.hasFileDescriptors() == true) {
4240             throw new IllegalArgumentException("File descriptors passed in Intent");
4241         }
4242         ActivityOptions options = ActivityOptions.fromBundle(bOptions);
4243
4244         synchronized (this) {
4245             final ActivityRecord r = ActivityRecord.isInStackLocked(callingActivity);
4246             if (r == null) {
4247                 ActivityOptions.abort(options);
4248                 return false;
4249             }
4250             if (r.app == null || r.app.thread == null) {
4251                 // The caller is not running...  d'oh!
4252                 ActivityOptions.abort(options);
4253                 return false;
4254             }
4255             intent = new Intent(intent);
4256             // The caller is not allowed to change the data.
4257             intent.setDataAndType(r.intent.getData(), r.intent.getType());
4258             // And we are resetting to find the next component...
4259             intent.setComponent(null);
4260
4261             final boolean debug = ((intent.getFlags() & Intent.FLAG_DEBUG_LOG_RESOLUTION) != 0);
4262
4263             ActivityInfo aInfo = null;
4264             try {
4265                 List<ResolveInfo> resolves =
4266                     AppGlobals.getPackageManager().queryIntentActivities(
4267                             intent, r.resolvedType,
4268                             PackageManager.MATCH_DEFAULT_ONLY | STOCK_PM_FLAGS,
4269                             UserHandle.getCallingUserId());
4270
4271                 // Look for the original activity in the list...
4272                 final int N = resolves != null ? resolves.size() : 0;
4273                 for (int i=0; i<N; i++) {
4274                     ResolveInfo rInfo = resolves.get(i);
4275                     if (rInfo.activityInfo.packageName.equals(r.packageName)
4276                             && rInfo.activityInfo.name.equals(r.info.name)) {
4277                         // We found the current one...  the next matching is
4278                         // after it.
4279                         i++;
4280                         if (i<N) {
4281                             aInfo = resolves.get(i).activityInfo;
4282                         }
4283                         if (debug) {
4284                             Slog.v(TAG, "Next matching activity: found current " + r.packageName
4285                                     + "/" + r.info.name);
4286                             Slog.v(TAG, "Next matching activity: next is " + ((aInfo == null)
4287                                     ? "null" : aInfo.packageName + "/" + aInfo.name));
4288                         }
4289                         break;
4290                     }
4291                 }
4292             } catch (RemoteException e) {
4293             }
4294
4295             if (aInfo == null) {
4296                 // Nobody who is next!
4297                 ActivityOptions.abort(options);
4298                 if (debug) Slog.d(TAG, "Next matching activity: nothing found");
4299                 return false;
4300             }
4301
4302             intent.setComponent(new ComponentName(
4303                     aInfo.applicationInfo.packageName, aInfo.name));
4304             intent.setFlags(intent.getFlags()&~(
4305                     Intent.FLAG_ACTIVITY_FORWARD_RESULT|
4306                     Intent.FLAG_ACTIVITY_CLEAR_TOP|
4307                     Intent.FLAG_ACTIVITY_MULTIPLE_TASK|
4308                     Intent.FLAG_ACTIVITY_NEW_TASK));
4309
4310             // Okay now we need to start the new activity, replacing the
4311             // currently running activity.  This is a little tricky because
4312             // we want to start the new one as if the current one is finished,
4313             // but not finish the current one first so that there is no flicker.
4314             // And thus...
4315             final boolean wasFinishing = r.finishing;
4316             r.finishing = true;
4317
4318             // Propagate reply information over to the new activity.
4319             final ActivityRecord resultTo = r.resultTo;
4320             final String resultWho = r.resultWho;
4321             final int requestCode = r.requestCode;
4322             r.resultTo = null;
4323             if (resultTo != null) {
4324                 resultTo.removeResultsLocked(r, resultWho, requestCode);
4325             }
4326
4327             final long origId = Binder.clearCallingIdentity();
4328             int res = mStackSupervisor.startActivityLocked(r.app.thread, intent,
4329                     r.resolvedType, aInfo, null, null, resultTo != null ? resultTo.appToken : null,
4330                     resultWho, requestCode, -1, r.launchedFromUid, r.launchedFromPackage,
4331                     -1, r.launchedFromUid, 0, options, false, false, null, null, null);
4332             Binder.restoreCallingIdentity(origId);
4333
4334             r.finishing = wasFinishing;
4335             if (res != ActivityManager.START_SUCCESS) {
4336                 return false;
4337             }
4338             return true;
4339         }
4340     }
4341
4342     @Override
4343     public final int startActivityFromRecents(int taskId, int launchStackId, Bundle bOptions) {
4344         if (checkCallingPermission(START_TASKS_FROM_RECENTS) != PackageManager.PERMISSION_GRANTED) {
4345             String msg = "Permission Denial: startActivityFromRecents called without " +
4346                     START_TASKS_FROM_RECENTS;
4347             Slog.w(TAG, msg);
4348             throw new SecurityException(msg);
4349         }
4350         final long origId = Binder.clearCallingIdentity();
4351         try {
4352             return startActivityFromRecentsInner(taskId, launchStackId, bOptions);
4353         } finally {
4354             Binder.restoreCallingIdentity(origId);
4355         }
4356     }
4357
4358     final int startActivityFromRecentsInner(int taskId, int launchStackId, Bundle bOptions) {
4359         final TaskRecord task;
4360         final int callingUid;
4361         final String callingPackage;
4362         final Intent intent;
4363         final int userId;
4364         synchronized (this) {
4365             if (launchStackId == HOME_STACK_ID) {
4366                 throw new IllegalArgumentException("startActivityFromRecentsInner: Task "
4367                         + taskId + " can't be launch in the home stack.");
4368             }
4369
4370             task = mStackSupervisor.anyTaskForIdLocked(taskId, RESTORE_FROM_RECENTS, launchStackId);
4371             if (task == null) {
4372                 throw new IllegalArgumentException(
4373                         "startActivityFromRecentsInner: Task " + taskId + " not found.");
4374             }
4375
4376             if (launchStackId != INVALID_STACK_ID) {
4377                 if (launchStackId == DOCKED_STACK_ID && bOptions != null) {
4378                     ActivityOptions activityOptions = new ActivityOptions(bOptions);
4379                     mWindowManager.setDockedStackCreateState(activityOptions.getDockCreateMode(),
4380                             null /* initialBounds */);
4381                 }
4382                 if (task.stack.mStackId != launchStackId) {
4383                     mStackSupervisor.moveTaskToStackLocked(
4384                             taskId, launchStackId, ON_TOP, FORCE_FOCUS, "startActivityFromRecents",
4385                             true /* animate */);
4386                 }
4387             }
4388
4389             if (task.getRootActivity() != null) {
4390                 moveTaskToFrontLocked(task.taskId, 0, bOptions);
4391                 return ActivityManager.START_TASK_TO_FRONT;
4392             }
4393             callingUid = task.mCallingUid;
4394             callingPackage = task.mCallingPackage;
4395             intent = task.intent;
4396             intent.addFlags(Intent.FLAG_ACTIVITY_LAUNCHED_FROM_HISTORY);
4397             userId = task.userId;
4398         }
4399         return startActivityInPackage(callingUid, callingPackage, intent, null, null, null, 0, 0,
4400                 bOptions, userId, null, task);
4401     }
4402
4403     final int startActivityInPackage(int uid, String callingPackage,
4404             Intent intent, String resolvedType, IBinder resultTo,
4405             String resultWho, int requestCode, int startFlags, Bundle bOptions, int userId,
4406             IActivityContainer container, TaskRecord inTask) {
4407
4408         userId = mUserController.handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(),
4409                 userId, false, ALLOW_FULL_ONLY, "startActivityInPackage", null);
4410
4411         // TODO: Switch to user app stacks here.
4412         int ret = mStackSupervisor.startActivityMayWait(null, uid, callingPackage, intent,
4413                 resolvedType, null, null, resultTo, resultWho, requestCode, startFlags,
4414                 null, null, null, bOptions, false, userId, container, inTask);
4415         return ret;
4416     }
4417
4418     @Override
4419     public final int startActivities(IApplicationThread caller, String callingPackage,
4420             Intent[] intents, String[] resolvedTypes, IBinder resultTo, Bundle bOptions,
4421             int userId) {
4422         enforceNotIsolatedCaller("startActivities");
4423         userId = mUserController.handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(),
4424                 userId, false, ALLOW_FULL_ONLY, "startActivity", null);
4425         // TODO: Switch to user app stacks here.
4426         int ret = mStackSupervisor.startActivities(caller, -1, callingPackage, intents,
4427                 resolvedTypes, resultTo, bOptions, userId);
4428         return ret;
4429     }
4430
4431     final int startActivitiesInPackage(int uid, String callingPackage,
4432             Intent[] intents, String[] resolvedTypes, IBinder resultTo,
4433             Bundle bOptions, int userId) {
4434
4435         userId = mUserController.handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(),
4436                 userId, false, ALLOW_FULL_ONLY, "startActivityInPackage", null);
4437         // TODO: Switch to user app stacks here.
4438         int ret = mStackSupervisor.startActivities(null, uid, callingPackage, intents, resolvedTypes,
4439                 resultTo, bOptions, userId);
4440         return ret;
4441     }
4442
4443     @Override
4444     public void reportActivityFullyDrawn(IBinder token) {
4445         synchronized (this) {
4446             ActivityRecord r = ActivityRecord.isInStackLocked(token);
4447             if (r == null) {
4448                 return;
4449             }
4450             r.reportFullyDrawnLocked();
4451         }
4452     }
4453
4454     @Override
4455     public void setRequestedOrientation(IBinder token, int requestedOrientation) {
4456         synchronized (this) {
4457             ActivityRecord r = ActivityRecord.isInStackLocked(token);
4458             if (r == null) {
4459                 return;
4460             }
4461             TaskRecord task = r.task;
4462             if (task != null && (!task.mFullscreen || !task.stack.mFullscreen)) {
4463                 // Fixed screen orientation isn't supported when activities aren't in full screen
4464                 // mode.
4465                 return;
4466             }
4467             final long origId = Binder.clearCallingIdentity();
4468             mWindowManager.setAppOrientation(r.appToken, requestedOrientation);
4469             Configuration config = mWindowManager.updateOrientationFromAppTokens(
4470                     mConfiguration, r.mayFreezeScreenLocked(r.app) ? r.appToken : null);
4471             if (config != null) {
4472                 r.frozenBeforeDestroy = true;
4473                 if (!updateConfigurationLocked(config, r, false)) {
4474                     mStackSupervisor.resumeTopActivitiesLocked();
4475                 }
4476             }
4477             Binder.restoreCallingIdentity(origId);
4478         }
4479     }
4480
4481     @Override
4482     public int getRequestedOrientation(IBinder token) {
4483         synchronized (this) {
4484             ActivityRecord r = ActivityRecord.isInStackLocked(token);
4485             if (r == null) {
4486                 return ActivityInfo.SCREEN_ORIENTATION_UNSPECIFIED;
4487             }
4488             return mWindowManager.getAppOrientation(r.appToken);
4489         }
4490     }
4491
4492     /**
4493      * This is the internal entry point for handling Activity.finish().
4494      *
4495      * @param token The Binder token referencing the Activity we want to finish.
4496      * @param resultCode Result code, if any, from this Activity.
4497      * @param resultData Result data (Intent), if any, from this Activity.
4498      * @param finishTask Whether to finish the task associated with this Activity.
4499      *
4500      * @return Returns true if the activity successfully finished, or false if it is still running.
4501      */
4502     @Override
4503     public final boolean finishActivity(IBinder token, int resultCode, Intent resultData,
4504             int finishTask) {
4505         // Refuse possible leaked file descriptors
4506         if (resultData != null && resultData.hasFileDescriptors() == true) {
4507             throw new IllegalArgumentException("File descriptors passed in Intent");
4508         }
4509
4510         synchronized(this) {
4511             ActivityRecord r = ActivityRecord.isInStackLocked(token);
4512             if (r == null) {
4513                 return true;
4514             }
4515             // Keep track of the root activity of the task before we finish it
4516             TaskRecord tr = r.task;
4517             ActivityRecord rootR = tr.getRootActivity();
4518             if (rootR == null) {
4519                 Slog.w(TAG, "Finishing task with all activities already finished");
4520             }
4521             // Do not allow task to finish if last task in lockTask mode. Launchable priv-apps can
4522             // finish.
4523             if (tr.mLockTaskAuth != LOCK_TASK_AUTH_LAUNCHABLE_PRIV && rootR == r &&
4524                     mStackSupervisor.isLastLockedTask(tr)) {
4525                 Slog.i(TAG, "Not finishing task in lock task mode");
4526                 mStackSupervisor.showLockTaskToast();
4527                 return false;
4528             }
4529             if (mController != null) {
4530                 // Find the first activity that is not finishing.
4531                 ActivityRecord next = r.task.stack.topRunningActivityLocked(token, 0);
4532                 if (next != null) {
4533                     // ask watcher if this is allowed
4534                     boolean resumeOK = true;
4535                     try {
4536                         resumeOK = mController.activityResuming(next.packageName);
4537                     } catch (RemoteException e) {
4538                         mController = null;
4539                         Watchdog.getInstance().setActivityController(null);
4540                     }
4541
4542                     if (!resumeOK) {
4543                         Slog.i(TAG, "Not finishing activity because controller resumed");
4544                         return false;
4545                     }
4546                 }
4547             }
4548             final long origId = Binder.clearCallingIdentity();
4549             try {
4550                 boolean res;
4551                 final boolean finishWithRootActivity =
4552                         finishTask == Activity.FINISH_TASK_WITH_ROOT_ACTIVITY;
4553                 if (finishTask == Activity.FINISH_TASK_WITH_ACTIVITY
4554                         || (finishWithRootActivity && r == rootR)) {
4555                     // If requested, remove the task that is associated to this activity only if it
4556                     // was the root activity in the task. The result code and data is ignored
4557                     // because we don't support returning them across task boundaries. Also, to
4558                     // keep backwards compatibility we remove the task from recents when finishing
4559                     // task with root activity.
4560                     res = removeTaskByIdLocked(tr.taskId, false, finishWithRootActivity);
4561                     if (!res) {
4562                         Slog.i(TAG, "Removing task failed to finish activity");
4563                     }
4564                 } else {
4565                     res = tr.stack.requestFinishActivityLocked(token, resultCode,
4566                             resultData, "app-request", true);
4567                     if (!res) {
4568                         Slog.i(TAG, "Failed to finish by app-request");
4569                     }
4570                 }
4571                 return res;
4572             } finally {
4573                 Binder.restoreCallingIdentity(origId);
4574             }
4575         }
4576     }
4577
4578     @Override
4579     public final void finishHeavyWeightApp() {
4580         if (checkCallingPermission(android.Manifest.permission.FORCE_STOP_PACKAGES)
4581                 != PackageManager.PERMISSION_GRANTED) {
4582             String msg = "Permission Denial: finishHeavyWeightApp() from pid="
4583                     + Binder.getCallingPid()
4584                     + ", uid=" + Binder.getCallingUid()
4585                     + " requires " + android.Manifest.permission.FORCE_STOP_PACKAGES;
4586             Slog.w(TAG, msg);
4587             throw new SecurityException(msg);
4588         }
4589
4590         synchronized(this) {
4591             if (mHeavyWeightProcess == null) {
4592                 return;
4593             }
4594
4595             ArrayList<ActivityRecord> activities = new ArrayList<>(mHeavyWeightProcess.activities);
4596             for (int i = 0; i < activities.size(); i++) {
4597                 ActivityRecord r = activities.get(i);
4598                 if (!r.finishing && r.isInStackLocked()) {
4599                     r.task.stack.finishActivityLocked(r, Activity.RESULT_CANCELED,
4600                             null, "finish-heavy", true);
4601                 }
4602             }
4603
4604             mHandler.sendMessage(mHandler.obtainMessage(CANCEL_HEAVY_NOTIFICATION_MSG,
4605                     mHeavyWeightProcess.userId, 0));
4606             mHeavyWeightProcess = null;
4607         }
4608     }
4609
4610     @Override
4611     public void crashApplication(int uid, int initialPid, String packageName,
4612             String message) {
4613         if (checkCallingPermission(android.Manifest.permission.FORCE_STOP_PACKAGES)
4614                 != PackageManager.PERMISSION_GRANTED) {
4615             String msg = "Permission Denial: crashApplication() from pid="
4616                     + Binder.getCallingPid()
4617                     + ", uid=" + Binder.getCallingUid()
4618                     + " requires " + android.Manifest.permission.FORCE_STOP_PACKAGES;
4619             Slog.w(TAG, msg);
4620             throw new SecurityException(msg);
4621         }
4622
4623         synchronized(this) {
4624             ProcessRecord proc = null;
4625
4626             // Figure out which process to kill.  We don't trust that initialPid
4627             // still has any relation to current pids, so must scan through the
4628             // list.
4629             synchronized (mPidsSelfLocked) {
4630                 for (int i=0; i<mPidsSelfLocked.size(); i++) {
4631                     ProcessRecord p = mPidsSelfLocked.valueAt(i);
4632                     if (p.uid != uid) {
4633                         continue;
4634                     }
4635                     if (p.pid == initialPid) {
4636                         proc = p;
4637                         break;
4638                     }
4639                     if (p.pkgList.containsKey(packageName)) {
4640                         proc = p;
4641                     }
4642                 }
4643             }
4644
4645             if (proc == null) {
4646                 Slog.w(TAG, "crashApplication: nothing for uid=" + uid
4647                         + " initialPid=" + initialPid
4648                         + " packageName=" + packageName);
4649                 return;
4650             }
4651
4652             if (proc.thread != null) {
4653                 if (proc.pid == Process.myPid()) {
4654                     Log.w(TAG, "crashApplication: trying to crash self!");
4655                     return;
4656                 }
4657                 long ident = Binder.clearCallingIdentity();
4658                 try {
4659                     proc.thread.scheduleCrash(message);
4660                 } catch (RemoteException e) {
4661                 }
4662                 Binder.restoreCallingIdentity(ident);
4663             }
4664         }
4665     }
4666
4667     @Override
4668     public final void finishSubActivity(IBinder token, String resultWho,
4669             int requestCode) {
4670         synchronized(this) {
4671             final long origId = Binder.clearCallingIdentity();
4672             ActivityRecord r = ActivityRecord.isInStackLocked(token);
4673             if (r != null) {
4674                 r.task.stack.finishSubActivityLocked(r, resultWho, requestCode);
4675             }
4676             Binder.restoreCallingIdentity(origId);
4677         }
4678     }
4679
4680     @Override
4681     public boolean finishActivityAffinity(IBinder token) {
4682         synchronized(this) {
4683             final long origId = Binder.clearCallingIdentity();
4684             try {
4685                 ActivityRecord r = ActivityRecord.isInStackLocked(token);
4686                 if (r == null) {
4687                     return false;
4688                 }
4689
4690                 // Do not allow task to finish if last task in lockTask mode. Launchable priv-apps
4691                 // can finish.
4692                 final TaskRecord task = r.task;
4693                 if (task.mLockTaskAuth != LOCK_TASK_AUTH_LAUNCHABLE_PRIV &&
4694                         mStackSupervisor.isLastLockedTask(task) && task.getRootActivity() == r) {
4695                     mStackSupervisor.showLockTaskToast();
4696                     return false;
4697                 }
4698                 return task.stack.finishActivityAffinityLocked(r);
4699             } finally {
4700                 Binder.restoreCallingIdentity(origId);
4701             }
4702         }
4703     }
4704
4705     @Override
4706     public void finishVoiceTask(IVoiceInteractionSession session) {
4707         synchronized(this) {
4708             final long origId = Binder.clearCallingIdentity();
4709             try {
4710                 mStackSupervisor.finishVoiceTask(session);
4711             } finally {
4712                 Binder.restoreCallingIdentity(origId);
4713             }
4714         }
4715
4716     }
4717
4718     @Override
4719     public boolean releaseActivityInstance(IBinder token) {
4720         synchronized(this) {
4721             final long origId = Binder.clearCallingIdentity();
4722             try {
4723                 ActivityRecord r = ActivityRecord.isInStackLocked(token);
4724                 if (r == null) {
4725                     return false;
4726                 }
4727                 return r.task.stack.safelyDestroyActivityLocked(r, "app-req");
4728             } finally {
4729                 Binder.restoreCallingIdentity(origId);
4730             }
4731         }
4732     }
4733
4734     @Override
4735     public void releaseSomeActivities(IApplicationThread appInt) {
4736         synchronized(this) {
4737             final long origId = Binder.clearCallingIdentity();
4738             try {
4739                 ProcessRecord app = getRecordForAppLocked(appInt);
4740                 mStackSupervisor.releaseSomeActivitiesLocked(app, "low-mem");
4741             } finally {
4742                 Binder.restoreCallingIdentity(origId);
4743             }
4744         }
4745     }
4746
4747     @Override
4748     public boolean willActivityBeVisible(IBinder token) {
4749         synchronized(this) {
4750             ActivityStack stack = ActivityRecord.getStackLocked(token);
4751             if (stack != null) {
4752                 return stack.willActivityBeVisibleLocked(token);
4753             }
4754             return false;
4755         }
4756     }
4757
4758     @Override
4759     public void overridePendingTransition(IBinder token, String packageName,
4760             int enterAnim, int exitAnim) {
4761         synchronized(this) {
4762             ActivityRecord self = ActivityRecord.isInStackLocked(token);
4763             if (self == null) {
4764                 return;
4765             }
4766
4767             final long origId = Binder.clearCallingIdentity();
4768
4769             if (self.state == ActivityState.RESUMED
4770                     || self.state == ActivityState.PAUSING) {
4771                 mWindowManager.overridePendingAppTransition(packageName,
4772                         enterAnim, exitAnim, null);
4773             }
4774
4775             Binder.restoreCallingIdentity(origId);
4776         }
4777     }
4778
4779     /**
4780      * Main function for removing an existing process from the activity manager
4781      * as a result of that process going away.  Clears out all connections
4782      * to the process.
4783      */
4784     private final void handleAppDiedLocked(ProcessRecord app,
4785             boolean restarting, boolean allowRestart) {
4786         int pid = app.pid;
4787         boolean kept = cleanUpApplicationRecordLocked(app, restarting, allowRestart, -1);
4788         if (!kept && !restarting) {
4789             removeLruProcessLocked(app);
4790             if (pid > 0) {
4791                 ProcessList.remove(pid);
4792             }
4793         }
4794
4795         if (mProfileProc == app) {
4796             clearProfilerLocked();
4797         }
4798
4799         // Remove this application's activities from active lists.
4800         boolean hasVisibleActivities = mStackSupervisor.handleAppDiedLocked(app);
4801
4802         app.activities.clear();
4803
4804         if (app.instrumentationClass != null) {
4805             Slog.w(TAG, "Crash of app " + app.processName
4806                   + " running instrumentation " + app.instrumentationClass);
4807             Bundle info = new Bundle();
4808             info.putString("shortMsg", "Process crashed.");
4809             finishInstrumentationLocked(app, Activity.RESULT_CANCELED, info);
4810         }
4811
4812         if (!restarting && hasVisibleActivities && !mStackSupervisor.resumeTopActivitiesLocked()) {
4813             // If there was nothing to resume, and we are not already
4814             // restarting this process, but there is a visible activity that
4815             // is hosted by the process...  then make sure all visible
4816             // activities are running, taking care of restarting this
4817             // process.
4818             mStackSupervisor.ensureActivitiesVisibleLocked(null, 0, !PRESERVE_WINDOWS);
4819         }
4820     }
4821
4822     private final int getLRURecordIndexForAppLocked(IApplicationThread thread) {
4823         IBinder threadBinder = thread.asBinder();
4824         // Find the application record.
4825         for (int i=mLruProcesses.size()-1; i>=0; i--) {
4826             ProcessRecord rec = mLruProcesses.get(i);
4827             if (rec.thread != null && rec.thread.asBinder() == threadBinder) {
4828                 return i;
4829             }
4830         }
4831         return -1;
4832     }
4833
4834     final ProcessRecord getRecordForAppLocked(
4835             IApplicationThread thread) {
4836         if (thread == null) {
4837             return null;
4838         }
4839
4840         int appIndex = getLRURecordIndexForAppLocked(thread);
4841         return appIndex >= 0 ? mLruProcesses.get(appIndex) : null;
4842     }
4843
4844     final void doLowMemReportIfNeededLocked(ProcessRecord dyingProc) {
4845         // If there are no longer any background processes running,
4846         // and the app that died was not running instrumentation,
4847         // then tell everyone we are now low on memory.
4848         boolean haveBg = false;
4849         for (int i=mLruProcesses.size()-1; i>=0; i--) {
4850             ProcessRecord rec = mLruProcesses.get(i);
4851             if (rec.thread != null
4852                     && rec.setProcState >= ActivityManager.PROCESS_STATE_CACHED_ACTIVITY) {
4853                 haveBg = true;
4854                 break;
4855             }
4856         }
4857
4858         if (!haveBg) {
4859             boolean doReport = "1".equals(SystemProperties.get(SYSTEM_DEBUGGABLE, "0"));
4860             if (doReport) {
4861                 long now = SystemClock.uptimeMillis();
4862                 if (now < (mLastMemUsageReportTime+5*60*1000)) {
4863                     doReport = false;
4864                 } else {
4865                     mLastMemUsageReportTime = now;
4866                 }
4867             }
4868             final ArrayList<ProcessMemInfo> memInfos
4869                     = doReport ? new ArrayList<ProcessMemInfo>(mLruProcesses.size()) : null;
4870             EventLog.writeEvent(EventLogTags.AM_LOW_MEMORY, mLruProcesses.size());
4871             long now = SystemClock.uptimeMillis();
4872             for (int i=mLruProcesses.size()-1; i>=0; i--) {
4873                 ProcessRecord rec = mLruProcesses.get(i);
4874                 if (rec == dyingProc || rec.thread == null) {
4875                     continue;
4876                 }
4877                 if (doReport) {
4878                     memInfos.add(new ProcessMemInfo(rec.processName, rec.pid, rec.setAdj,
4879                             rec.setProcState, rec.adjType, rec.makeAdjReason()));
4880                 }
4881                 if ((rec.lastLowMemory+GC_MIN_INTERVAL) <= now) {
4882                     // The low memory report is overriding any current
4883                     // state for a GC request.  Make sure to do
4884                     // heavy/important/visible/foreground processes first.
4885                     if (rec.setAdj <= ProcessList.HEAVY_WEIGHT_APP_ADJ) {
4886                         rec.lastRequestedGc = 0;
4887                     } else {
4888                         rec.lastRequestedGc = rec.lastLowMemory;
4889                     }
4890                     rec.reportLowMemory = true;
4891                     rec.lastLowMemory = now;
4892                     mProcessesToGc.remove(rec);
4893                     addProcessToGcListLocked(rec);
4894                 }
4895             }
4896             if (doReport) {
4897                 Message msg = mHandler.obtainMessage(REPORT_MEM_USAGE_MSG, memInfos);
4898                 mHandler.sendMessage(msg);
4899             }
4900             scheduleAppGcsLocked();
4901         }
4902     }
4903
4904     final void appDiedLocked(ProcessRecord app) {
4905        appDiedLocked(app, app.pid, app.thread, false);
4906     }
4907
4908     final void appDiedLocked(ProcessRecord app, int pid, IApplicationThread thread,
4909             boolean fromBinderDied) {
4910         // First check if this ProcessRecord is actually active for the pid.
4911         synchronized (mPidsSelfLocked) {
4912             ProcessRecord curProc = mPidsSelfLocked.get(pid);
4913             if (curProc != app) {
4914                 Slog.w(TAG, "Spurious death for " + app + ", curProc for " + pid + ": " + curProc);
4915                 return;
4916             }
4917         }
4918
4919         BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
4920         synchronized (stats) {
4921             stats.noteProcessDiedLocked(app.info.uid, pid);
4922         }
4923
4924         if (!app.killed) {
4925             if (!fromBinderDied) {
4926                 Process.killProcessQuiet(pid);
4927             }
4928             killProcessGroup(app.info.uid, pid);
4929             app.killed = true;
4930         }
4931
4932         // Clean up already done if the process has been re-started.
4933         if (app.pid == pid && app.thread != null &&
4934                 app.thread.asBinder() == thread.asBinder()) {
4935             boolean doLowMem = app.instrumentationClass == null;
4936             boolean doOomAdj = doLowMem;
4937             if (!app.killedByAm) {
4938                 Slog.i(TAG, "Process " + app.processName + " (pid " + pid
4939                         + ") has died");
4940                 mAllowLowerMemLevel = true;
4941             } else {
4942                 // Note that we always want to do oom adj to update our state with the
4943                 // new number of procs.
4944                 mAllowLowerMemLevel = false;
4945                 doLowMem = false;
4946             }
4947             EventLog.writeEvent(EventLogTags.AM_PROC_DIED, app.userId, app.pid, app.processName);
4948             if (DEBUG_CLEANUP) Slog.v(TAG_CLEANUP,
4949                 "Dying app: " + app + ", pid: " + pid + ", thread: " + thread.asBinder());
4950             handleAppDiedLocked(app, false, true);
4951
4952             if (doOomAdj) {
4953                 updateOomAdjLocked();
4954             }
4955             if (doLowMem) {
4956                 doLowMemReportIfNeededLocked(app);
4957             }
4958         } else if (app.pid != pid) {
4959             // A new process has already been started.
4960             Slog.i(TAG, "Process " + app.processName + " (pid " + pid
4961                     + ") has died and restarted (pid " + app.pid + ").");
4962             EventLog.writeEvent(EventLogTags.AM_PROC_DIED, app.userId, app.pid, app.processName);
4963         } else if (DEBUG_PROCESSES) {
4964             Slog.d(TAG_PROCESSES, "Received spurious death notification for thread "
4965                     + thread.asBinder());
4966         }
4967     }
4968
4969     /**
4970      * If a stack trace dump file is configured, dump process stack traces.
4971      * @param clearTraces causes the dump file to be erased prior to the new
4972      *    traces being written, if true; when false, the new traces will be
4973      *    appended to any existing file content.
4974      * @param firstPids of dalvik VM processes to dump stack traces for first
4975      * @param lastPids of dalvik VM processes to dump stack traces for last
4976      * @param nativeProcs optional list of native process names to dump stack crawls
4977      * @return file containing stack traces, or null if no dump file is configured
4978      */
4979     public static File dumpStackTraces(boolean clearTraces, ArrayList<Integer> firstPids,
4980             ProcessCpuTracker processCpuTracker, SparseArray<Boolean> lastPids, String[] nativeProcs) {
4981         String tracesPath = SystemProperties.get("dalvik.vm.stack-trace-file", null);
4982         if (tracesPath == null || tracesPath.length() == 0) {
4983             return null;
4984         }
4985
4986         File tracesFile = new File(tracesPath);
4987         try {
4988             if (clearTraces && tracesFile.exists()) tracesFile.delete();
4989             tracesFile.createNewFile();
4990             FileUtils.setPermissions(tracesFile.getPath(), 0666, -1, -1); // -rw-rw-rw-
4991         } catch (IOException e) {
4992             Slog.w(TAG, "Unable to prepare ANR traces file: " + tracesPath, e);
4993             return null;
4994         }
4995
4996         dumpStackTraces(tracesPath, firstPids, processCpuTracker, lastPids, nativeProcs);
4997         return tracesFile;
4998     }
4999
5000     private static void dumpStackTraces(String tracesPath, ArrayList<Integer> firstPids,
5001             ProcessCpuTracker processCpuTracker, SparseArray<Boolean> lastPids, String[] nativeProcs) {
5002         // Use a FileObserver to detect when traces finish writing.
5003         // The order of traces is considered important to maintain for legibility.
5004         FileObserver observer = new FileObserver(tracesPath, FileObserver.CLOSE_WRITE) {
5005             @Override
5006             public synchronized void onEvent(int event, String path) { notify(); }
5007         };
5008
5009         try {
5010             observer.startWatching();
5011
5012             // First collect all of the stacks of the most important pids.
5013             if (firstPids != null) {
5014                 try {
5015                     int num = firstPids.size();
5016                     for (int i = 0; i < num; i++) {
5017                         synchronized (observer) {
5018                             Process.sendSignal(firstPids.get(i), Process.SIGNAL_QUIT);
5019                             observer.wait(200);  // Wait for write-close, give up after 200msec
5020                         }
5021                     }
5022                 } catch (InterruptedException e) {
5023                     Slog.wtf(TAG, e);
5024                 }
5025             }
5026
5027             // Next collect the stacks of the native pids
5028             if (nativeProcs != null) {
5029                 int[] pids = Process.getPidsForCommands(nativeProcs);
5030                 if (pids != null) {
5031                     for (int pid : pids) {
5032                         Debug.dumpNativeBacktraceToFile(pid, tracesPath);
5033                     }
5034                 }
5035             }
5036
5037             // Lastly, measure CPU usage.
5038             if (processCpuTracker != null) {
5039                 processCpuTracker.init();
5040                 System.gc();
5041                 processCpuTracker.update();
5042                 try {
5043                     synchronized (processCpuTracker) {
5044                         processCpuTracker.wait(500); // measure over 1/2 second.
5045                     }
5046                 } catch (InterruptedException e) {
5047                 }
5048                 processCpuTracker.update();
5049
5050                 // We'll take the stack crawls of just the top apps using CPU.
5051                 final int N = processCpuTracker.countWorkingStats();
5052                 int numProcs = 0;
5053                 for (int i=0; i<N && numProcs<5; i++) {
5054                     ProcessCpuTracker.Stats stats = processCpuTracker.getWorkingStats(i);
5055                     if (lastPids.indexOfKey(stats.pid) >= 0) {
5056                         numProcs++;
5057                         try {
5058                             synchronized (observer) {
5059                                 Process.sendSignal(stats.pid, Process.SIGNAL_QUIT);
5060                                 observer.wait(200);  // Wait for write-close, give up after 200msec
5061                             }
5062                         } catch (InterruptedException e) {
5063                             Slog.wtf(TAG, e);
5064                         }
5065
5066                     }
5067                 }
5068             }
5069         } finally {
5070             observer.stopWatching();
5071         }
5072     }
5073
5074     final void logAppTooSlow(ProcessRecord app, long startTime, String msg) {
5075         if (true || IS_USER_BUILD) {
5076             return;
5077         }
5078         String tracesPath = SystemProperties.get("dalvik.vm.stack-trace-file", null);
5079         if (tracesPath == null || tracesPath.length() == 0) {
5080             return;
5081         }
5082
5083         StrictMode.ThreadPolicy oldPolicy = StrictMode.allowThreadDiskReads();
5084         StrictMode.allowThreadDiskWrites();
5085         try {
5086             final File tracesFile = new File(tracesPath);
5087             final File tracesDir = tracesFile.getParentFile();
5088             final File tracesTmp = new File(tracesDir, "__tmp__");
5089             try {
5090                 if (tracesFile.exists()) {
5091                     tracesTmp.delete();
5092                     tracesFile.renameTo(tracesTmp);
5093                 }
5094                 StringBuilder sb = new StringBuilder();
5095                 Time tobj = new Time();
5096                 tobj.set(System.currentTimeMillis());
5097                 sb.append(tobj.format("%Y-%m-%d %H:%M:%S"));
5098                 sb.append(": ");
5099                 TimeUtils.formatDuration(SystemClock.uptimeMillis()-startTime, sb);
5100                 sb.append(" since ");
5101                 sb.append(msg);
5102                 FileOutputStream fos = new FileOutputStream(tracesFile);
5103                 fos.write(sb.toString().getBytes());
5104                 if (app == null) {
5105                     fos.write("\n*** No application process!".getBytes());
5106                 }
5107                 fos.close();
5108                 FileUtils.setPermissions(tracesFile.getPath(), 0666, -1, -1); // -rw-rw-rw-
5109             } catch (IOException e) {
5110                 Slog.w(TAG, "Unable to prepare slow app traces file: " + tracesPath, e);
5111                 return;
5112             }
5113
5114             if (app != null) {
5115                 ArrayList<Integer> firstPids = new ArrayList<Integer>();
5116                 firstPids.add(app.pid);
5117                 dumpStackTraces(tracesPath, firstPids, null, null, null);
5118             }
5119
5120             File lastTracesFile = null;
5121             File curTracesFile = null;
5122             for (int i=9; i>=0; i--) {
5123                 String name = String.format(Locale.US, "slow%02d.txt", i);
5124                 curTracesFile = new File(tracesDir, name);
5125                 if (curTracesFile.exists()) {
5126                     if (lastTracesFile != null) {
5127                         curTracesFile.renameTo(lastTracesFile);
5128                     } else {
5129                         curTracesFile.delete();
5130                     }
5131                 }
5132                 lastTracesFile = curTracesFile;
5133             }
5134             tracesFile.renameTo(curTracesFile);
5135             if (tracesTmp.exists()) {
5136                 tracesTmp.renameTo(tracesFile);
5137             }
5138         } finally {
5139             StrictMode.setThreadPolicy(oldPolicy);
5140         }
5141     }
5142
5143     final void appNotResponding(ProcessRecord app, ActivityRecord activity,
5144             ActivityRecord parent, boolean aboveSystem, final String annotation) {
5145         ArrayList<Integer> firstPids = new ArrayList<Integer>(5);
5146         SparseArray<Boolean> lastPids = new SparseArray<Boolean>(20);
5147
5148         if (mController != null) {
5149             try {
5150                 // 0 == continue, -1 = kill process immediately
5151                 int res = mController.appEarlyNotResponding(app.processName, app.pid, annotation);
5152                 if (res < 0 && app.pid != MY_PID) {
5153                     app.kill("anr", true);
5154                 }
5155             } catch (RemoteException e) {
5156                 mController = null;
5157                 Watchdog.getInstance().setActivityController(null);
5158             }
5159         }
5160
5161         long anrTime = SystemClock.uptimeMillis();
5162         if (MONITOR_CPU_USAGE) {
5163             updateCpuStatsNow();
5164         }
5165
5166         synchronized (this) {
5167             // PowerManager.reboot() can block for a long time, so ignore ANRs while shutting down.
5168             if (mShuttingDown) {
5169                 Slog.i(TAG, "During shutdown skipping ANR: " + app + " " + annotation);
5170                 return;
5171             } else if (app.notResponding) {
5172                 Slog.i(TAG, "Skipping duplicate ANR: " + app + " " + annotation);
5173                 return;
5174             } else if (app.crashing) {
5175                 Slog.i(TAG, "Crashing app skipping ANR: " + app + " " + annotation);
5176                 return;
5177             }
5178
5179             // In case we come through here for the same app before completing
5180             // this one, mark as anring now so we will bail out.
5181             app.notResponding = true;
5182
5183             // Log the ANR to the event log.
5184             EventLog.writeEvent(EventLogTags.AM_ANR, app.userId, app.pid,
5185                     app.processName, app.info.flags, annotation);
5186
5187             // Dump thread traces as quickly as we can, starting with "interesting" processes.
5188             firstPids.add(app.pid);
5189
5190             int parentPid = app.pid;
5191             if (parent != null && parent.app != null && parent.app.pid > 0) parentPid = parent.app.pid;
5192             if (parentPid != app.pid) firstPids.add(parentPid);
5193
5194             if (MY_PID != app.pid && MY_PID != parentPid) firstPids.add(MY_PID);
5195
5196             for (int i = mLruProcesses.size() - 1; i >= 0; i--) {
5197                 ProcessRecord r = mLruProcesses.get(i);
5198                 if (r != null && r.thread != null) {
5199                     int pid = r.pid;
5200                     if (pid > 0 && pid != app.pid && pid != parentPid && pid != MY_PID) {
5201                         if (r.persistent) {
5202                             firstPids.add(pid);
5203                         } else {
5204                             lastPids.put(pid, Boolean.TRUE);
5205                         }
5206                     }
5207                 }
5208             }
5209         }
5210
5211         // Log the ANR to the main log.
5212         StringBuilder info = new StringBuilder();
5213         info.setLength(0);
5214         info.append("ANR in ").append(app.processName);
5215         if (activity != null && activity.shortComponentName != null) {
5216             info.append(" (").append(activity.shortComponentName).append(")");
5217         }
5218         info.append("\n");
5219         info.append("PID: ").append(app.pid).append("\n");
5220         if (annotation != null) {
5221             info.append("Reason: ").append(annotation).append("\n");
5222         }
5223         if (parent != null && parent != activity) {
5224             info.append("Parent: ").append(parent.shortComponentName).append("\n");
5225         }
5226
5227         final ProcessCpuTracker processCpuTracker = new ProcessCpuTracker(true);
5228
5229         File tracesFile = dumpStackTraces(true, firstPids, processCpuTracker, lastPids,
5230                 NATIVE_STACKS_OF_INTEREST);
5231
5232         String cpuInfo = null;
5233         if (MONITOR_CPU_USAGE) {
5234             updateCpuStatsNow();
5235             synchronized (mProcessCpuTracker) {
5236                 cpuInfo = mProcessCpuTracker.printCurrentState(anrTime);
5237             }
5238             info.append(processCpuTracker.printCurrentLoad());
5239             info.append(cpuInfo);
5240         }
5241
5242         info.append(processCpuTracker.printCurrentState(anrTime));
5243
5244         Slog.e(TAG, info.toString());
5245         if (tracesFile == null) {
5246             // There is no trace file, so dump (only) the alleged culprit's threads to the log
5247             Process.sendSignal(app.pid, Process.SIGNAL_QUIT);
5248         }
5249
5250         addErrorToDropBox("anr", app, app.processName, activity, parent, annotation,
5251                 cpuInfo, tracesFile, null);
5252
5253         if (mController != null) {
5254             try {
5255                 // 0 == show dialog, 1 = keep waiting, -1 = kill process immediately
5256                 int res = mController.appNotResponding(app.processName, app.pid, info.toString());
5257                 if (res != 0) {
5258                     if (res < 0 && app.pid != MY_PID) {
5259                         app.kill("anr", true);
5260                     } else {
5261                         synchronized (this) {
5262                             mServices.scheduleServiceTimeoutLocked(app);
5263                         }
5264                     }
5265                     return;
5266                 }
5267             } catch (RemoteException e) {
5268                 mController = null;
5269                 Watchdog.getInstance().setActivityController(null);
5270             }
5271         }
5272
5273         // Unless configured otherwise, swallow ANRs in background processes & kill the process.
5274         boolean showBackground = Settings.Secure.getInt(mContext.getContentResolver(),
5275                 Settings.Secure.ANR_SHOW_BACKGROUND, 0) != 0;
5276
5277         synchronized (this) {
5278             mBatteryStatsService.noteProcessAnr(app.processName, app.uid);
5279
5280             if (!showBackground && !app.isInterestingToUserLocked() && app.pid != MY_PID) {
5281                 app.kill("bg anr", true);
5282                 return;
5283             }
5284
5285             // Set the app's notResponding state, and look up the errorReportReceiver
5286             makeAppNotRespondingLocked(app,
5287                     activity != null ? activity.shortComponentName : null,
5288                     annotation != null ? "ANR " + annotation : "ANR",
5289                     info.toString());
5290
5291             // Bring up the infamous App Not Responding dialog
5292             Message msg = Message.obtain();
5293             HashMap<String, Object> map = new HashMap<String, Object>();
5294             msg.what = SHOW_NOT_RESPONDING_UI_MSG;
5295             msg.obj = map;
5296             msg.arg1 = aboveSystem ? 1 : 0;
5297             map.put("app", app);
5298             if (activity != null) {
5299                 map.put("activity", activity);
5300             }
5301
5302             mUiHandler.sendMessage(msg);
5303         }
5304     }
5305
5306     final void showLaunchWarningLocked(final ActivityRecord cur, final ActivityRecord next) {
5307         if (!mLaunchWarningShown) {
5308             mLaunchWarningShown = true;
5309             mUiHandler.post(new Runnable() {
5310                 @Override
5311                 public void run() {
5312                     synchronized (ActivityManagerService.this) {
5313                         final Dialog d = new LaunchWarningWindow(mContext, cur, next);
5314                         d.show();
5315                         mUiHandler.postDelayed(new Runnable() {
5316                             @Override
5317                             public void run() {
5318                                 synchronized (ActivityManagerService.this) {
5319                                     d.dismiss();
5320                                     mLaunchWarningShown = false;
5321                                 }
5322                             }
5323                         }, 4000);
5324                     }
5325                 }
5326             });
5327         }
5328     }
5329
5330     @Override
5331     public boolean clearApplicationUserData(final String packageName,
5332             final IPackageDataObserver observer, int userId) {
5333         enforceNotIsolatedCaller("clearApplicationUserData");
5334         if (packageName != null && packageName.equals(mDeviceOwnerName)) {
5335             throw new SecurityException("Clearing DeviceOwner data is forbidden.");
5336         }
5337         int uid = Binder.getCallingUid();
5338         int pid = Binder.getCallingPid();
5339         userId = mUserController.handleIncomingUser(pid, uid, userId, false,
5340                 ALLOW_FULL_ONLY, "clearApplicationUserData", null);
5341         long callingId = Binder.clearCallingIdentity();
5342         try {
5343             IPackageManager pm = AppGlobals.getPackageManager();
5344             int pkgUid = -1;
5345             synchronized(this) {
5346                 try {
5347                     pkgUid = pm.getPackageUid(packageName, userId);
5348                 } catch (RemoteException e) {
5349                 }
5350                 if (pkgUid == -1) {
5351                     Slog.w(TAG, "Invalid packageName: " + packageName);
5352                     if (observer != null) {
5353                         try {
5354                             observer.onRemoveCompleted(packageName, false);
5355                         } catch (RemoteException e) {
5356                             Slog.i(TAG, "Observer no longer exists.");
5357                         }
5358                     }
5359                     return false;
5360                 }
5361                 if (uid == pkgUid || checkComponentPermission(
5362                         android.Manifest.permission.CLEAR_APP_USER_DATA,
5363                         pid, uid, -1, true)
5364                         == PackageManager.PERMISSION_GRANTED) {
5365                     forceStopPackageLocked(packageName, pkgUid, "clear data");
5366                 } else {
5367                     throw new SecurityException("PID " + pid + " does not have permission "
5368                             + android.Manifest.permission.CLEAR_APP_USER_DATA + " to clear data"
5369                                     + " of package " + packageName);
5370                 }
5371
5372                 // Remove all tasks match the cleared application package and user
5373                 for (int i = mRecentTasks.size() - 1; i >= 0; i--) {
5374                     final TaskRecord tr = mRecentTasks.get(i);
5375                     final String taskPackageName =
5376                             tr.getBaseIntent().getComponent().getPackageName();
5377                     if (tr.userId != userId) continue;
5378                     if (!taskPackageName.equals(packageName)) continue;
5379                     removeTaskByIdLocked(tr.taskId, false, REMOVE_FROM_RECENTS);
5380                 }
5381             }
5382
5383             try {
5384                 // Clear application user data
5385                 pm.clearApplicationUserData(packageName, observer, userId);
5386
5387                 synchronized(this) {
5388                     // Remove all permissions granted from/to this package
5389                     removeUriPermissionsForPackageLocked(packageName, userId, true);
5390                 }
5391
5392                 Intent intent = new Intent(Intent.ACTION_PACKAGE_DATA_CLEARED,
5393                         Uri.fromParts("package", packageName, null));
5394                 intent.putExtra(Intent.EXTRA_UID, pkgUid);
5395                 broadcastIntentInPackage("android", Process.SYSTEM_UID, intent,
5396                         null, null, 0, null, null, null, null, false, false, userId);
5397             } catch (RemoteException e) {
5398             }
5399         } finally {
5400             Binder.restoreCallingIdentity(callingId);
5401         }
5402         return true;
5403     }
5404
5405     @Override
5406     public void killBackgroundProcesses(final String packageName, int userId) {
5407         if (checkCallingPermission(android.Manifest.permission.KILL_BACKGROUND_PROCESSES)
5408                 != PackageManager.PERMISSION_GRANTED &&
5409                 checkCallingPermission(android.Manifest.permission.RESTART_PACKAGES)
5410                         != PackageManager.PERMISSION_GRANTED) {
5411             String msg = "Permission Denial: killBackgroundProcesses() from pid="
5412                     + Binder.getCallingPid()
5413                     + ", uid=" + Binder.getCallingUid()
5414                     + " requires " + android.Manifest.permission.KILL_BACKGROUND_PROCESSES;
5415             Slog.w(TAG, msg);
5416             throw new SecurityException(msg);
5417         }
5418
5419         userId = mUserController.handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(),
5420                 userId, true, ALLOW_FULL_ONLY, "killBackgroundProcesses", null);
5421         long callingId = Binder.clearCallingIdentity();
5422         try {
5423             IPackageManager pm = AppGlobals.getPackageManager();
5424             synchronized(this) {
5425                 int appId = -1;
5426                 try {
5427                     appId = UserHandle.getAppId(pm.getPackageUid(packageName, 0));
5428                 } catch (RemoteException e) {
5429                 }
5430                 if (appId == -1) {
5431                     Slog.w(TAG, "Invalid packageName: " + packageName);
5432                     return;
5433                 }
5434                 killPackageProcessesLocked(packageName, appId, userId,
5435                         ProcessList.SERVICE_ADJ, false, true, true, false, "kill background");
5436             }
5437         } finally {
5438             Binder.restoreCallingIdentity(callingId);
5439         }
5440     }
5441
5442     @Override
5443     public void killAllBackgroundProcesses() {
5444         if (checkCallingPermission(android.Manifest.permission.KILL_BACKGROUND_PROCESSES)
5445                 != PackageManager.PERMISSION_GRANTED) {
5446             String msg = "Permission Denial: killAllBackgroundProcesses() from pid="
5447                     + Binder.getCallingPid()
5448                     + ", uid=" + Binder.getCallingUid()
5449                     + " requires " + android.Manifest.permission.KILL_BACKGROUND_PROCESSES;
5450             Slog.w(TAG, msg);
5451             throw new SecurityException(msg);
5452         }
5453
5454         long callingId = Binder.clearCallingIdentity();
5455         try {
5456             synchronized(this) {
5457                 ArrayList<ProcessRecord> procs = new ArrayList<ProcessRecord>();
5458                 final int NP = mProcessNames.getMap().size();
5459                 for (int ip=0; ip<NP; ip++) {
5460                     SparseArray<ProcessRecord> apps = mProcessNames.getMap().valueAt(ip);
5461                     final int NA = apps.size();
5462                     for (int ia=0; ia<NA; ia++) {
5463                         ProcessRecord app = apps.valueAt(ia);
5464                         if (app.persistent) {
5465                             // we don't kill persistent processes
5466                             continue;
5467                         }
5468                         if (app.removed) {
5469                             procs.add(app);
5470                         } else if (app.setAdj >= ProcessList.CACHED_APP_MIN_ADJ) {
5471                             app.removed = true;
5472                             procs.add(app);
5473                         }
5474                     }
5475                 }
5476
5477                 int N = procs.size();
5478                 for (int i=0; i<N; i++) {
5479                     removeProcessLocked(procs.get(i), false, true, "kill all background");
5480                 }
5481                 mAllowLowerMemLevel = true;
5482                 updateOomAdjLocked();
5483                 doLowMemReportIfNeededLocked(null);
5484             }
5485         } finally {
5486             Binder.restoreCallingIdentity(callingId);
5487         }
5488     }
5489
5490     @Override
5491     public void forceStopPackage(final String packageName, int userId) {
5492         if (checkCallingPermission(android.Manifest.permission.FORCE_STOP_PACKAGES)
5493                 != PackageManager.PERMISSION_GRANTED) {
5494             String msg = "Permission Denial: forceStopPackage() from pid="
5495                     + Binder.getCallingPid()
5496                     + ", uid=" + Binder.getCallingUid()
5497                     + " requires " + android.Manifest.permission.FORCE_STOP_PACKAGES;
5498             Slog.w(TAG, msg);
5499             throw new SecurityException(msg);
5500         }
5501         final int callingPid = Binder.getCallingPid();
5502         userId = mUserController.handleIncomingUser(callingPid, Binder.getCallingUid(),
5503                 userId, true, ALLOW_FULL_ONLY, "forceStopPackage", null);
5504         long callingId = Binder.clearCallingIdentity();
5505         try {
5506             IPackageManager pm = AppGlobals.getPackageManager();
5507             synchronized(this) {
5508                 int[] users = userId == UserHandle.USER_ALL
5509                         ? mUserController.getUsers() : new int[] { userId };
5510                 for (int user : users) {
5511                     int pkgUid = -1;
5512                     try {
5513                         pkgUid = pm.getPackageUid(packageName, user);
5514                     } catch (RemoteException e) {
5515                     }
5516                     if (pkgUid == -1) {
5517                         Slog.w(TAG, "Invalid packageName: " + packageName);
5518                         continue;
5519                     }
5520                     try {
5521                         pm.setPackageStoppedState(packageName, true, user);
5522                     } catch (RemoteException e) {
5523                     } catch (IllegalArgumentException e) {
5524                         Slog.w(TAG, "Failed trying to unstop package "
5525                                 + packageName + ": " + e);
5526                     }
5527                     if (mUserController.isUserRunningLocked(user, 0)) {
5528                         forceStopPackageLocked(packageName, pkgUid, "from pid " + callingPid);
5529                     }
5530                 }
5531             }
5532         } finally {
5533             Binder.restoreCallingIdentity(callingId);
5534         }
5535     }
5536
5537     @Override
5538     public void addPackageDependency(String packageName) {
5539         synchronized (this) {
5540             int callingPid = Binder.getCallingPid();
5541             if (callingPid == Process.myPid()) {
5542                 //  Yeah, um, no.
5543                 return;
5544             }
5545             ProcessRecord proc;
5546             synchronized (mPidsSelfLocked) {
5547                 proc = mPidsSelfLocked.get(Binder.getCallingPid());
5548             }
5549             if (proc != null) {
5550                 if (proc.pkgDeps == null) {
5551                     proc.pkgDeps = new ArraySet<String>(1);
5552                 }
5553                 proc.pkgDeps.add(packageName);
5554             }
5555         }
5556     }
5557
5558     /*
5559      * The pkg name and app id have to be specified.
5560      */
5561     @Override
5562     public void killApplicationWithAppId(String pkg, int appid, String reason) {
5563         if (pkg == null) {
5564             return;
5565         }
5566         // Make sure the uid is valid.
5567         if (appid < 0) {
5568             Slog.w(TAG, "Invalid appid specified for pkg : " + pkg);
5569             return;
5570         }
5571         int callerUid = Binder.getCallingUid();
5572         // Only the system server can kill an application
5573         if (UserHandle.getAppId(callerUid) == Process.SYSTEM_UID) {
5574             // Post an aysnc message to kill the application
5575             Message msg = mHandler.obtainMessage(KILL_APPLICATION_MSG);
5576             msg.arg1 = appid;
5577             msg.arg2 = 0;
5578             Bundle bundle = new Bundle();
5579             bundle.putString("pkg", pkg);
5580             bundle.putString("reason", reason);
5581             msg.obj = bundle;
5582             mHandler.sendMessage(msg);
5583         } else {
5584             throw new SecurityException(callerUid + " cannot kill pkg: " +
5585                     pkg);
5586         }
5587     }
5588
5589     @Override
5590     public void closeSystemDialogs(String reason) {
5591         enforceNotIsolatedCaller("closeSystemDialogs");
5592
5593         final int pid = Binder.getCallingPid();
5594         final int uid = Binder.getCallingUid();
5595         final long origId = Binder.clearCallingIdentity();
5596         try {
5597             synchronized (this) {
5598                 // Only allow this from foreground processes, so that background
5599                 // applications can't abuse it to prevent system UI from being shown.
5600                 if (uid >= Process.FIRST_APPLICATION_UID) {
5601                     ProcessRecord proc;
5602                     synchronized (mPidsSelfLocked) {
5603                         proc = mPidsSelfLocked.get(pid);
5604                     }
5605                     if (proc.curRawAdj > ProcessList.PERCEPTIBLE_APP_ADJ) {
5606                         Slog.w(TAG, "Ignoring closeSystemDialogs " + reason
5607                                 + " from background process " + proc);
5608                         return;
5609                     }
5610                 }
5611                 closeSystemDialogsLocked(reason);
5612             }
5613         } finally {
5614             Binder.restoreCallingIdentity(origId);
5615         }
5616     }
5617
5618     void closeSystemDialogsLocked(String reason) {
5619         Intent intent = new Intent(Intent.ACTION_CLOSE_SYSTEM_DIALOGS);
5620         intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY
5621                 | Intent.FLAG_RECEIVER_FOREGROUND);
5622         if (reason != null) {
5623             intent.putExtra("reason", reason);
5624         }
5625         mWindowManager.closeSystemDialogs(reason);
5626
5627         mStackSupervisor.closeSystemDialogsLocked();
5628
5629         broadcastIntentLocked(null, null, intent, null, null, 0, null, null, null,
5630                 AppOpsManager.OP_NONE, null, false, false,
5631                 -1, Process.SYSTEM_UID, UserHandle.USER_ALL);
5632     }
5633
5634     @Override
5635     public Debug.MemoryInfo[] getProcessMemoryInfo(int[] pids) {
5636         enforceNotIsolatedCaller("getProcessMemoryInfo");
5637         Debug.MemoryInfo[] infos = new Debug.MemoryInfo[pids.length];
5638         for (int i=pids.length-1; i>=0; i--) {
5639             ProcessRecord proc;
5640             int oomAdj;
5641             synchronized (this) {
5642                 synchronized (mPidsSelfLocked) {
5643                     proc = mPidsSelfLocked.get(pids[i]);
5644                     oomAdj = proc != null ? proc.setAdj : 0;
5645                 }
5646             }
5647             infos[i] = new Debug.MemoryInfo();
5648             Debug.getMemoryInfo(pids[i], infos[i]);
5649             if (proc != null) {
5650                 synchronized (this) {
5651                     if (proc.thread != null && proc.setAdj == oomAdj) {
5652                         // Record this for posterity if the process has been stable.
5653                         proc.baseProcessTracker.addPss(infos[i].getTotalPss(),
5654                                 infos[i].getTotalUss(), false, proc.pkgList);
5655                     }
5656                 }
5657             }
5658         }
5659         return infos;
5660     }
5661
5662     @Override
5663     public long[] getProcessPss(int[] pids) {
5664         enforceNotIsolatedCaller("getProcessPss");
5665         long[] pss = new long[pids.length];
5666         for (int i=pids.length-1; i>=0; i--) {
5667             ProcessRecord proc;
5668             int oomAdj;
5669             synchronized (this) {
5670                 synchronized (mPidsSelfLocked) {
5671                     proc = mPidsSelfLocked.get(pids[i]);
5672                     oomAdj = proc != null ? proc.setAdj : 0;
5673                 }
5674             }
5675             long[] tmpUss = new long[1];
5676             pss[i] = Debug.getPss(pids[i], tmpUss, null);
5677             if (proc != null) {
5678                 synchronized (this) {
5679                     if (proc.thread != null && proc.setAdj == oomAdj) {
5680                         // Record this for posterity if the process has been stable.
5681                         proc.baseProcessTracker.addPss(pss[i], tmpUss[0], false, proc.pkgList);
5682                     }
5683                 }
5684             }
5685         }
5686         return pss;
5687     }
5688
5689     @Override
5690     public void killApplicationProcess(String processName, int uid) {
5691         if (processName == null) {
5692             return;
5693         }
5694
5695         int callerUid = Binder.getCallingUid();
5696         // Only the system server can kill an application
5697         if (callerUid == Process.SYSTEM_UID) {
5698             synchronized (this) {
5699                 ProcessRecord app = getProcessRecordLocked(processName, uid, true);
5700                 if (app != null && app.thread != null) {
5701                     try {
5702                         app.thread.scheduleSuicide();
5703                     } catch (RemoteException e) {
5704                         // If the other end already died, then our work here is done.
5705                     }
5706                 } else {
5707                     Slog.w(TAG, "Process/uid not found attempting kill of "
5708                             + processName + " / " + uid);
5709                 }
5710             }
5711         } else {
5712             throw new SecurityException(callerUid + " cannot kill app process: " +
5713                     processName);
5714         }
5715     }
5716
5717     private void forceStopPackageLocked(final String packageName, int uid, String reason) {
5718         forceStopPackageLocked(packageName, UserHandle.getAppId(uid), false,
5719                 false, true, false, false, UserHandle.getUserId(uid), reason);
5720         Intent intent = new Intent(Intent.ACTION_PACKAGE_RESTARTED,
5721                 Uri.fromParts("package", packageName, null));
5722         if (!mProcessesReady) {
5723             intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY
5724                     | Intent.FLAG_RECEIVER_FOREGROUND);
5725         }
5726         intent.putExtra(Intent.EXTRA_UID, uid);
5727         intent.putExtra(Intent.EXTRA_USER_HANDLE, UserHandle.getUserId(uid));
5728         broadcastIntentLocked(null, null, intent,
5729                 null, null, 0, null, null, null, AppOpsManager.OP_NONE,
5730                 null, false, false, MY_PID, Process.SYSTEM_UID, UserHandle.getUserId(uid));
5731     }
5732
5733
5734     private final boolean killPackageProcessesLocked(String packageName, int appId,
5735             int userId, int minOomAdj, boolean callerWillRestart, boolean allowRestart,
5736             boolean doit, boolean evenPersistent, String reason) {
5737         ArrayList<ProcessRecord> procs = new ArrayList<>();
5738
5739         // Remove all processes this package may have touched: all with the
5740         // same UID (except for the system or root user), and all whose name
5741         // matches the package name.
5742         final int NP = mProcessNames.getMap().size();
5743         for (int ip=0; ip<NP; ip++) {
5744             SparseArray<ProcessRecord> apps = mProcessNames.getMap().valueAt(ip);
5745             final int NA = apps.size();
5746             for (int ia=0; ia<NA; ia++) {
5747                 ProcessRecord app = apps.valueAt(ia);
5748                 if (app.persistent && !evenPersistent) {
5749                     // we don't kill persistent processes
5750                     continue;
5751                 }
5752                 if (app.removed) {
5753                     if (doit) {
5754                         procs.add(app);
5755                     }
5756                     continue;
5757                 }
5758
5759                 // Skip process if it doesn't meet our oom adj requirement.
5760                 if (app.setAdj < minOomAdj) {
5761                     continue;
5762                 }
5763
5764                 // If no package is specified, we call all processes under the
5765                 // give user id.
5766                 if (packageName == null) {
5767                     if (userId != UserHandle.USER_ALL && app.userId != userId) {
5768                         continue;
5769                     }
5770                     if (appId >= 0 && UserHandle.getAppId(app.uid) != appId) {
5771                         continue;
5772                     }
5773                 // Package has been specified, we want to hit all processes
5774                 // that match it.  We need to qualify this by the processes
5775                 // that are running under the specified app and user ID.
5776                 } else {
5777                     final boolean isDep = app.pkgDeps != null
5778                             && app.pkgDeps.contains(packageName);
5779                     if (!isDep && UserHandle.getAppId(app.uid) != appId) {
5780                         continue;
5781                     }
5782                     if (userId != UserHandle.USER_ALL && app.userId != userId) {
5783                         continue;
5784                     }
5785                     if (!app.pkgList.containsKey(packageName) && !isDep) {
5786                         continue;
5787                     }
5788                 }
5789
5790                 // Process has passed all conditions, kill it!
5791                 if (!doit) {
5792                     return true;
5793                 }
5794                 app.removed = true;
5795                 procs.add(app);
5796             }
5797         }
5798
5799         int N = procs.size();
5800         for (int i=0; i<N; i++) {
5801             removeProcessLocked(procs.get(i), callerWillRestart, allowRestart, reason);
5802         }
5803         updateOomAdjLocked();
5804         return N > 0;
5805     }
5806
5807     private void cleanupDisabledPackageComponentsLocked(
5808             String packageName, int userId, boolean killProcess, String[] changedClasses) {
5809
5810         Set<String> disabledClasses = null;
5811         boolean packageDisabled = false;
5812         IPackageManager pm = AppGlobals.getPackageManager();
5813
5814         if (changedClasses == null) {
5815             // Nothing changed...
5816             return;
5817         }
5818
5819         // Determine enable/disable state of the package and its components.
5820         int enabled = PackageManager.COMPONENT_ENABLED_STATE_DEFAULT;
5821         for (int i = changedClasses.length - 1; i >= 0; i--) {
5822             final String changedClass = changedClasses[i];
5823
5824             if (changedClass.equals(packageName)) {
5825                 try {
5826                     // Entire package setting changed
5827                     enabled = pm.getApplicationEnabledSetting(packageName,
5828                             (userId != UserHandle.USER_ALL) ? userId : UserHandle.USER_SYSTEM);
5829                 } catch (Exception e) {
5830                     // No such package/component; probably racing with uninstall.  In any
5831                     // event it means we have nothing further to do here.
5832                     return;
5833                 }
5834                 packageDisabled = enabled != PackageManager.COMPONENT_ENABLED_STATE_ENABLED
5835                         && enabled != PackageManager.COMPONENT_ENABLED_STATE_DEFAULT;
5836                 if (packageDisabled) {
5837                     // Entire package is disabled.
5838                     // No need to continue to check component states.
5839                     disabledClasses = null;
5840                     break;
5841                 }
5842             } else {
5843                 try {
5844                     enabled = pm.getComponentEnabledSetting(
5845                             new ComponentName(packageName, changedClass),
5846                             (userId != UserHandle.USER_ALL) ? userId : UserHandle.USER_SYSTEM);
5847                 } catch (Exception e) {
5848                     // As above, probably racing with uninstall.
5849                     return;
5850                 }
5851                 if (enabled != PackageManager.COMPONENT_ENABLED_STATE_ENABLED
5852                         && enabled != PackageManager.COMPONENT_ENABLED_STATE_DEFAULT) {
5853                     if (disabledClasses == null) {
5854                         disabledClasses = new ArraySet<>(changedClasses.length);
5855                     }
5856                     disabledClasses.add(changedClass);
5857                 }
5858             }
5859         }
5860
5861         if (!packageDisabled && disabledClasses == null) {
5862             // Nothing to do here...
5863             return;
5864         }
5865
5866         // Clean-up disabled activities.
5867         if (mStackSupervisor.finishDisabledPackageActivitiesLocked(
5868                 packageName, disabledClasses, true, false, userId) && mBooted) {
5869             mStackSupervisor.resumeTopActivitiesLocked();
5870             mStackSupervisor.scheduleIdleLocked();
5871         }
5872
5873         // Clean-up disabled tasks
5874         cleanupDisabledPackageTasksLocked(packageName, disabledClasses, userId);
5875
5876         // Clean-up disabled services.
5877         mServices.bringDownDisabledPackageServicesLocked(
5878                 packageName, disabledClasses, userId, false, killProcess, true);
5879
5880         // Clean-up disabled providers.
5881         ArrayList<ContentProviderRecord> providers = new ArrayList<>();
5882         mProviderMap.collectPackageProvidersLocked(
5883                 packageName, disabledClasses, true, false, userId, providers);
5884         for (int i = providers.size() - 1; i >= 0; i--) {
5885             removeDyingProviderLocked(null, providers.get(i), true);
5886         }
5887
5888         // Clean-up disabled broadcast receivers.
5889         for (int i = mBroadcastQueues.length - 1; i >= 0; i--) {
5890             mBroadcastQueues[i].cleanupDisabledPackageReceiversLocked(
5891                     packageName, disabledClasses, userId, true);
5892         }
5893
5894     }
5895
5896     final boolean forceStopPackageLocked(String packageName, int appId,
5897             boolean callerWillRestart, boolean purgeCache, boolean doit,
5898             boolean evenPersistent, boolean uninstalling, int userId, String reason) {
5899         int i;
5900
5901         if (userId == UserHandle.USER_ALL && packageName == null) {
5902             Slog.w(TAG, "Can't force stop all processes of all users, that is insane!");
5903         }
5904
5905         if (appId < 0 && packageName != null) {
5906             try {
5907                 appId = UserHandle.getAppId(
5908                         AppGlobals.getPackageManager().getPackageUid(packageName, 0));
5909             } catch (RemoteException e) {
5910             }
5911         }
5912
5913         if (doit) {
5914             if (packageName != null) {
5915                 Slog.i(TAG, "Force stopping " + packageName + " appid=" + appId
5916                         + " user=" + userId + ": " + reason);
5917             } else {
5918                 Slog.i(TAG, "Force stopping u" + userId + ": " + reason);
5919             }
5920
5921             final ArrayMap<String, SparseArray<Long>> pmap = mProcessCrashTimes.getMap();
5922             for (int ip = pmap.size() - 1; ip >= 0; ip--) {
5923                 SparseArray<Long> ba = pmap.valueAt(ip);
5924                 for (i = ba.size() - 1; i >= 0; i--) {
5925                     boolean remove = false;
5926                     final int entUid = ba.keyAt(i);
5927                     if (packageName != null) {
5928                         if (userId == UserHandle.USER_ALL) {
5929                             if (UserHandle.getAppId(entUid) == appId) {
5930                                 remove = true;
5931                             }
5932                         } else {
5933                             if (entUid == UserHandle.getUid(userId, appId)) {
5934                                 remove = true;
5935                             }
5936                         }
5937                     } else if (UserHandle.getUserId(entUid) == userId) {
5938                         remove = true;
5939                     }
5940                     if (remove) {
5941                         ba.removeAt(i);
5942                     }
5943                 }
5944                 if (ba.size() == 0) {
5945                     pmap.removeAt(ip);
5946                 }
5947             }
5948         }
5949
5950         boolean didSomething = killPackageProcessesLocked(packageName, appId, userId,
5951                 ProcessList.INVALID_ADJ, callerWillRestart, true, doit, evenPersistent,
5952                 packageName == null ? ("stop user " + userId) : ("stop " + packageName));
5953
5954         if (mStackSupervisor.finishDisabledPackageActivitiesLocked(
5955                 packageName, null, doit, evenPersistent, userId)) {
5956             if (!doit) {
5957                 return true;
5958             }
5959             didSomething = true;
5960         }
5961
5962         if (mServices.bringDownDisabledPackageServicesLocked(
5963                 packageName, null, userId, evenPersistent, true, doit)) {
5964             if (!doit) {
5965                 return true;
5966             }
5967             didSomething = true;
5968         }
5969
5970         if (packageName == null) {
5971             // Remove all sticky broadcasts from this user.
5972             mStickyBroadcasts.remove(userId);
5973         }
5974
5975         ArrayList<ContentProviderRecord> providers = new ArrayList<>();
5976         if (mProviderMap.collectPackageProvidersLocked(packageName, null, doit, evenPersistent,
5977                 userId, providers)) {
5978             if (!doit) {
5979                 return true;
5980             }
5981             didSomething = true;
5982         }
5983         for (i = providers.size() - 1; i >= 0; i--) {
5984             removeDyingProviderLocked(null, providers.get(i), true);
5985         }
5986
5987         // Remove transient permissions granted from/to this package/user
5988         removeUriPermissionsForPackageLocked(packageName, userId, false);
5989
5990         if (doit) {
5991             for (i = mBroadcastQueues.length - 1; i >= 0; i--) {
5992                 didSomething |= mBroadcastQueues[i].cleanupDisabledPackageReceiversLocked(
5993                         packageName, null, userId, doit);
5994             }
5995         }
5996
5997         if (packageName == null || uninstalling) {
5998             // Remove pending intents.  For now we only do this when force
5999             // stopping users, because we have some problems when doing this
6000             // for packages -- app widgets are not currently cleaned up for
6001             // such packages, so they can be left with bad pending intents.
6002             if (mIntentSenderRecords.size() > 0) {
6003                 Iterator<WeakReference<PendingIntentRecord>> it
6004                         = mIntentSenderRecords.values().iterator();
6005                 while (it.hasNext()) {
6006                     WeakReference<PendingIntentRecord> wpir = it.next();
6007                     if (wpir == null) {
6008                         it.remove();
6009                         continue;
6010                     }
6011                     PendingIntentRecord pir = wpir.get();
6012                     if (pir == null) {
6013                         it.remove();
6014                         continue;
6015                     }
6016                     if (packageName == null) {
6017                         // Stopping user, remove all objects for the user.
6018                         if (pir.key.userId != userId) {
6019                             // Not the same user, skip it.
6020                             continue;
6021                         }
6022                     } else {
6023                         if (UserHandle.getAppId(pir.uid) != appId) {
6024                             // Different app id, skip it.
6025                             continue;
6026                         }
6027                         if (userId != UserHandle.USER_ALL && pir.key.userId != userId) {
6028                             // Different user, skip it.
6029                             continue;
6030                         }
6031                         if (!pir.key.packageName.equals(packageName)) {
6032                             // Different package, skip it.
6033                             continue;
6034                         }
6035                     }
6036                     if (!doit) {
6037                         return true;
6038                     }
6039                     didSomething = true;
6040                     it.remove();
6041                     pir.canceled = true;
6042                     if (pir.key.activity != null && pir.key.activity.pendingResults != null) {
6043                         pir.key.activity.pendingResults.remove(pir.ref);
6044                     }
6045                 }
6046             }
6047         }
6048
6049         if (doit) {
6050             if (purgeCache && packageName != null) {
6051                 AttributeCache ac = AttributeCache.instance();
6052                 if (ac != null) {
6053                     ac.removePackage(packageName);
6054                 }
6055             }
6056             if (mBooted) {
6057                 mStackSupervisor.resumeTopActivitiesLocked();
6058                 mStackSupervisor.scheduleIdleLocked();
6059             }
6060         }
6061
6062         return didSomething;
6063     }
6064
6065     private final ProcessRecord removeProcessNameLocked(final String name, final int uid) {
6066         ProcessRecord old = mProcessNames.remove(name, uid);
6067         if (old != null) {
6068             old.uidRecord.numProcs--;
6069             if (old.uidRecord.numProcs == 0) {
6070                 // No more processes using this uid, tell clients it is gone.
6071                 if (DEBUG_UID_OBSERVERS) Slog.i(TAG_UID_OBSERVERS,
6072                         "No more processes in " + old.uidRecord);
6073                 enqueueUidChangeLocked(old.uidRecord, -1, UidRecord.CHANGE_GONE);
6074                 mActiveUids.remove(uid);
6075             }
6076             old.uidRecord = null;
6077         }
6078         mIsolatedProcesses.remove(uid);
6079         return old;
6080     }
6081
6082     private final void addProcessNameLocked(ProcessRecord proc) {
6083         // We shouldn't already have a process under this name, but just in case we
6084         // need to clean up whatever may be there now.
6085         ProcessRecord old = removeProcessNameLocked(proc.processName, proc.uid);
6086         if (old == proc && proc.persistent) {
6087             // We are re-adding a persistent process.  Whatevs!  Just leave it there.
6088             Slog.w(TAG, "Re-adding persistent process " + proc);
6089         } else if (old != null) {
6090             Slog.wtf(TAG, "Already have existing proc " + old + " when adding " + proc);
6091         }
6092         UidRecord uidRec = mActiveUids.get(proc.uid);
6093         if (uidRec == null) {
6094             uidRec = new UidRecord(proc.uid);
6095             // This is the first appearance of the uid, report it now!
6096             if (DEBUG_UID_OBSERVERS) Slog.i(TAG_UID_OBSERVERS,
6097                     "Creating new process uid: " + uidRec);
6098             mActiveUids.put(proc.uid, uidRec);
6099             enqueueUidChangeLocked(uidRec, -1, UidRecord.CHANGE_ACTIVE);
6100         }
6101         proc.uidRecord = uidRec;
6102         uidRec.numProcs++;
6103         mProcessNames.put(proc.processName, proc.uid, proc);
6104         if (proc.isolated) {
6105             mIsolatedProcesses.put(proc.uid, proc);
6106         }
6107     }
6108
6109     private final boolean removeProcessLocked(ProcessRecord app,
6110             boolean callerWillRestart, boolean allowRestart, String reason) {
6111         final String name = app.processName;
6112         final int uid = app.uid;
6113         if (DEBUG_PROCESSES) Slog.d(TAG_PROCESSES,
6114             "Force removing proc " + app.toShortString() + " (" + name + "/" + uid + ")");
6115
6116         removeProcessNameLocked(name, uid);
6117         if (mHeavyWeightProcess == app) {
6118             mHandler.sendMessage(mHandler.obtainMessage(CANCEL_HEAVY_NOTIFICATION_MSG,
6119                     mHeavyWeightProcess.userId, 0));
6120             mHeavyWeightProcess = null;
6121         }
6122         boolean needRestart = false;
6123         if (app.pid > 0 && app.pid != MY_PID) {
6124             int pid = app.pid;
6125             synchronized (mPidsSelfLocked) {
6126                 mPidsSelfLocked.remove(pid);
6127                 mHandler.removeMessages(PROC_START_TIMEOUT_MSG, app);
6128             }
6129             mBatteryStatsService.noteProcessFinish(app.processName, app.info.uid);
6130             if (app.isolated) {
6131                 mBatteryStatsService.removeIsolatedUid(app.uid, app.info.uid);
6132             }
6133             boolean willRestart = false;
6134             if (app.persistent && !app.isolated) {
6135                 if (!callerWillRestart) {
6136                     willRestart = true;
6137                 } else {
6138                     needRestart = true;
6139                 }
6140             }
6141             app.kill(reason, true);
6142             handleAppDiedLocked(app, willRestart, allowRestart);
6143             if (willRestart) {
6144                 removeLruProcessLocked(app);
6145                 addAppLocked(app.info, false, null /* ABI override */);
6146             }
6147         } else {
6148             mRemovedProcesses.add(app);
6149         }
6150
6151         return needRestart;
6152     }
6153
6154     private final void processContentProviderPublishTimedOutLocked(ProcessRecord app) {
6155         cleanupAppInLaunchingProvidersLocked(app, true);
6156         removeProcessLocked(app, false, true, "timeout publishing content providers");
6157     }
6158
6159     private final void processStartTimedOutLocked(ProcessRecord app) {
6160         final int pid = app.pid;
6161         boolean gone = false;
6162         synchronized (mPidsSelfLocked) {
6163             ProcessRecord knownApp = mPidsSelfLocked.get(pid);
6164             if (knownApp != null && knownApp.thread == null) {
6165                 mPidsSelfLocked.remove(pid);
6166                 gone = true;
6167             }
6168         }
6169
6170         if (gone) {
6171             Slog.w(TAG, "Process " + app + " failed to attach");
6172             EventLog.writeEvent(EventLogTags.AM_PROCESS_START_TIMEOUT, app.userId,
6173                     pid, app.uid, app.processName);
6174             removeProcessNameLocked(app.processName, app.uid);
6175             if (mHeavyWeightProcess == app) {
6176                 mHandler.sendMessage(mHandler.obtainMessage(CANCEL_HEAVY_NOTIFICATION_MSG,
6177                         mHeavyWeightProcess.userId, 0));
6178                 mHeavyWeightProcess = null;
6179             }
6180             mBatteryStatsService.noteProcessFinish(app.processName, app.info.uid);
6181             if (app.isolated) {
6182                 mBatteryStatsService.removeIsolatedUid(app.uid, app.info.uid);
6183             }
6184             // Take care of any launching providers waiting for this process.
6185             cleanupAppInLaunchingProvidersLocked(app, true);
6186             // Take care of any services that are waiting for the process.
6187             mServices.processStartTimedOutLocked(app);
6188             app.kill("start timeout", true);
6189             removeLruProcessLocked(app);
6190             if (mBackupTarget != null && mBackupTarget.app.pid == pid) {
6191                 Slog.w(TAG, "Unattached app died before backup, skipping");
6192                 try {
6193                     IBackupManager bm = IBackupManager.Stub.asInterface(
6194                             ServiceManager.getService(Context.BACKUP_SERVICE));
6195                     bm.agentDisconnected(app.info.packageName);
6196                 } catch (RemoteException e) {
6197                     // Can't happen; the backup manager is local
6198                 }
6199             }
6200             if (isPendingBroadcastProcessLocked(pid)) {
6201                 Slog.w(TAG, "Unattached app died before broadcast acknowledged, skipping");
6202                 skipPendingBroadcastLocked(pid);
6203             }
6204         } else {
6205             Slog.w(TAG, "Spurious process start timeout - pid not known for " + app);
6206         }
6207     }
6208
6209     private final boolean attachApplicationLocked(IApplicationThread thread,
6210             int pid) {
6211
6212         // Find the application record that is being attached...  either via
6213         // the pid if we are running in multiple processes, or just pull the
6214         // next app record if we are emulating process with anonymous threads.
6215         ProcessRecord app;
6216         if (pid != MY_PID && pid >= 0) {
6217             synchronized (mPidsSelfLocked) {
6218                 app = mPidsSelfLocked.get(pid);
6219             }
6220         } else {
6221             app = null;
6222         }
6223
6224         if (app == null) {
6225             Slog.w(TAG, "No pending application record for pid " + pid
6226                     + " (IApplicationThread " + thread + "); dropping process");
6227             EventLog.writeEvent(EventLogTags.AM_DROP_PROCESS, pid);
6228             if (pid > 0 && pid != MY_PID) {
6229                 Process.killProcessQuiet(pid);
6230                 //TODO: killProcessGroup(app.info.uid, pid);
6231             } else {
6232                 try {
6233                     thread.scheduleExit();
6234                 } catch (Exception e) {
6235                     // Ignore exceptions.
6236                 }
6237             }
6238             return false;
6239         }
6240
6241         // If this application record is still attached to a previous
6242         // process, clean it up now.
6243         if (app.thread != null) {
6244             handleAppDiedLocked(app, true, true);
6245         }
6246
6247         // Tell the process all about itself.
6248
6249         if (DEBUG_ALL) Slog.v(
6250                 TAG, "Binding process pid " + pid + " to record " + app);
6251
6252         final String processName = app.processName;
6253         try {
6254             AppDeathRecipient adr = new AppDeathRecipient(
6255                     app, pid, thread);
6256             thread.asBinder().linkToDeath(adr, 0);
6257             app.deathRecipient = adr;
6258         } catch (RemoteException e) {
6259             app.resetPackageList(mProcessStats);
6260             startProcessLocked(app, "link fail", processName);
6261             return false;
6262         }
6263
6264         EventLog.writeEvent(EventLogTags.AM_PROC_BOUND, app.userId, app.pid, app.processName);
6265
6266         app.makeActive(thread, mProcessStats);
6267         app.curAdj = app.setAdj = ProcessList.INVALID_ADJ;
6268         app.curSchedGroup = app.setSchedGroup = Process.THREAD_GROUP_DEFAULT;
6269         app.forcingToForeground = null;
6270         updateProcessForegroundLocked(app, false, false);
6271         app.hasShownUi = false;
6272         app.debugging = false;
6273         app.cached = false;
6274         app.killedByAm = false;
6275
6276         mHandler.removeMessages(PROC_START_TIMEOUT_MSG, app);
6277
6278         boolean normalMode = mProcessesReady || isAllowedWhileBooting(app.info);
6279         List<ProviderInfo> providers = normalMode ? generateApplicationProvidersLocked(app) : null;
6280
6281         if (providers != null && checkAppInLaunchingProvidersLocked(app)) {
6282             Message msg = mHandler.obtainMessage(CONTENT_PROVIDER_PUBLISH_TIMEOUT_MSG);
6283             msg.obj = app;
6284             mHandler.sendMessageDelayed(msg, CONTENT_PROVIDER_PUBLISH_TIMEOUT);
6285         }
6286
6287         if (!normalMode) {
6288             Slog.i(TAG, "Launching preboot mode app: " + app);
6289         }
6290
6291         if (DEBUG_ALL) Slog.v(
6292             TAG, "New app record " + app
6293             + " thread=" + thread.asBinder() + " pid=" + pid);
6294         try {
6295             int testMode = IApplicationThread.DEBUG_OFF;
6296             if (mDebugApp != null && mDebugApp.equals(processName)) {
6297                 testMode = mWaitForDebugger
6298                     ? IApplicationThread.DEBUG_WAIT
6299                     : IApplicationThread.DEBUG_ON;
6300                 app.debugging = true;
6301                 if (mDebugTransient) {
6302                     mDebugApp = mOrigDebugApp;
6303                     mWaitForDebugger = mOrigWaitForDebugger;
6304                 }
6305             }
6306             String profileFile = app.instrumentationProfileFile;
6307             ParcelFileDescriptor profileFd = null;
6308             int samplingInterval = 0;
6309             boolean profileAutoStop = false;
6310             if (mProfileApp != null && mProfileApp.equals(processName)) {
6311                 mProfileProc = app;
6312                 profileFile = mProfileFile;
6313                 profileFd = mProfileFd;
6314                 samplingInterval = mSamplingInterval;
6315                 profileAutoStop = mAutoStopProfiler;
6316             }
6317             boolean enableTrackAllocation = false;
6318             if (mTrackAllocationApp != null && mTrackAllocationApp.equals(processName)) {
6319                 enableTrackAllocation = true;
6320                 mTrackAllocationApp = null;
6321             }
6322
6323             // If the app is being launched for restore or full backup, set it up specially
6324             boolean isRestrictedBackupMode = false;
6325             if (mBackupTarget != null && mBackupAppName.equals(processName)) {
6326                 isRestrictedBackupMode = (mBackupTarget.backupMode == BackupRecord.RESTORE)
6327                         || (mBackupTarget.backupMode == BackupRecord.RESTORE_FULL)
6328                         || (mBackupTarget.backupMode == BackupRecord.BACKUP_FULL);
6329             }
6330
6331             notifyPackageUse(app.instrumentationInfo != null
6332                     ? app.instrumentationInfo.packageName
6333                     : app.info.packageName);
6334             if (app.instrumentationClass != null) {
6335                 notifyPackageUse(app.instrumentationClass.getPackageName());
6336             }
6337             if (DEBUG_CONFIGURATION) Slog.v(TAG_CONFIGURATION, "Binding proc "
6338                     + processName + " with config " + mConfiguration);
6339             ApplicationInfo appInfo = app.instrumentationInfo != null
6340                     ? app.instrumentationInfo : app.info;
6341             app.compat = compatibilityInfoForPackageLocked(appInfo);
6342             if (profileFd != null) {
6343                 profileFd = profileFd.dup();
6344             }
6345             ProfilerInfo profilerInfo = profileFile == null ? null
6346                     : new ProfilerInfo(profileFile, profileFd, samplingInterval, profileAutoStop);
6347             thread.bindApplication(processName, appInfo, providers, app.instrumentationClass,
6348                     profilerInfo, app.instrumentationArguments, app.instrumentationWatcher,
6349                     app.instrumentationUiAutomationConnection, testMode,
6350                     mBinderTransactionTrackingEnabled, enableTrackAllocation,
6351                     isRestrictedBackupMode || !normalMode, app.persistent,
6352                     new Configuration(mConfiguration), app.compat,
6353                     getCommonServicesLocked(app.isolated),
6354                     mCoreSettingsObserver.getCoreSettingsLocked());
6355             updateLruProcessLocked(app, false, null);
6356             app.lastRequestedGc = app.lastLowMemory = SystemClock.uptimeMillis();
6357         } catch (Exception e) {
6358             // todo: Yikes!  What should we do?  For now we will try to
6359             // start another process, but that could easily get us in
6360             // an infinite loop of restarting processes...
6361             Slog.wtf(TAG, "Exception thrown during bind of " + app, e);
6362
6363             app.resetPackageList(mProcessStats);
6364             app.unlinkDeathRecipient();
6365             startProcessLocked(app, "bind fail", processName);
6366             return false;
6367         }
6368
6369         // Remove this record from the list of starting applications.
6370         mPersistentStartingProcesses.remove(app);
6371         if (DEBUG_PROCESSES && mProcessesOnHold.contains(app)) Slog.v(TAG_PROCESSES,
6372                 "Attach application locked removing on hold: " + app);
6373         mProcessesOnHold.remove(app);
6374
6375         boolean badApp = false;
6376         boolean didSomething = false;
6377
6378         // See if the top visible activity is waiting to run in this process...
6379         if (normalMode) {
6380             try {
6381                 if (mStackSupervisor.attachApplicationLocked(app)) {
6382                     didSomething = true;
6383                 }
6384             } catch (Exception e) {
6385                 Slog.wtf(TAG, "Exception thrown launching activities in " + app, e);
6386                 badApp = true;
6387             }
6388         }
6389
6390         // Find any services that should be running in this process...
6391         if (!badApp) {
6392             try {
6393                 didSomething |= mServices.attachApplicationLocked(app, processName);
6394             } catch (Exception e) {
6395                 Slog.wtf(TAG, "Exception thrown starting services in " + app, e);
6396                 badApp = true;
6397             }
6398         }
6399
6400         // Check if a next-broadcast receiver is in this process...
6401         if (!badApp && isPendingBroadcastProcessLocked(pid)) {
6402             try {
6403                 didSomething |= sendPendingBroadcastsLocked(app);
6404             } catch (Exception e) {
6405                 // If the app died trying to launch the receiver we declare it 'bad'
6406                 Slog.wtf(TAG, "Exception thrown dispatching broadcasts in " + app, e);
6407                 badApp = true;
6408             }
6409         }
6410
6411         // Check whether the next backup agent is in this process...
6412         if (!badApp && mBackupTarget != null && mBackupTarget.appInfo.uid == app.uid) {
6413             if (DEBUG_BACKUP) Slog.v(TAG_BACKUP,
6414                     "New app is backup target, launching agent for " + app);
6415             notifyPackageUse(mBackupTarget.appInfo.packageName);
6416             try {
6417                 thread.scheduleCreateBackupAgent(mBackupTarget.appInfo,
6418                         compatibilityInfoForPackageLocked(mBackupTarget.appInfo),
6419                         mBackupTarget.backupMode);
6420             } catch (Exception e) {
6421                 Slog.wtf(TAG, "Exception thrown creating backup agent in " + app, e);
6422                 badApp = true;
6423             }
6424         }
6425
6426         if (badApp) {
6427             app.kill("error during init", true);
6428             handleAppDiedLocked(app, false, true);
6429             return false;
6430         }
6431
6432         if (!didSomething) {
6433             updateOomAdjLocked();
6434         }
6435
6436         return true;
6437     }
6438
6439     @Override
6440     public final void attachApplication(IApplicationThread thread) {
6441         synchronized (this) {
6442             int callingPid = Binder.getCallingPid();
6443             final long origId = Binder.clearCallingIdentity();
6444             attachApplicationLocked(thread, callingPid);
6445             Binder.restoreCallingIdentity(origId);
6446         }
6447     }
6448
6449     @Override
6450     public final void activityIdle(IBinder token, Configuration config, boolean stopProfiling) {
6451         final long origId = Binder.clearCallingIdentity();
6452         synchronized (this) {
6453             ActivityStack stack = ActivityRecord.getStackLocked(token);
6454             if (stack != null) {
6455                 ActivityRecord r =
6456                         mStackSupervisor.activityIdleInternalLocked(token, false, config);
6457                 if (stopProfiling) {
6458                     if ((mProfileProc == r.app) && (mProfileFd != null)) {
6459                         try {
6460                             mProfileFd.close();
6461                         } catch (IOException e) {
6462                         }
6463                         clearProfilerLocked();
6464                     }
6465                 }
6466             }
6467         }
6468         Binder.restoreCallingIdentity(origId);
6469     }
6470
6471     void postFinishBooting(boolean finishBooting, boolean enableScreen) {
6472         mHandler.sendMessage(mHandler.obtainMessage(FINISH_BOOTING_MSG,
6473                 finishBooting ? 1 : 0, enableScreen ? 1 : 0));
6474     }
6475
6476     void enableScreenAfterBoot() {
6477         EventLog.writeEvent(EventLogTags.BOOT_PROGRESS_ENABLE_SCREEN,
6478                 SystemClock.uptimeMillis());
6479         mWindowManager.enableScreenAfterBoot();
6480
6481         synchronized (this) {
6482             updateEventDispatchingLocked();
6483         }
6484     }
6485
6486     @Override
6487     public void showBootMessage(final CharSequence msg, final boolean always) {
6488         if (Binder.getCallingUid() != Process.myUid()) {
6489             // These days only the core system can call this, so apps can't get in
6490             // the way of what we show about running them.
6491         }
6492         mWindowManager.showBootMessage(msg, always);
6493     }
6494
6495     @Override
6496     public void keyguardWaitingForActivityDrawn() {
6497         enforceNotIsolatedCaller("keyguardWaitingForActivityDrawn");
6498         final long token = Binder.clearCallingIdentity();
6499         try {
6500             synchronized (this) {
6501                 if (DEBUG_LOCKSCREEN) logLockScreen("");
6502                 mWindowManager.keyguardWaitingForActivityDrawn();
6503                 if (mLockScreenShown == LOCK_SCREEN_SHOWN) {
6504                     mLockScreenShown = LOCK_SCREEN_LEAVING;
6505                     updateSleepIfNeededLocked();
6506                 }
6507             }
6508         } finally {
6509             Binder.restoreCallingIdentity(token);
6510         }
6511     }
6512
6513     @Override
6514     public void keyguardGoingAway(boolean disableWindowAnimations,
6515             boolean keyguardGoingToNotificationShade) {
6516         enforceNotIsolatedCaller("keyguardGoingAway");
6517         final long token = Binder.clearCallingIdentity();
6518         try {
6519             synchronized (this) {
6520                 if (DEBUG_LOCKSCREEN) logLockScreen("");
6521                 mWindowManager.keyguardGoingAway(disableWindowAnimations,
6522                         keyguardGoingToNotificationShade);
6523                 if (mLockScreenShown == LOCK_SCREEN_SHOWN) {
6524                     mLockScreenShown = LOCK_SCREEN_HIDDEN;
6525                     updateSleepIfNeededLocked();
6526                 }
6527             }
6528         } finally {
6529             Binder.restoreCallingIdentity(token);
6530         }
6531     }
6532
6533     final void finishBooting() {
6534         synchronized (this) {
6535             if (!mBootAnimationComplete) {
6536                 mCallFinishBooting = true;
6537                 return;
6538             }
6539             mCallFinishBooting = false;
6540         }
6541
6542         ArraySet<String> completedIsas = new ArraySet<String>();
6543         for (String abi : Build.SUPPORTED_ABIS) {
6544             Process.establishZygoteConnectionForAbi(abi);
6545             final String instructionSet = VMRuntime.getInstructionSet(abi);
6546             if (!completedIsas.contains(instructionSet)) {
6547                 if (mInstaller.markBootComplete(VMRuntime.getInstructionSet(abi)) != 0) {
6548                     Slog.e(TAG, "Unable to mark boot complete for abi: " + abi);
6549                 }
6550                 completedIsas.add(instructionSet);
6551             }
6552         }
6553
6554         IntentFilter pkgFilter = new IntentFilter();
6555         pkgFilter.addAction(Intent.ACTION_QUERY_PACKAGE_RESTART);
6556         pkgFilter.addDataScheme("package");
6557         mContext.registerReceiver(new BroadcastReceiver() {
6558             @Override
6559             public void onReceive(Context context, Intent intent) {
6560                 String[] pkgs = intent.getStringArrayExtra(Intent.EXTRA_PACKAGES);
6561                 if (pkgs != null) {
6562                     for (String pkg : pkgs) {
6563                         synchronized (ActivityManagerService.this) {
6564                             if (forceStopPackageLocked(pkg, -1, false, false, false, false, false,
6565                                     0, "query restart")) {
6566                                 setResultCode(Activity.RESULT_OK);
6567                                 return;
6568                             }
6569                         }
6570                     }
6571                 }
6572             }
6573         }, pkgFilter);
6574
6575         IntentFilter dumpheapFilter = new IntentFilter();
6576         dumpheapFilter.addAction(DumpHeapActivity.ACTION_DELETE_DUMPHEAP);
6577         mContext.registerReceiver(new BroadcastReceiver() {
6578             @Override
6579             public void onReceive(Context context, Intent intent) {
6580                 if (intent.getBooleanExtra(DumpHeapActivity.EXTRA_DELAY_DELETE, false)) {
6581                     mHandler.sendEmptyMessageDelayed(POST_DUMP_HEAP_NOTIFICATION_MSG, 5*60*1000);
6582                 } else {
6583                     mHandler.sendEmptyMessage(POST_DUMP_HEAP_NOTIFICATION_MSG);
6584                 }
6585             }
6586         }, dumpheapFilter);
6587
6588         // Let system services know.
6589         mSystemServiceManager.startBootPhase(SystemService.PHASE_BOOT_COMPLETED);
6590
6591         synchronized (this) {
6592             // Ensure that any processes we had put on hold are now started
6593             // up.
6594             final int NP = mProcessesOnHold.size();
6595             if (NP > 0) {
6596                 ArrayList<ProcessRecord> procs =
6597                     new ArrayList<ProcessRecord>(mProcessesOnHold);
6598                 for (int ip=0; ip<NP; ip++) {
6599                     if (DEBUG_PROCESSES) Slog.v(TAG_PROCESSES, "Starting process on hold: "
6600                             + procs.get(ip));
6601                     startProcessLocked(procs.get(ip), "on-hold", null);
6602                 }
6603             }
6604
6605             if (mFactoryTest != FactoryTest.FACTORY_TEST_LOW_LEVEL) {
6606                 // Start looking for apps that are abusing wake locks.
6607                 Message nmsg = mHandler.obtainMessage(CHECK_EXCESSIVE_WAKE_LOCKS_MSG);
6608                 mHandler.sendMessageDelayed(nmsg, POWER_CHECK_DELAY);
6609                 // Tell anyone interested that we are done booting!
6610                 SystemProperties.set("sys.boot_completed", "1");
6611
6612                 // And trigger dev.bootcomplete if we are not showing encryption progress
6613                 if (!"trigger_restart_min_framework".equals(SystemProperties.get("vold.decrypt"))
6614                     || "".equals(SystemProperties.get("vold.encrypt_progress"))) {
6615                     SystemProperties.set("dev.bootcomplete", "1");
6616                 }
6617                 mUserController.sendBootCompletedLocked(
6618                         new IIntentReceiver.Stub() {
6619                             @Override
6620                             public void performReceive(Intent intent, int resultCode,
6621                                     String data, Bundle extras, boolean ordered,
6622                                     boolean sticky, int sendingUser) {
6623                                 synchronized (ActivityManagerService.this) {
6624                                     requestPssAllProcsLocked(SystemClock.uptimeMillis(),
6625                                             true, false);
6626                                 }
6627                             }
6628                         });
6629                 scheduleStartProfilesLocked();
6630             }
6631         }
6632     }
6633
6634     @Override
6635     public void bootAnimationComplete() {
6636         final boolean callFinishBooting;
6637         synchronized (this) {
6638             callFinishBooting = mCallFinishBooting;
6639             mBootAnimationComplete = true;
6640         }
6641         if (callFinishBooting) {
6642             Trace.traceBegin(Trace.TRACE_TAG_ACTIVITY_MANAGER, "FinishBooting");
6643             finishBooting();
6644             Trace.traceEnd(Trace.TRACE_TAG_ACTIVITY_MANAGER);
6645         }
6646     }
6647
6648     final void ensureBootCompleted() {
6649         boolean booting;
6650         boolean enableScreen;
6651         synchronized (this) {
6652             booting = mBooting;
6653             mBooting = false;
6654             enableScreen = !mBooted;
6655             mBooted = true;
6656         }
6657
6658         if (booting) {
6659             Trace.traceBegin(Trace.TRACE_TAG_ACTIVITY_MANAGER, "FinishBooting");
6660             finishBooting();
6661             Trace.traceEnd(Trace.TRACE_TAG_ACTIVITY_MANAGER);
6662         }
6663
6664         if (enableScreen) {
6665             enableScreenAfterBoot();
6666         }
6667     }
6668
6669     @Override
6670     public final void activityResumed(IBinder token) {
6671         final long origId = Binder.clearCallingIdentity();
6672         synchronized(this) {
6673             ActivityStack stack = ActivityRecord.getStackLocked(token);
6674             if (stack != null) {
6675                 ActivityRecord.activityResumedLocked(token);
6676             }
6677         }
6678         Binder.restoreCallingIdentity(origId);
6679     }
6680
6681     @Override
6682     public final void activityPaused(IBinder token) {
6683         final long origId = Binder.clearCallingIdentity();
6684         synchronized(this) {
6685             ActivityStack stack = ActivityRecord.getStackLocked(token);
6686             if (stack != null) {
6687                 stack.activityPausedLocked(token, false);
6688             }
6689         }
6690         Binder.restoreCallingIdentity(origId);
6691     }
6692
6693     @Override
6694     public final void activityStopped(IBinder token, Bundle icicle,
6695             PersistableBundle persistentState, CharSequence description) {
6696         if (DEBUG_ALL) Slog.v(TAG, "Activity stopped: token=" + token);
6697
6698         // Refuse possible leaked file descriptors
6699         if (icicle != null && icicle.hasFileDescriptors()) {
6700             throw new IllegalArgumentException("File descriptors passed in Bundle");
6701         }
6702
6703         final long origId = Binder.clearCallingIdentity();
6704
6705         synchronized (this) {
6706             ActivityRecord r = ActivityRecord.isInStackLocked(token);
6707             if (r != null) {
6708                 r.task.stack.activityStoppedLocked(r, icicle, persistentState, description);
6709             }
6710         }
6711
6712         trimApplications();
6713
6714         Binder.restoreCallingIdentity(origId);
6715     }
6716
6717     @Override
6718     public final void activityDestroyed(IBinder token) {
6719         if (DEBUG_SWITCH) Slog.v(TAG_SWITCH, "ACTIVITY DESTROYED: " + token);
6720         synchronized (this) {
6721             ActivityStack stack = ActivityRecord.getStackLocked(token);
6722             if (stack != null) {
6723                 stack.activityDestroyedLocked(token, "activityDestroyed");
6724             }
6725         }
6726     }
6727
6728     @Override
6729     public void reportSizeConfigurations(IBinder token, int[] horizontalSizeConfiguration,
6730             int[] verticalSizeConfigurations, int[] smallestSizeConfigurations) {
6731         if (DEBUG_CONFIGURATION) Slog.v(TAG, "Report configuration: " + token + " "
6732                 + horizontalSizeConfiguration + " " + verticalSizeConfigurations);
6733         synchronized (this) {
6734             ActivityRecord record = ActivityRecord.isInStackLocked(token);
6735             if (record == null) {
6736                 throw new IllegalArgumentException("reportSizeConfigurations: ActivityRecord not "
6737                         + "found for: " + token);
6738             }
6739             record.setSizeConfigurations(horizontalSizeConfiguration,
6740                     verticalSizeConfigurations, smallestSizeConfigurations);
6741         }
6742     }
6743
6744     @Override
6745     public final void backgroundResourcesReleased(IBinder token) {
6746         final long origId = Binder.clearCallingIdentity();
6747         try {
6748             synchronized (this) {
6749                 ActivityStack stack = ActivityRecord.getStackLocked(token);
6750                 if (stack != null) {
6751                     stack.backgroundResourcesReleased();
6752                 }
6753             }
6754         } finally {
6755             Binder.restoreCallingIdentity(origId);
6756         }
6757     }
6758
6759     @Override
6760     public final void notifyLaunchTaskBehindComplete(IBinder token) {
6761         mStackSupervisor.scheduleLaunchTaskBehindComplete(token);
6762     }
6763
6764     @Override
6765     public final void notifyEnterAnimationComplete(IBinder token) {
6766         mHandler.sendMessage(mHandler.obtainMessage(ENTER_ANIMATION_COMPLETE_MSG, token));
6767     }
6768
6769     @Override
6770     public String getCallingPackage(IBinder token) {
6771         synchronized (this) {
6772             ActivityRecord r = getCallingRecordLocked(token);
6773             return r != null ? r.info.packageName : null;
6774         }
6775     }
6776
6777     @Override
6778     public ComponentName getCallingActivity(IBinder token) {
6779         synchronized (this) {
6780             ActivityRecord r = getCallingRecordLocked(token);
6781             return r != null ? r.intent.getComponent() : null;
6782         }
6783     }
6784
6785     private ActivityRecord getCallingRecordLocked(IBinder token) {
6786         ActivityRecord r = ActivityRecord.isInStackLocked(token);
6787         if (r == null) {
6788             return null;
6789         }
6790         return r.resultTo;
6791     }
6792
6793     @Override
6794     public ComponentName getActivityClassForToken(IBinder token) {
6795         synchronized(this) {
6796             ActivityRecord r = ActivityRecord.isInStackLocked(token);
6797             if (r == null) {
6798                 return null;
6799             }
6800             return r.intent.getComponent();
6801         }
6802     }
6803
6804     @Override
6805     public String getPackageForToken(IBinder token) {
6806         synchronized(this) {
6807             ActivityRecord r = ActivityRecord.isInStackLocked(token);
6808             if (r == null) {
6809                 return null;
6810             }
6811             return r.packageName;
6812         }
6813     }
6814
6815     @Override
6816     public boolean isRootVoiceInteraction(IBinder token) {
6817         synchronized(this) {
6818             ActivityRecord r = ActivityRecord.isInStackLocked(token);
6819             if (r == null) {
6820                 return false;
6821             }
6822             return r.rootVoiceInteraction;
6823         }
6824     }
6825
6826     @Override
6827     public IIntentSender getIntentSender(int type,
6828             String packageName, IBinder token, String resultWho,
6829             int requestCode, Intent[] intents, String[] resolvedTypes,
6830             int flags, Bundle bOptions, int userId) {
6831         enforceNotIsolatedCaller("getIntentSender");
6832         // Refuse possible leaked file descriptors
6833         if (intents != null) {
6834             if (intents.length < 1) {
6835                 throw new IllegalArgumentException("Intents array length must be >= 1");
6836             }
6837             for (int i=0; i<intents.length; i++) {
6838                 Intent intent = intents[i];
6839                 if (intent != null) {
6840                     if (intent.hasFileDescriptors()) {
6841                         throw new IllegalArgumentException("File descriptors passed in Intent");
6842                     }
6843                     if (type == ActivityManager.INTENT_SENDER_BROADCAST &&
6844                             (intent.getFlags()&Intent.FLAG_RECEIVER_BOOT_UPGRADE) != 0) {
6845                         throw new IllegalArgumentException(
6846                                 "Can't use FLAG_RECEIVER_BOOT_UPGRADE here");
6847                     }
6848                     intents[i] = new Intent(intent);
6849                 }
6850             }
6851             if (resolvedTypes != null && resolvedTypes.length != intents.length) {
6852                 throw new IllegalArgumentException(
6853                         "Intent array length does not match resolvedTypes length");
6854             }
6855         }
6856         if (bOptions != null) {
6857             if (bOptions.hasFileDescriptors()) {
6858                 throw new IllegalArgumentException("File descriptors passed in options");
6859             }
6860         }
6861
6862         synchronized(this) {
6863             int callingUid = Binder.getCallingUid();
6864             int origUserId = userId;
6865             userId = mUserController.handleIncomingUser(Binder.getCallingPid(), callingUid, userId,
6866                     type == ActivityManager.INTENT_SENDER_BROADCAST,
6867                     ALLOW_NON_FULL, "getIntentSender", null);
6868             if (origUserId == UserHandle.USER_CURRENT) {
6869                 // We don't want to evaluate this until the pending intent is
6870                 // actually executed.  However, we do want to always do the
6871                 // security checking for it above.
6872                 userId = UserHandle.USER_CURRENT;
6873             }
6874             try {
6875                 if (callingUid != 0 && callingUid != Process.SYSTEM_UID) {
6876                     int uid = AppGlobals.getPackageManager()
6877                             .getPackageUid(packageName, UserHandle.getUserId(callingUid));
6878                     if (!UserHandle.isSameApp(callingUid, uid)) {
6879                         String msg = "Permission Denial: getIntentSender() from pid="
6880                             + Binder.getCallingPid()
6881                             + ", uid=" + Binder.getCallingUid()
6882                             + ", (need uid=" + uid + ")"
6883                             + " is not allowed to send as package " + packageName;
6884                         Slog.w(TAG, msg);
6885                         throw new SecurityException(msg);
6886                     }
6887                 }
6888
6889                 return getIntentSenderLocked(type, packageName, callingUid, userId,
6890                         token, resultWho, requestCode, intents, resolvedTypes, flags, bOptions);
6891
6892             } catch (RemoteException e) {
6893                 throw new SecurityException(e);
6894             }
6895         }
6896     }
6897
6898     IIntentSender getIntentSenderLocked(int type, String packageName,
6899             int callingUid, int userId, IBinder token, String resultWho,
6900             int requestCode, Intent[] intents, String[] resolvedTypes, int flags,
6901             Bundle bOptions) {
6902         if (DEBUG_MU) Slog.v(TAG_MU, "getIntentSenderLocked(): uid=" + callingUid);
6903         ActivityRecord activity = null;
6904         if (type == ActivityManager.INTENT_SENDER_ACTIVITY_RESULT) {
6905             activity = ActivityRecord.isInStackLocked(token);
6906             if (activity == null) {
6907                 Slog.w(TAG, "Failed createPendingResult: activity " + token + " not in any stack");
6908                 return null;
6909             }
6910             if (activity.finishing) {
6911                 Slog.w(TAG, "Failed createPendingResult: activity " + activity + " is finishing");
6912                 return null;
6913             }
6914         }
6915
6916         final boolean noCreate = (flags&PendingIntent.FLAG_NO_CREATE) != 0;
6917         final boolean cancelCurrent = (flags&PendingIntent.FLAG_CANCEL_CURRENT) != 0;
6918         final boolean updateCurrent = (flags&PendingIntent.FLAG_UPDATE_CURRENT) != 0;
6919         flags &= ~(PendingIntent.FLAG_NO_CREATE|PendingIntent.FLAG_CANCEL_CURRENT
6920                 |PendingIntent.FLAG_UPDATE_CURRENT);
6921
6922         PendingIntentRecord.Key key = new PendingIntentRecord.Key(
6923                 type, packageName, activity, resultWho,
6924                 requestCode, intents, resolvedTypes, flags, bOptions, userId);
6925         WeakReference<PendingIntentRecord> ref;
6926         ref = mIntentSenderRecords.get(key);
6927         PendingIntentRecord rec = ref != null ? ref.get() : null;
6928         if (rec != null) {
6929             if (!cancelCurrent) {
6930                 if (updateCurrent) {
6931                     if (rec.key.requestIntent != null) {
6932                         rec.key.requestIntent.replaceExtras(intents != null ?
6933                                 intents[intents.length - 1] : null);
6934                     }
6935                     if (intents != null) {
6936                         intents[intents.length-1] = rec.key.requestIntent;
6937                         rec.key.allIntents = intents;
6938                         rec.key.allResolvedTypes = resolvedTypes;
6939                     } else {
6940                         rec.key.allIntents = null;
6941                         rec.key.allResolvedTypes = null;
6942                     }
6943                 }
6944                 return rec;
6945             }
6946             rec.canceled = true;
6947             mIntentSenderRecords.remove(key);
6948         }
6949         if (noCreate) {
6950             return rec;
6951         }
6952         rec = new PendingIntentRecord(this, key, callingUid);
6953         mIntentSenderRecords.put(key, rec.ref);
6954         if (type == ActivityManager.INTENT_SENDER_ACTIVITY_RESULT) {
6955             if (activity.pendingResults == null) {
6956                 activity.pendingResults
6957                         = new HashSet<WeakReference<PendingIntentRecord>>();
6958             }
6959             activity.pendingResults.add(rec.ref);
6960         }
6961         return rec;
6962     }
6963
6964     @Override
6965     public void cancelIntentSender(IIntentSender sender) {
6966         if (!(sender instanceof PendingIntentRecord)) {
6967             return;
6968         }
6969         synchronized(this) {
6970             PendingIntentRecord rec = (PendingIntentRecord)sender;
6971             try {
6972                 int uid = AppGlobals.getPackageManager()
6973                         .getPackageUid(rec.key.packageName, UserHandle.getCallingUserId());
6974                 if (!UserHandle.isSameApp(uid, Binder.getCallingUid())) {
6975                     String msg = "Permission Denial: cancelIntentSender() from pid="
6976                         + Binder.getCallingPid()
6977                         + ", uid=" + Binder.getCallingUid()
6978                         + " is not allowed to cancel packges "
6979                         + rec.key.packageName;
6980                     Slog.w(TAG, msg);
6981                     throw new SecurityException(msg);
6982                 }
6983             } catch (RemoteException e) {
6984                 throw new SecurityException(e);
6985             }
6986             cancelIntentSenderLocked(rec, true);
6987         }
6988     }
6989
6990     void cancelIntentSenderLocked(PendingIntentRecord rec, boolean cleanActivity) {
6991         rec.canceled = true;
6992         mIntentSenderRecords.remove(rec.key);
6993         if (cleanActivity && rec.key.activity != null) {
6994             rec.key.activity.pendingResults.remove(rec.ref);
6995         }
6996     }
6997
6998     @Override
6999     public String getPackageForIntentSender(IIntentSender pendingResult) {
7000         if (!(pendingResult instanceof PendingIntentRecord)) {
7001             return null;
7002         }
7003         try {
7004             PendingIntentRecord res = (PendingIntentRecord)pendingResult;
7005             return res.key.packageName;
7006         } catch (ClassCastException e) {
7007         }
7008         return null;
7009     }
7010
7011     @Override
7012     public int getUidForIntentSender(IIntentSender sender) {
7013         if (sender instanceof PendingIntentRecord) {
7014             try {
7015                 PendingIntentRecord res = (PendingIntentRecord)sender;
7016                 return res.uid;
7017             } catch (ClassCastException e) {
7018             }
7019         }
7020         return -1;
7021     }
7022
7023     @Override
7024     public boolean isIntentSenderTargetedToPackage(IIntentSender pendingResult) {
7025         if (!(pendingResult instanceof PendingIntentRecord)) {
7026             return false;
7027         }
7028         try {
7029             PendingIntentRecord res = (PendingIntentRecord)pendingResult;
7030             if (res.key.allIntents == null) {
7031                 return false;
7032             }
7033             for (int i=0; i<res.key.allIntents.length; i++) {
7034                 Intent intent = res.key.allIntents[i];
7035                 if (intent.getPackage() != null && intent.getComponent() != null) {
7036                     return false;
7037                 }
7038             }
7039             return true;
7040         } catch (ClassCastException e) {
7041         }
7042         return false;
7043     }
7044
7045     @Override
7046     public boolean isIntentSenderAnActivity(IIntentSender pendingResult) {
7047         if (!(pendingResult instanceof PendingIntentRecord)) {
7048             return false;
7049         }
7050         try {
7051             PendingIntentRecord res = (PendingIntentRecord)pendingResult;
7052             if (res.key.type == ActivityManager.INTENT_SENDER_ACTIVITY) {
7053                 return true;
7054             }
7055             return false;
7056         } catch (ClassCastException e) {
7057         }
7058         return false;
7059     }
7060
7061     @Override
7062     public Intent getIntentForIntentSender(IIntentSender pendingResult) {
7063         if (!(pendingResult instanceof PendingIntentRecord)) {
7064             return null;
7065         }
7066         try {
7067             PendingIntentRecord res = (PendingIntentRecord)pendingResult;
7068             return res.key.requestIntent != null ? new Intent(res.key.requestIntent) : null;
7069         } catch (ClassCastException e) {
7070         }
7071         return null;
7072     }
7073
7074     @Override
7075     public String getTagForIntentSender(IIntentSender pendingResult, String prefix) {
7076         if (!(pendingResult instanceof PendingIntentRecord)) {
7077             return null;
7078         }
7079         try {
7080             PendingIntentRecord res = (PendingIntentRecord)pendingResult;
7081             synchronized (this) {
7082                 return getTagForIntentSenderLocked(res, prefix);
7083             }
7084         } catch (ClassCastException e) {
7085         }
7086         return null;
7087     }
7088
7089     String getTagForIntentSenderLocked(PendingIntentRecord res, String prefix) {
7090         final Intent intent = res.key.requestIntent;
7091         if (intent != null) {
7092             if (res.lastTag != null && res.lastTagPrefix == prefix && (res.lastTagPrefix == null
7093                     || res.lastTagPrefix.equals(prefix))) {
7094                 return res.lastTag;
7095             }
7096             res.lastTagPrefix = prefix;
7097             final StringBuilder sb = new StringBuilder(128);
7098             if (prefix != null) {
7099                 sb.append(prefix);
7100             }
7101             if (intent.getAction() != null) {
7102                 sb.append(intent.getAction());
7103             } else if (intent.getComponent() != null) {
7104                 intent.getComponent().appendShortString(sb);
7105             } else {
7106                 sb.append("?");
7107             }
7108             return res.lastTag = sb.toString();
7109         }
7110         return null;
7111     }
7112
7113     @Override
7114     public void setProcessLimit(int max) {
7115         enforceCallingPermission(android.Manifest.permission.SET_PROCESS_LIMIT,
7116                 "setProcessLimit()");
7117         synchronized (this) {
7118             mProcessLimit = max < 0 ? ProcessList.MAX_CACHED_APPS : max;
7119             mProcessLimitOverride = max;
7120         }
7121         trimApplications();
7122     }
7123
7124     @Override
7125     public int getProcessLimit() {
7126         synchronized (this) {
7127             return mProcessLimitOverride;
7128         }
7129     }
7130
7131     void foregroundTokenDied(ForegroundToken token) {
7132         synchronized (ActivityManagerService.this) {
7133             synchronized (mPidsSelfLocked) {
7134                 ForegroundToken cur
7135                     = mForegroundProcesses.get(token.pid);
7136                 if (cur != token) {
7137                     return;
7138                 }
7139                 mForegroundProcesses.remove(token.pid);
7140                 ProcessRecord pr = mPidsSelfLocked.get(token.pid);
7141                 if (pr == null) {
7142                     return;
7143                 }
7144                 pr.forcingToForeground = null;
7145                 updateProcessForegroundLocked(pr, false, false);
7146             }
7147             updateOomAdjLocked();
7148         }
7149     }
7150
7151     @Override
7152     public void setProcessForeground(IBinder token, int pid, boolean isForeground) {
7153         enforceCallingPermission(android.Manifest.permission.SET_PROCESS_LIMIT,
7154                 "setProcessForeground()");
7155         synchronized(this) {
7156             boolean changed = false;
7157
7158             synchronized (mPidsSelfLocked) {
7159                 ProcessRecord pr = mPidsSelfLocked.get(pid);
7160                 if (pr == null && isForeground) {
7161                     Slog.w(TAG, "setProcessForeground called on unknown pid: " + pid);
7162                     return;
7163                 }
7164                 ForegroundToken oldToken = mForegroundProcesses.get(pid);
7165                 if (oldToken != null) {
7166                     oldToken.token.unlinkToDeath(oldToken, 0);
7167                     mForegroundProcesses.remove(pid);
7168                     if (pr != null) {
7169                         pr.forcingToForeground = null;
7170                     }
7171                     changed = true;
7172                 }
7173                 if (isForeground && token != null) {
7174                     ForegroundToken newToken = new ForegroundToken() {
7175                         @Override
7176                         public void binderDied() {
7177                             foregroundTokenDied(this);
7178                         }
7179                     };
7180                     newToken.pid = pid;
7181                     newToken.token = token;
7182                     try {
7183                         token.linkToDeath(newToken, 0);
7184                         mForegroundProcesses.put(pid, newToken);
7185                         pr.forcingToForeground = token;
7186                         changed = true;
7187                     } catch (RemoteException e) {
7188                         // If the process died while doing this, we will later
7189                         // do the cleanup with the process death link.
7190                     }
7191                 }
7192             }
7193
7194             if (changed) {
7195                 updateOomAdjLocked();
7196             }
7197         }
7198     }
7199
7200     // =========================================================
7201     // PROCESS INFO
7202     // =========================================================
7203
7204     static class ProcessInfoService extends IProcessInfoService.Stub {
7205         final ActivityManagerService mActivityManagerService;
7206         ProcessInfoService(ActivityManagerService activityManagerService) {
7207             mActivityManagerService = activityManagerService;
7208         }
7209
7210         @Override
7211         public void getProcessStatesFromPids(/*in*/ int[] pids, /*out*/ int[] states) {
7212             mActivityManagerService.getProcessStatesAndOomScoresForPIDs(
7213                     /*in*/ pids, /*out*/ states, null);
7214         }
7215
7216         @Override
7217         public void getProcessStatesAndOomScoresFromPids(
7218                 /*in*/ int[] pids, /*out*/ int[] states, /*out*/ int[] scores) {
7219             mActivityManagerService.getProcessStatesAndOomScoresForPIDs(
7220                     /*in*/ pids, /*out*/ states, /*out*/ scores);
7221         }
7222     }
7223
7224     /**
7225      * For each PID in the given input array, write the current process state
7226      * for that process into the states array, or -1 to indicate that no
7227      * process with the given PID exists. If scores array is provided, write
7228      * the oom score for the process into the scores array, with INVALID_ADJ
7229      * indicating the PID doesn't exist.
7230      */
7231     public void getProcessStatesAndOomScoresForPIDs(
7232             /*in*/ int[] pids, /*out*/ int[] states, /*out*/ int[] scores) {
7233         if (pids == null) {
7234             throw new NullPointerException("pids");
7235         } else if (states == null) {
7236             throw new NullPointerException("states");
7237         } else if (pids.length != states.length) {
7238             throw new IllegalArgumentException("pids and states arrays have different lengths!");
7239         } else if (scores != null && pids.length != scores.length) {
7240             throw new IllegalArgumentException("pids and scores arrays have different lengths!");
7241         }
7242
7243         synchronized (mPidsSelfLocked) {
7244             for (int i = 0; i < pids.length; i++) {
7245                 ProcessRecord pr = mPidsSelfLocked.get(pids[i]);
7246                 states[i] = (pr == null) ? ActivityManager.PROCESS_STATE_NONEXISTENT :
7247                         pr.curProcState;
7248                 if (scores != null) {
7249                     scores[i] = (pr == null) ? ProcessList.INVALID_ADJ : pr.curAdj;
7250                 }
7251             }
7252         }
7253     }
7254
7255     // =========================================================
7256     // PERMISSIONS
7257     // =========================================================
7258
7259     static class PermissionController extends IPermissionController.Stub {
7260         ActivityManagerService mActivityManagerService;
7261         PermissionController(ActivityManagerService activityManagerService) {
7262             mActivityManagerService = activityManagerService;
7263         }
7264
7265         @Override
7266         public boolean checkPermission(String permission, int pid, int uid) {
7267             return mActivityManagerService.checkPermission(permission, pid,
7268                     uid) == PackageManager.PERMISSION_GRANTED;
7269         }
7270
7271         @Override
7272         public String[] getPackagesForUid(int uid) {
7273             return mActivityManagerService.mContext.getPackageManager()
7274                     .getPackagesForUid(uid);
7275         }
7276
7277         @Override
7278         public boolean isRuntimePermission(String permission) {
7279             try {
7280                 PermissionInfo info = mActivityManagerService.mContext.getPackageManager()
7281                         .getPermissionInfo(permission, 0);
7282                 return info.protectionLevel == PermissionInfo.PROTECTION_DANGEROUS;
7283             } catch (NameNotFoundException nnfe) {
7284                 Slog.e(TAG, "No such permission: "+ permission, nnfe);
7285             }
7286             return false;
7287         }
7288     }
7289
7290     class IntentFirewallInterface implements IntentFirewall.AMSInterface {
7291         @Override
7292         public int checkComponentPermission(String permission, int pid, int uid,
7293                 int owningUid, boolean exported) {
7294             return ActivityManagerService.this.checkComponentPermission(permission, pid, uid,
7295                     owningUid, exported);
7296         }
7297
7298         @Override
7299         public Object getAMSLock() {
7300             return ActivityManagerService.this;
7301         }
7302     }
7303
7304     /**
7305      * This can be called with or without the global lock held.
7306      */
7307     int checkComponentPermission(String permission, int pid, int uid,
7308             int owningUid, boolean exported) {
7309         if (pid == MY_PID) {
7310             return PackageManager.PERMISSION_GRANTED;
7311         }
7312         return ActivityManager.checkComponentPermission(permission, uid,
7313                 owningUid, exported);
7314     }
7315
7316     /**
7317      * As the only public entry point for permissions checking, this method
7318      * can enforce the semantic that requesting a check on a null global
7319      * permission is automatically denied.  (Internally a null permission
7320      * string is used when calling {@link #checkComponentPermission} in cases
7321      * when only uid-based security is needed.)
7322      *
7323      * This can be called with or without the global lock held.
7324      */
7325     @Override
7326     public int checkPermission(String permission, int pid, int uid) {
7327         if (permission == null) {
7328             return PackageManager.PERMISSION_DENIED;
7329         }
7330         return checkComponentPermission(permission, pid, uid, -1, true);
7331     }
7332
7333     @Override
7334     public int checkPermissionWithToken(String permission, int pid, int uid, IBinder callerToken) {
7335         if (permission == null) {
7336             return PackageManager.PERMISSION_DENIED;
7337         }
7338
7339         // We might be performing an operation on behalf of an indirect binder
7340         // invocation, e.g. via {@link #openContentUri}.  Check and adjust the
7341         // client identity accordingly before proceeding.
7342         Identity tlsIdentity = sCallerIdentity.get();
7343         if (tlsIdentity != null && tlsIdentity.token == callerToken) {
7344             Slog.d(TAG, "checkComponentPermission() adjusting {pid,uid} to {"
7345                     + tlsIdentity.pid + "," + tlsIdentity.uid + "}");
7346             uid = tlsIdentity.uid;
7347             pid = tlsIdentity.pid;
7348         }
7349
7350         return checkComponentPermission(permission, pid, uid, -1, true);
7351     }
7352
7353     /**
7354      * Binder IPC calls go through the public entry point.
7355      * This can be called with or without the global lock held.
7356      */
7357     int checkCallingPermission(String permission) {
7358         return checkPermission(permission,
7359                 Binder.getCallingPid(),
7360                 UserHandle.getAppId(Binder.getCallingUid()));
7361     }
7362
7363     /**
7364      * This can be called with or without the global lock held.
7365      */
7366     void enforceCallingPermission(String permission, String func) {
7367         if (checkCallingPermission(permission)
7368                 == PackageManager.PERMISSION_GRANTED) {
7369             return;
7370         }
7371
7372         String msg = "Permission Denial: " + func + " from pid="
7373                 + Binder.getCallingPid()
7374                 + ", uid=" + Binder.getCallingUid()
7375                 + " requires " + permission;
7376         Slog.w(TAG, msg);
7377         throw new SecurityException(msg);
7378     }
7379
7380     /**
7381      * Determine if UID is holding permissions required to access {@link Uri} in
7382      * the given {@link ProviderInfo}. Final permission checking is always done
7383      * in {@link ContentProvider}.
7384      */
7385     private final boolean checkHoldingPermissionsLocked(
7386             IPackageManager pm, ProviderInfo pi, GrantUri grantUri, int uid, final int modeFlags) {
7387         if (DEBUG_URI_PERMISSION) Slog.v(TAG_URI_PERMISSION,
7388                 "checkHoldingPermissionsLocked: uri=" + grantUri + " uid=" + uid);
7389         if (UserHandle.getUserId(uid) != grantUri.sourceUserId) {
7390             if (ActivityManager.checkComponentPermission(INTERACT_ACROSS_USERS, uid, -1, true)
7391                     != PERMISSION_GRANTED) {
7392                 return false;
7393             }
7394         }
7395         return checkHoldingPermissionsInternalLocked(pm, pi, grantUri, uid, modeFlags, true);
7396     }
7397
7398     private final boolean checkHoldingPermissionsInternalLocked(IPackageManager pm, ProviderInfo pi,
7399             GrantUri grantUri, int uid, final int modeFlags, boolean considerUidPermissions) {
7400         if (pi.applicationInfo.uid == uid) {
7401             return true;
7402         } else if (!pi.exported) {
7403             return false;
7404         }
7405
7406         boolean readMet = (modeFlags & Intent.FLAG_GRANT_READ_URI_PERMISSION) == 0;
7407         boolean writeMet = (modeFlags & Intent.FLAG_GRANT_WRITE_URI_PERMISSION) == 0;
7408         try {
7409             // check if target holds top-level <provider> permissions
7410             if (!readMet && pi.readPermission != null && considerUidPermissions
7411                     && (pm.checkUidPermission(pi.readPermission, uid) == PERMISSION_GRANTED)) {
7412                 readMet = true;
7413             }
7414             if (!writeMet && pi.writePermission != null && considerUidPermissions
7415                     && (pm.checkUidPermission(pi.writePermission, uid) == PERMISSION_GRANTED)) {
7416                 writeMet = true;
7417             }
7418
7419             // track if unprotected read/write is allowed; any denied
7420             // <path-permission> below removes this ability
7421             boolean allowDefaultRead = pi.readPermission == null;
7422             boolean allowDefaultWrite = pi.writePermission == null;
7423
7424             // check if target holds any <path-permission> that match uri
7425             final PathPermission[] pps = pi.pathPermissions;
7426             if (pps != null) {
7427                 final String path = grantUri.uri.getPath();
7428                 int i = pps.length;
7429                 while (i > 0 && (!readMet || !writeMet)) {
7430                     i--;
7431                     PathPermission pp = pps[i];
7432                     if (pp.match(path)) {
7433                         if (!readMet) {
7434                             final String pprperm = pp.getReadPermission();
7435                             if (DEBUG_URI_PERMISSION) Slog.v(TAG_URI_PERMISSION,
7436                                     "Checking read perm for " + pprperm + " for " + pp.getPath()
7437                                     + ": match=" + pp.match(path)
7438                                     + " check=" + pm.checkUidPermission(pprperm, uid));
7439                             if (pprperm != null) {
7440                                 if (considerUidPermissions && pm.checkUidPermission(pprperm, uid)
7441                                         == PERMISSION_GRANTED) {
7442                                     readMet = true;
7443                                 } else {
7444                                     allowDefaultRead = false;
7445                                 }
7446                             }
7447                         }
7448                         if (!writeMet) {
7449                             final String ppwperm = pp.getWritePermission();
7450                             if (DEBUG_URI_PERMISSION) Slog.v(TAG_URI_PERMISSION,
7451                                     "Checking write perm " + ppwperm + " for " + pp.getPath()
7452                                     + ": match=" + pp.match(path)
7453                                     + " check=" + pm.checkUidPermission(ppwperm, uid));
7454                             if (ppwperm != null) {
7455                                 if (considerUidPermissions && pm.checkUidPermission(ppwperm, uid)
7456                                         == PERMISSION_GRANTED) {
7457                                     writeMet = true;
7458                                 } else {
7459                                     allowDefaultWrite = false;
7460                                 }
7461                             }
7462                         }
7463                     }
7464                 }
7465             }
7466
7467             // grant unprotected <provider> read/write, if not blocked by
7468             // <path-permission> above
7469             if (allowDefaultRead) readMet = true;
7470             if (allowDefaultWrite) writeMet = true;
7471
7472         } catch (RemoteException e) {
7473             return false;
7474         }
7475
7476         return readMet && writeMet;
7477     }
7478
7479     public int getAppStartMode(int uid, String packageName) {
7480         synchronized (this) {
7481             boolean bg = checkAllowBackgroundLocked(uid, packageName, -1);
7482             return bg ? ActivityManager.APP_START_MODE_NORMAL
7483                     : ActivityManager.APP_START_MODE_DISABLED;
7484         }
7485     }
7486
7487     boolean checkAllowBackgroundLocked(int uid, String packageName, int callingPid) {
7488         UidRecord uidRec = mActiveUids.get(uid);
7489         if (uidRec == null || uidRec.idle) {
7490             if (callingPid >= 0) {
7491                 ProcessRecord proc;
7492                 synchronized (mPidsSelfLocked) {
7493                     proc = mPidsSelfLocked.get(callingPid);
7494                 }
7495                 if (proc != null && proc.curProcState < ActivityManager.PROCESS_STATE_RECEIVER) {
7496                     // Whoever is instigating this is in the foreground, so we will allow it
7497                     // to go through.
7498                     return true;
7499                 }
7500             }
7501             if (mAppOpsService.noteOperation(AppOpsManager.OP_RUN_IN_BACKGROUND, uid, packageName)
7502                     != AppOpsManager.MODE_ALLOWED) {
7503                 return false;
7504             }
7505         }
7506         return true;
7507     }
7508
7509     private ProviderInfo getProviderInfoLocked(String authority, int userHandle) {
7510         ProviderInfo pi = null;
7511         ContentProviderRecord cpr = mProviderMap.getProviderByName(authority, userHandle);
7512         if (cpr != null) {
7513             pi = cpr.info;
7514         } else {
7515             try {
7516                 pi = AppGlobals.getPackageManager().resolveContentProvider(
7517                         authority, PackageManager.GET_URI_PERMISSION_PATTERNS, userHandle);
7518             } catch (RemoteException ex) {
7519             }
7520         }
7521         return pi;
7522     }
7523
7524     private UriPermission findUriPermissionLocked(int targetUid, GrantUri grantUri) {
7525         final ArrayMap<GrantUri, UriPermission> targetUris = mGrantedUriPermissions.get(targetUid);
7526         if (targetUris != null) {
7527             return targetUris.get(grantUri);
7528         }
7529         return null;
7530     }
7531
7532     private UriPermission findOrCreateUriPermissionLocked(String sourcePkg,
7533             String targetPkg, int targetUid, GrantUri grantUri) {
7534         ArrayMap<GrantUri, UriPermission> targetUris = mGrantedUriPermissions.get(targetUid);
7535         if (targetUris == null) {
7536             targetUris = Maps.newArrayMap();
7537             mGrantedUriPermissions.put(targetUid, targetUris);
7538         }
7539
7540         UriPermission perm = targetUris.get(grantUri);
7541         if (perm == null) {
7542             perm = new UriPermission(sourcePkg, targetPkg, targetUid, grantUri);
7543             targetUris.put(grantUri, perm);
7544         }
7545
7546         return perm;
7547     }
7548
7549     private final boolean checkUriPermissionLocked(GrantUri grantUri, int uid,
7550             final int modeFlags) {
7551         final boolean persistable = (modeFlags & Intent.FLAG_GRANT_PERSISTABLE_URI_PERMISSION) != 0;
7552         final int minStrength = persistable ? UriPermission.STRENGTH_PERSISTABLE
7553                 : UriPermission.STRENGTH_OWNED;
7554
7555         // Root gets to do everything.
7556         if (uid == 0) {
7557             return true;
7558         }
7559
7560         final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.get(uid);
7561         if (perms == null) return false;
7562
7563         // First look for exact match
7564         final UriPermission exactPerm = perms.get(grantUri);
7565         if (exactPerm != null && exactPerm.getStrength(modeFlags) >= minStrength) {
7566             return true;
7567         }
7568
7569         // No exact match, look for prefixes
7570         final int N = perms.size();
7571         for (int i = 0; i < N; i++) {
7572             final UriPermission perm = perms.valueAt(i);
7573             if (perm.uri.prefix && grantUri.uri.isPathPrefixMatch(perm.uri.uri)
7574                     && perm.getStrength(modeFlags) >= minStrength) {
7575                 return true;
7576             }
7577         }
7578
7579         return false;
7580     }
7581
7582     /**
7583      * @param uri This uri must NOT contain an embedded userId.
7584      * @param userId The userId in which the uri is to be resolved.
7585      */
7586     @Override
7587     public int checkUriPermission(Uri uri, int pid, int uid,
7588             final int modeFlags, int userId, IBinder callerToken) {
7589         enforceNotIsolatedCaller("checkUriPermission");
7590
7591         // Another redirected-binder-call permissions check as in
7592         // {@link checkPermissionWithToken}.
7593         Identity tlsIdentity = sCallerIdentity.get();
7594         if (tlsIdentity != null && tlsIdentity.token == callerToken) {
7595             uid = tlsIdentity.uid;
7596             pid = tlsIdentity.pid;
7597         }
7598
7599         // Our own process gets to do everything.
7600         if (pid == MY_PID) {
7601             return PackageManager.PERMISSION_GRANTED;
7602         }
7603         synchronized (this) {
7604             return checkUriPermissionLocked(new GrantUri(userId, uri, false), uid, modeFlags)
7605                     ? PackageManager.PERMISSION_GRANTED
7606                     : PackageManager.PERMISSION_DENIED;
7607         }
7608     }
7609
7610     /**
7611      * Check if the targetPkg can be granted permission to access uri by
7612      * the callingUid using the given modeFlags.  Throws a security exception
7613      * if callingUid is not allowed to do this.  Returns the uid of the target
7614      * if the URI permission grant should be performed; returns -1 if it is not
7615      * needed (for example targetPkg already has permission to access the URI).
7616      * If you already know the uid of the target, you can supply it in
7617      * lastTargetUid else set that to -1.
7618      */
7619     int checkGrantUriPermissionLocked(int callingUid, String targetPkg, GrantUri grantUri,
7620             final int modeFlags, int lastTargetUid) {
7621         if (!Intent.isAccessUriMode(modeFlags)) {
7622             return -1;
7623         }
7624
7625         if (targetPkg != null) {
7626             if (DEBUG_URI_PERMISSION) Slog.v(TAG_URI_PERMISSION,
7627                     "Checking grant " + targetPkg + " permission to " + grantUri);
7628         }
7629
7630         final IPackageManager pm = AppGlobals.getPackageManager();
7631
7632         // If this is not a content: uri, we can't do anything with it.
7633         if (!ContentResolver.SCHEME_CONTENT.equals(grantUri.uri.getScheme())) {
7634             if (DEBUG_URI_PERMISSION) Slog.v(TAG_URI_PERMISSION,
7635                     "Can't grant URI permission for non-content URI: " + grantUri);
7636             return -1;
7637         }
7638
7639         final String authority = grantUri.uri.getAuthority();
7640         final ProviderInfo pi = getProviderInfoLocked(authority, grantUri.sourceUserId);
7641         if (pi == null) {
7642             Slog.w(TAG, "No content provider found for permission check: " +
7643                     grantUri.uri.toSafeString());
7644             return -1;
7645         }
7646
7647         int targetUid = lastTargetUid;
7648         if (targetUid < 0 && targetPkg != null) {
7649             try {
7650                 targetUid = pm.getPackageUid(targetPkg, UserHandle.getUserId(callingUid));
7651                 if (targetUid < 0) {
7652                     if (DEBUG_URI_PERMISSION) Slog.v(TAG_URI_PERMISSION,
7653                             "Can't grant URI permission no uid for: " + targetPkg);
7654                     return -1;
7655                 }
7656             } catch (RemoteException ex) {
7657                 return -1;
7658             }
7659         }
7660
7661         if (targetUid >= 0) {
7662             // First...  does the target actually need this permission?
7663             if (checkHoldingPermissionsLocked(pm, pi, grantUri, targetUid, modeFlags)) {
7664                 // No need to grant the target this permission.
7665                 if (DEBUG_URI_PERMISSION) Slog.v(TAG_URI_PERMISSION,
7666                         "Target " + targetPkg + " already has full permission to " + grantUri);
7667                 return -1;
7668             }
7669         } else {
7670             // First...  there is no target package, so can anyone access it?
7671             boolean allowed = pi.exported;
7672             if ((modeFlags&Intent.FLAG_GRANT_READ_URI_PERMISSION) != 0) {
7673                 if (pi.readPermission != null) {
7674                     allowed = false;
7675                 }
7676             }
7677             if ((modeFlags&Intent.FLAG_GRANT_WRITE_URI_PERMISSION) != 0) {
7678                 if (pi.writePermission != null) {
7679                     allowed = false;
7680                 }
7681             }
7682             if (allowed) {
7683                 return -1;
7684             }
7685         }
7686
7687         /* There is a special cross user grant if:
7688          * - The target is on another user.
7689          * - Apps on the current user can access the uri without any uid permissions.
7690          * In this case, we grant a uri permission, even if the ContentProvider does not normally
7691          * grant uri permissions.
7692          */
7693         boolean specialCrossUserGrant = UserHandle.getUserId(targetUid) != grantUri.sourceUserId
7694                 && checkHoldingPermissionsInternalLocked(pm, pi, grantUri, callingUid,
7695                 modeFlags, false /*without considering the uid permissions*/);
7696
7697         // Second...  is the provider allowing granting of URI permissions?
7698         if (!specialCrossUserGrant) {
7699             if (!pi.grantUriPermissions) {
7700                 throw new SecurityException("Provider " + pi.packageName
7701                         + "/" + pi.name
7702                         + " does not allow granting of Uri permissions (uri "
7703                         + grantUri + ")");
7704             }
7705             if (pi.uriPermissionPatterns != null) {
7706                 final int N = pi.uriPermissionPatterns.length;
7707                 boolean allowed = false;
7708                 for (int i=0; i<N; i++) {
7709                     if (pi.uriPermissionPatterns[i] != null
7710                             && pi.uriPermissionPatterns[i].match(grantUri.uri.getPath())) {
7711                         allowed = true;
7712                         break;
7713                     }
7714                 }
7715                 if (!allowed) {
7716                     throw new SecurityException("Provider " + pi.packageName
7717                             + "/" + pi.name
7718                             + " does not allow granting of permission to path of Uri "
7719                             + grantUri);
7720                 }
7721             }
7722         }
7723
7724         // Third...  does the caller itself have permission to access
7725         // this uri?
7726         if (UserHandle.getAppId(callingUid) != Process.SYSTEM_UID) {
7727             if (!checkHoldingPermissionsLocked(pm, pi, grantUri, callingUid, modeFlags)) {
7728                 // Require they hold a strong enough Uri permission
7729                 if (!checkUriPermissionLocked(grantUri, callingUid, modeFlags)) {
7730                     throw new SecurityException("Uid " + callingUid
7731                             + " does not have permission to uri " + grantUri);
7732                 }
7733             }
7734         }
7735         return targetUid;
7736     }
7737
7738     /**
7739      * @param uri This uri must NOT contain an embedded userId.
7740      * @param userId The userId in which the uri is to be resolved.
7741      */
7742     @Override
7743     public int checkGrantUriPermission(int callingUid, String targetPkg, Uri uri,
7744             final int modeFlags, int userId) {
7745         enforceNotIsolatedCaller("checkGrantUriPermission");
7746         synchronized(this) {
7747             return checkGrantUriPermissionLocked(callingUid, targetPkg,
7748                     new GrantUri(userId, uri, false), modeFlags, -1);
7749         }
7750     }
7751
7752     void grantUriPermissionUncheckedLocked(int targetUid, String targetPkg, GrantUri grantUri,
7753             final int modeFlags, UriPermissionOwner owner) {
7754         if (!Intent.isAccessUriMode(modeFlags)) {
7755             return;
7756         }
7757
7758         // So here we are: the caller has the assumed permission
7759         // to the uri, and the target doesn't.  Let's now give this to
7760         // the target.
7761
7762         if (DEBUG_URI_PERMISSION) Slog.v(TAG_URI_PERMISSION,
7763                 "Granting " + targetPkg + "/" + targetUid + " permission to " + grantUri);
7764
7765         final String authority = grantUri.uri.getAuthority();
7766         final ProviderInfo pi = getProviderInfoLocked(authority, grantUri.sourceUserId);
7767         if (pi == null) {
7768             Slog.w(TAG, "No content provider found for grant: " + grantUri.toSafeString());
7769             return;
7770         }
7771
7772         if ((modeFlags & Intent.FLAG_GRANT_PREFIX_URI_PERMISSION) != 0) {
7773             grantUri.prefix = true;
7774         }
7775         final UriPermission perm = findOrCreateUriPermissionLocked(
7776                 pi.packageName, targetPkg, targetUid, grantUri);
7777         perm.grantModes(modeFlags, owner);
7778     }
7779
7780     void grantUriPermissionLocked(int callingUid, String targetPkg, GrantUri grantUri,
7781             final int modeFlags, UriPermissionOwner owner, int targetUserId) {
7782         if (targetPkg == null) {
7783             throw new NullPointerException("targetPkg");
7784         }
7785         int targetUid;
7786         final IPackageManager pm = AppGlobals.getPackageManager();
7787         try {
7788             targetUid = pm.getPackageUid(targetPkg, targetUserId);
7789         } catch (RemoteException ex) {
7790             return;
7791         }
7792
7793         targetUid = checkGrantUriPermissionLocked(callingUid, targetPkg, grantUri, modeFlags,
7794                 targetUid);
7795         if (targetUid < 0) {
7796             return;
7797         }
7798
7799         grantUriPermissionUncheckedLocked(targetUid, targetPkg, grantUri, modeFlags,
7800                 owner);
7801     }
7802
7803     static class NeededUriGrants extends ArrayList<GrantUri> {
7804         final String targetPkg;
7805         final int targetUid;
7806         final int flags;
7807
7808         NeededUriGrants(String targetPkg, int targetUid, int flags) {
7809             this.targetPkg = targetPkg;
7810             this.targetUid = targetUid;
7811             this.flags = flags;
7812         }
7813     }
7814
7815     /**
7816      * Like checkGrantUriPermissionLocked, but takes an Intent.
7817      */
7818     NeededUriGrants checkGrantUriPermissionFromIntentLocked(int callingUid,
7819             String targetPkg, Intent intent, int mode, NeededUriGrants needed, int targetUserId) {
7820         if (DEBUG_URI_PERMISSION) Slog.v(TAG_URI_PERMISSION,
7821                 "Checking URI perm to data=" + (intent != null ? intent.getData() : null)
7822                 + " clip=" + (intent != null ? intent.getClipData() : null)
7823                 + " from " + intent + "; flags=0x"
7824                 + Integer.toHexString(intent != null ? intent.getFlags() : 0));
7825
7826         if (targetPkg == null) {
7827             throw new NullPointerException("targetPkg");
7828         }
7829
7830         if (intent == null) {
7831             return null;
7832         }
7833         Uri data = intent.getData();
7834         ClipData clip = intent.getClipData();
7835         if (data == null && clip == null) {
7836             return null;
7837         }
7838         // Default userId for uris in the intent (if they don't specify it themselves)
7839         int contentUserHint = intent.getContentUserHint();
7840         if (contentUserHint == UserHandle.USER_CURRENT) {
7841             contentUserHint = UserHandle.getUserId(callingUid);
7842         }
7843         final IPackageManager pm = AppGlobals.getPackageManager();
7844         int targetUid;
7845         if (needed != null) {
7846             targetUid = needed.targetUid;
7847         } else {
7848             try {
7849                 targetUid = pm.getPackageUid(targetPkg, targetUserId);
7850             } catch (RemoteException ex) {
7851                 return null;
7852             }
7853             if (targetUid < 0) {
7854                 if (DEBUG_URI_PERMISSION) Slog.v(TAG_URI_PERMISSION,
7855                         "Can't grant URI permission no uid for: " + targetPkg
7856                         + " on user " + targetUserId);
7857                 return null;
7858             }
7859         }
7860         if (data != null) {
7861             GrantUri grantUri = GrantUri.resolve(contentUserHint, data);
7862             targetUid = checkGrantUriPermissionLocked(callingUid, targetPkg, grantUri, mode,
7863                     targetUid);
7864             if (targetUid > 0) {
7865                 if (needed == null) {
7866                     needed = new NeededUriGrants(targetPkg, targetUid, mode);
7867                 }
7868                 needed.add(grantUri);
7869             }
7870         }
7871         if (clip != null) {
7872             for (int i=0; i<clip.getItemCount(); i++) {
7873                 Uri uri = clip.getItemAt(i).getUri();
7874                 if (uri != null) {
7875                     GrantUri grantUri = GrantUri.resolve(contentUserHint, uri);
7876                     targetUid = checkGrantUriPermissionLocked(callingUid, targetPkg, grantUri, mode,
7877                             targetUid);
7878                     if (targetUid > 0) {
7879                         if (needed == null) {
7880                             needed = new NeededUriGrants(targetPkg, targetUid, mode);
7881                         }
7882                         needed.add(grantUri);
7883                     }
7884                 } else {
7885                     Intent clipIntent = clip.getItemAt(i).getIntent();
7886                     if (clipIntent != null) {
7887                         NeededUriGrants newNeeded = checkGrantUriPermissionFromIntentLocked(
7888                                 callingUid, targetPkg, clipIntent, mode, needed, targetUserId);
7889                         if (newNeeded != null) {
7890                             needed = newNeeded;
7891                         }
7892                     }
7893                 }
7894             }
7895         }
7896
7897         return needed;
7898     }
7899
7900     /**
7901      * Like grantUriPermissionUncheckedLocked, but takes an Intent.
7902      */
7903     void grantUriPermissionUncheckedFromIntentLocked(NeededUriGrants needed,
7904             UriPermissionOwner owner) {
7905         if (needed != null) {
7906             for (int i=0; i<needed.size(); i++) {
7907                 GrantUri grantUri = needed.get(i);
7908                 grantUriPermissionUncheckedLocked(needed.targetUid, needed.targetPkg,
7909                         grantUri, needed.flags, owner);
7910             }
7911         }
7912     }
7913
7914     void grantUriPermissionFromIntentLocked(int callingUid,
7915             String targetPkg, Intent intent, UriPermissionOwner owner, int targetUserId) {
7916         NeededUriGrants needed = checkGrantUriPermissionFromIntentLocked(callingUid, targetPkg,
7917                 intent, intent != null ? intent.getFlags() : 0, null, targetUserId);
7918         if (needed == null) {
7919             return;
7920         }
7921
7922         grantUriPermissionUncheckedFromIntentLocked(needed, owner);
7923     }
7924
7925     /**
7926      * @param uri This uri must NOT contain an embedded userId.
7927      * @param userId The userId in which the uri is to be resolved.
7928      */
7929     @Override
7930     public void grantUriPermission(IApplicationThread caller, String targetPkg, Uri uri,
7931             final int modeFlags, int userId) {
7932         enforceNotIsolatedCaller("grantUriPermission");
7933         GrantUri grantUri = new GrantUri(userId, uri, false);
7934         synchronized(this) {
7935             final ProcessRecord r = getRecordForAppLocked(caller);
7936             if (r == null) {
7937                 throw new SecurityException("Unable to find app for caller "
7938                         + caller
7939                         + " when granting permission to uri " + grantUri);
7940             }
7941             if (targetPkg == null) {
7942                 throw new IllegalArgumentException("null target");
7943             }
7944             if (grantUri == null) {
7945                 throw new IllegalArgumentException("null uri");
7946             }
7947
7948             Preconditions.checkFlagsArgument(modeFlags, Intent.FLAG_GRANT_READ_URI_PERMISSION
7949                     | Intent.FLAG_GRANT_WRITE_URI_PERMISSION
7950                     | Intent.FLAG_GRANT_PERSISTABLE_URI_PERMISSION
7951                     | Intent.FLAG_GRANT_PREFIX_URI_PERMISSION);
7952
7953             grantUriPermissionLocked(r.uid, targetPkg, grantUri, modeFlags, null,
7954                     UserHandle.getUserId(r.uid));
7955         }
7956     }
7957
7958     void removeUriPermissionIfNeededLocked(UriPermission perm) {
7959         if (perm.modeFlags == 0) {
7960             final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.get(
7961                     perm.targetUid);
7962             if (perms != null) {
7963                 if (DEBUG_URI_PERMISSION) Slog.v(TAG_URI_PERMISSION,
7964                         "Removing " + perm.targetUid + " permission to " + perm.uri);
7965
7966                 perms.remove(perm.uri);
7967                 if (perms.isEmpty()) {
7968                     mGrantedUriPermissions.remove(perm.targetUid);
7969                 }
7970             }
7971         }
7972     }
7973
7974     private void revokeUriPermissionLocked(int callingUid, GrantUri grantUri, final int modeFlags) {
7975         if (DEBUG_URI_PERMISSION) Slog.v(TAG_URI_PERMISSION,
7976                 "Revoking all granted permissions to " + grantUri);
7977
7978         final IPackageManager pm = AppGlobals.getPackageManager();
7979         final String authority = grantUri.uri.getAuthority();
7980         final ProviderInfo pi = getProviderInfoLocked(authority, grantUri.sourceUserId);
7981         if (pi == null) {
7982             Slog.w(TAG, "No content provider found for permission revoke: "
7983                     + grantUri.toSafeString());
7984             return;
7985         }
7986
7987         // Does the caller have this permission on the URI?
7988         if (!checkHoldingPermissionsLocked(pm, pi, grantUri, callingUid, modeFlags)) {
7989             // If they don't have direct access to the URI, then revoke any
7990             // ownerless URI permissions that have been granted to them.
7991             final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.get(callingUid);
7992             if (perms != null) {
7993                 boolean persistChanged = false;
7994                 for (Iterator<UriPermission> it = perms.values().iterator(); it.hasNext();) {
7995                     final UriPermission perm = it.next();
7996                     if (perm.uri.sourceUserId == grantUri.sourceUserId
7997                             && perm.uri.uri.isPathPrefixMatch(grantUri.uri)) {
7998                         if (DEBUG_URI_PERMISSION) Slog.v(TAG_URI_PERMISSION,
7999                                 "Revoking non-owned " + perm.targetUid
8000                                 + " permission to " + perm.uri);
8001                         persistChanged |= perm.revokeModes(
8002                                 modeFlags | Intent.FLAG_GRANT_PERSISTABLE_URI_PERMISSION, false);
8003                         if (perm.modeFlags == 0) {
8004                             it.remove();
8005                         }
8006                     }
8007                 }
8008                 if (perms.isEmpty()) {
8009                     mGrantedUriPermissions.remove(callingUid);
8010                 }
8011                 if (persistChanged) {
8012                     schedulePersistUriGrants();
8013                 }
8014             }
8015             return;
8016         }
8017
8018         boolean persistChanged = false;
8019
8020         // Go through all of the permissions and remove any that match.
8021         int N = mGrantedUriPermissions.size();
8022         for (int i = 0; i < N; i++) {
8023             final int targetUid = mGrantedUriPermissions.keyAt(i);
8024             final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.valueAt(i);
8025
8026             for (Iterator<UriPermission> it = perms.values().iterator(); it.hasNext();) {
8027                 final UriPermission perm = it.next();
8028                 if (perm.uri.sourceUserId == grantUri.sourceUserId
8029                         && perm.uri.uri.isPathPrefixMatch(grantUri.uri)) {
8030                     if (DEBUG_URI_PERMISSION) Slog.v(TAG_URI_PERMISSION,
8031                                 "Revoking " + perm.targetUid + " permission to " + perm.uri);
8032                     persistChanged |= perm.revokeModes(
8033                             modeFlags | Intent.FLAG_GRANT_PERSISTABLE_URI_PERMISSION, true);
8034                     if (perm.modeFlags == 0) {
8035                         it.remove();
8036                     }
8037                 }
8038             }
8039
8040             if (perms.isEmpty()) {
8041                 mGrantedUriPermissions.remove(targetUid);
8042                 N--;
8043                 i--;
8044             }
8045         }
8046
8047         if (persistChanged) {
8048             schedulePersistUriGrants();
8049         }
8050     }
8051
8052     /**
8053      * @param uri This uri must NOT contain an embedded userId.
8054      * @param userId The userId in which the uri is to be resolved.
8055      */
8056     @Override
8057     public void revokeUriPermission(IApplicationThread caller, Uri uri, final int modeFlags,
8058             int userId) {
8059         enforceNotIsolatedCaller("revokeUriPermission");
8060         synchronized(this) {
8061             final ProcessRecord r = getRecordForAppLocked(caller);
8062             if (r == null) {
8063                 throw new SecurityException("Unable to find app for caller "
8064                         + caller
8065                         + " when revoking permission to uri " + uri);
8066             }
8067             if (uri == null) {
8068                 Slog.w(TAG, "revokeUriPermission: null uri");
8069                 return;
8070             }
8071
8072             if (!Intent.isAccessUriMode(modeFlags)) {
8073                 return;
8074             }
8075
8076             final String authority = uri.getAuthority();
8077             final ProviderInfo pi = getProviderInfoLocked(authority, userId);
8078             if (pi == null) {
8079                 Slog.w(TAG, "No content provider found for permission revoke: "
8080                         + uri.toSafeString());
8081                 return;
8082             }
8083
8084             revokeUriPermissionLocked(r.uid, new GrantUri(userId, uri, false), modeFlags);
8085         }
8086     }
8087
8088     /**
8089      * Remove any {@link UriPermission} granted <em>from</em> or <em>to</em> the
8090      * given package.
8091      *
8092      * @param packageName Package name to match, or {@code null} to apply to all
8093      *            packages.
8094      * @param userHandle User to match, or {@link UserHandle#USER_ALL} to apply
8095      *            to all users.
8096      * @param persistable If persistable grants should be removed.
8097      */
8098     private void removeUriPermissionsForPackageLocked(
8099             String packageName, int userHandle, boolean persistable) {
8100         if (userHandle == UserHandle.USER_ALL && packageName == null) {
8101             throw new IllegalArgumentException("Must narrow by either package or user");
8102         }
8103
8104         boolean persistChanged = false;
8105
8106         int N = mGrantedUriPermissions.size();
8107         for (int i = 0; i < N; i++) {
8108             final int targetUid = mGrantedUriPermissions.keyAt(i);
8109             final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.valueAt(i);
8110
8111             // Only inspect grants matching user
8112             if (userHandle == UserHandle.USER_ALL
8113                     || userHandle == UserHandle.getUserId(targetUid)) {
8114                 for (Iterator<UriPermission> it = perms.values().iterator(); it.hasNext();) {
8115                     final UriPermission perm = it.next();
8116
8117                     // Only inspect grants matching package
8118                     if (packageName == null || perm.sourcePkg.equals(packageName)
8119                             || perm.targetPkg.equals(packageName)) {
8120                         persistChanged |= perm.revokeModes(persistable
8121                                 ? ~0 : ~Intent.FLAG_GRANT_PERSISTABLE_URI_PERMISSION, true);
8122
8123                         // Only remove when no modes remain; any persisted grants
8124                         // will keep this alive.
8125                         if (perm.modeFlags == 0) {
8126                             it.remove();
8127                         }
8128                     }
8129                 }
8130
8131                 if (perms.isEmpty()) {
8132                     mGrantedUriPermissions.remove(targetUid);
8133                     N--;
8134                     i--;
8135                 }
8136             }
8137         }
8138
8139         if (persistChanged) {
8140             schedulePersistUriGrants();
8141         }
8142     }
8143
8144     @Override
8145     public IBinder newUriPermissionOwner(String name) {
8146         enforceNotIsolatedCaller("newUriPermissionOwner");
8147         synchronized(this) {
8148             UriPermissionOwner owner = new UriPermissionOwner(this, name);
8149             return owner.getExternalTokenLocked();
8150         }
8151     }
8152
8153     /**
8154      * @param uri This uri must NOT contain an embedded userId.
8155      * @param sourceUserId The userId in which the uri is to be resolved.
8156      * @param targetUserId The userId of the app that receives the grant.
8157      */
8158     @Override
8159     public void grantUriPermissionFromOwner(IBinder token, int fromUid, String targetPkg, Uri uri,
8160             final int modeFlags, int sourceUserId, int targetUserId) {
8161         targetUserId = mUserController.handleIncomingUser(Binder.getCallingPid(),
8162                 Binder.getCallingUid(), targetUserId, false, ALLOW_FULL_ONLY,
8163                 "grantUriPermissionFromOwner", null);
8164         synchronized(this) {
8165             UriPermissionOwner owner = UriPermissionOwner.fromExternalToken(token);
8166             if (owner == null) {
8167                 throw new IllegalArgumentException("Unknown owner: " + token);
8168             }
8169             if (fromUid != Binder.getCallingUid()) {
8170                 if (Binder.getCallingUid() != Process.myUid()) {
8171                     // Only system code can grant URI permissions on behalf
8172                     // of other users.
8173                     throw new SecurityException("nice try");
8174                 }
8175             }
8176             if (targetPkg == null) {
8177                 throw new IllegalArgumentException("null target");
8178             }
8179             if (uri == null) {
8180                 throw new IllegalArgumentException("null uri");
8181             }
8182
8183             grantUriPermissionLocked(fromUid, targetPkg, new GrantUri(sourceUserId, uri, false),
8184                     modeFlags, owner, targetUserId);
8185         }
8186     }
8187
8188     /**
8189      * @param uri This uri must NOT contain an embedded userId.
8190      * @param userId The userId in which the uri is to be resolved.
8191      */
8192     @Override
8193     public void revokeUriPermissionFromOwner(IBinder token, Uri uri, int mode, int userId) {
8194         synchronized(this) {
8195             UriPermissionOwner owner = UriPermissionOwner.fromExternalToken(token);
8196             if (owner == null) {
8197                 throw new IllegalArgumentException("Unknown owner: " + token);
8198             }
8199
8200             if (uri == null) {
8201                 owner.removeUriPermissionsLocked(mode);
8202             } else {
8203                 owner.removeUriPermissionLocked(new GrantUri(userId, uri, false), mode);
8204             }
8205         }
8206     }
8207
8208     private void schedulePersistUriGrants() {
8209         if (!mHandler.hasMessages(PERSIST_URI_GRANTS_MSG)) {
8210             mHandler.sendMessageDelayed(mHandler.obtainMessage(PERSIST_URI_GRANTS_MSG),
8211                     10 * DateUtils.SECOND_IN_MILLIS);
8212         }
8213     }
8214
8215     private void writeGrantedUriPermissions() {
8216         if (DEBUG_URI_PERMISSION) Slog.v(TAG_URI_PERMISSION, "writeGrantedUriPermissions()");
8217
8218         // Snapshot permissions so we can persist without lock
8219         ArrayList<UriPermission.Snapshot> persist = Lists.newArrayList();
8220         synchronized (this) {
8221             final int size = mGrantedUriPermissions.size();
8222             for (int i = 0; i < size; i++) {
8223                 final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.valueAt(i);
8224                 for (UriPermission perm : perms.values()) {
8225                     if (perm.persistedModeFlags != 0) {
8226                         persist.add(perm.snapshot());
8227                     }
8228                 }
8229             }
8230         }
8231
8232         FileOutputStream fos = null;
8233         try {
8234             fos = mGrantFile.startWrite();
8235
8236             XmlSerializer out = new FastXmlSerializer();
8237             out.setOutput(fos, StandardCharsets.UTF_8.name());
8238             out.startDocument(null, true);
8239             out.startTag(null, TAG_URI_GRANTS);
8240             for (UriPermission.Snapshot perm : persist) {
8241                 out.startTag(null, TAG_URI_GRANT);
8242                 writeIntAttribute(out, ATTR_SOURCE_USER_ID, perm.uri.sourceUserId);
8243                 writeIntAttribute(out, ATTR_TARGET_USER_ID, perm.targetUserId);
8244                 out.attribute(null, ATTR_SOURCE_PKG, perm.sourcePkg);
8245                 out.attribute(null, ATTR_TARGET_PKG, perm.targetPkg);
8246                 out.attribute(null, ATTR_URI, String.valueOf(perm.uri.uri));
8247                 writeBooleanAttribute(out, ATTR_PREFIX, perm.uri.prefix);
8248                 writeIntAttribute(out, ATTR_MODE_FLAGS, perm.persistedModeFlags);
8249                 writeLongAttribute(out, ATTR_CREATED_TIME, perm.persistedCreateTime);
8250                 out.endTag(null, TAG_URI_GRANT);
8251             }
8252             out.endTag(null, TAG_URI_GRANTS);
8253             out.endDocument();
8254
8255             mGrantFile.finishWrite(fos);
8256         } catch (IOException e) {
8257             if (fos != null) {
8258                 mGrantFile.failWrite(fos);
8259             }
8260         }
8261     }
8262
8263     private void readGrantedUriPermissionsLocked() {
8264         if (DEBUG_URI_PERMISSION) Slog.v(TAG_URI_PERMISSION, "readGrantedUriPermissions()");
8265
8266         final long now = System.currentTimeMillis();
8267
8268         FileInputStream fis = null;
8269         try {
8270             fis = mGrantFile.openRead();
8271             final XmlPullParser in = Xml.newPullParser();
8272             in.setInput(fis, StandardCharsets.UTF_8.name());
8273
8274             int type;
8275             while ((type = in.next()) != END_DOCUMENT) {
8276                 final String tag = in.getName();
8277                 if (type == START_TAG) {
8278                     if (TAG_URI_GRANT.equals(tag)) {
8279                         final int sourceUserId;
8280                         final int targetUserId;
8281                         final int userHandle = readIntAttribute(in,
8282                                 ATTR_USER_HANDLE, UserHandle.USER_NULL);
8283                         if (userHandle != UserHandle.USER_NULL) {
8284                             // For backwards compatibility.
8285                             sourceUserId = userHandle;
8286                             targetUserId = userHandle;
8287                         } else {
8288                             sourceUserId = readIntAttribute(in, ATTR_SOURCE_USER_ID);
8289                             targetUserId = readIntAttribute(in, ATTR_TARGET_USER_ID);
8290                         }
8291                         final String sourcePkg = in.getAttributeValue(null, ATTR_SOURCE_PKG);
8292                         final String targetPkg = in.getAttributeValue(null, ATTR_TARGET_PKG);
8293                         final Uri uri = Uri.parse(in.getAttributeValue(null, ATTR_URI));
8294                         final boolean prefix = readBooleanAttribute(in, ATTR_PREFIX);
8295                         final int modeFlags = readIntAttribute(in, ATTR_MODE_FLAGS);
8296                         final long createdTime = readLongAttribute(in, ATTR_CREATED_TIME, now);
8297
8298                         // Sanity check that provider still belongs to source package
8299                         final ProviderInfo pi = getProviderInfoLocked(
8300                                 uri.getAuthority(), sourceUserId);
8301                         if (pi != null && sourcePkg.equals(pi.packageName)) {
8302                             int targetUid = -1;
8303                             try {
8304                                 targetUid = AppGlobals.getPackageManager()
8305                                         .getPackageUid(targetPkg, targetUserId);
8306                             } catch (RemoteException e) {
8307                             }
8308                             if (targetUid != -1) {
8309                                 final UriPermission perm = findOrCreateUriPermissionLocked(
8310                                         sourcePkg, targetPkg, targetUid,
8311                                         new GrantUri(sourceUserId, uri, prefix));
8312                                 perm.initPersistedModes(modeFlags, createdTime);
8313                             }
8314                         } else {
8315                             Slog.w(TAG, "Persisted grant for " + uri + " had source " + sourcePkg
8316                                     + " but instead found " + pi);
8317                         }
8318                     }
8319                 }
8320             }
8321         } catch (FileNotFoundException e) {
8322             // Missing grants is okay
8323         } catch (IOException e) {
8324             Slog.wtf(TAG, "Failed reading Uri grants", e);
8325         } catch (XmlPullParserException e) {
8326             Slog.wtf(TAG, "Failed reading Uri grants", e);
8327         } finally {
8328             IoUtils.closeQuietly(fis);
8329         }
8330     }
8331
8332     /**
8333      * @param uri This uri must NOT contain an embedded userId.
8334      * @param userId The userId in which the uri is to be resolved.
8335      */
8336     @Override
8337     public void takePersistableUriPermission(Uri uri, final int modeFlags, int userId) {
8338         enforceNotIsolatedCaller("takePersistableUriPermission");
8339
8340         Preconditions.checkFlagsArgument(modeFlags,
8341                 Intent.FLAG_GRANT_READ_URI_PERMISSION | Intent.FLAG_GRANT_WRITE_URI_PERMISSION);
8342
8343         synchronized (this) {
8344             final int callingUid = Binder.getCallingUid();
8345             boolean persistChanged = false;
8346             GrantUri grantUri = new GrantUri(userId, uri, false);
8347
8348             UriPermission exactPerm = findUriPermissionLocked(callingUid,
8349                     new GrantUri(userId, uri, false));
8350             UriPermission prefixPerm = findUriPermissionLocked(callingUid,
8351                     new GrantUri(userId, uri, true));
8352
8353             final boolean exactValid = (exactPerm != null)
8354                     && ((modeFlags & exactPerm.persistableModeFlags) == modeFlags);
8355             final boolean prefixValid = (prefixPerm != null)
8356                     && ((modeFlags & prefixPerm.persistableModeFlags) == modeFlags);
8357
8358             if (!(exactValid || prefixValid)) {
8359                 throw new SecurityException("No persistable permission grants found for UID "
8360                         + callingUid + " and Uri " + grantUri.toSafeString());
8361             }
8362
8363             if (exactValid) {
8364                 persistChanged |= exactPerm.takePersistableModes(modeFlags);
8365             }
8366             if (prefixValid) {
8367                 persistChanged |= prefixPerm.takePersistableModes(modeFlags);
8368             }
8369
8370             persistChanged |= maybePrunePersistedUriGrantsLocked(callingUid);
8371
8372             if (persistChanged) {
8373                 schedulePersistUriGrants();
8374             }
8375         }
8376     }
8377
8378     /**
8379      * @param uri This uri must NOT contain an embedded userId.
8380      * @param userId The userId in which the uri is to be resolved.
8381      */
8382     @Override
8383     public void releasePersistableUriPermission(Uri uri, final int modeFlags, int userId) {
8384         enforceNotIsolatedCaller("releasePersistableUriPermission");
8385
8386         Preconditions.checkFlagsArgument(modeFlags,
8387                 Intent.FLAG_GRANT_READ_URI_PERMISSION | Intent.FLAG_GRANT_WRITE_URI_PERMISSION);
8388
8389         synchronized (this) {
8390             final int callingUid = Binder.getCallingUid();
8391             boolean persistChanged = false;
8392
8393             UriPermission exactPerm = findUriPermissionLocked(callingUid,
8394                     new GrantUri(userId, uri, false));
8395             UriPermission prefixPerm = findUriPermissionLocked(callingUid,
8396                     new GrantUri(userId, uri, true));
8397             if (exactPerm == null && prefixPerm == null) {
8398                 throw new SecurityException("No permission grants found for UID " + callingUid
8399                         + " and Uri " + uri.toSafeString());
8400             }
8401
8402             if (exactPerm != null) {
8403                 persistChanged |= exactPerm.releasePersistableModes(modeFlags);
8404                 removeUriPermissionIfNeededLocked(exactPerm);
8405             }
8406             if (prefixPerm != null) {
8407                 persistChanged |= prefixPerm.releasePersistableModes(modeFlags);
8408                 removeUriPermissionIfNeededLocked(prefixPerm);
8409             }
8410
8411             if (persistChanged) {
8412                 schedulePersistUriGrants();
8413             }
8414         }
8415     }
8416
8417     /**
8418      * Prune any older {@link UriPermission} for the given UID until outstanding
8419      * persisted grants are below {@link #MAX_PERSISTED_URI_GRANTS}.
8420      *
8421      * @return if any mutations occured that require persisting.
8422      */
8423     private boolean maybePrunePersistedUriGrantsLocked(int uid) {
8424         final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.get(uid);
8425         if (perms == null) return false;
8426         if (perms.size() < MAX_PERSISTED_URI_GRANTS) return false;
8427
8428         final ArrayList<UriPermission> persisted = Lists.newArrayList();
8429         for (UriPermission perm : perms.values()) {
8430             if (perm.persistedModeFlags != 0) {
8431                 persisted.add(perm);
8432             }
8433         }
8434
8435         final int trimCount = persisted.size() - MAX_PERSISTED_URI_GRANTS;
8436         if (trimCount <= 0) return false;
8437
8438         Collections.sort(persisted, new UriPermission.PersistedTimeComparator());
8439         for (int i = 0; i < trimCount; i++) {
8440             final UriPermission perm = persisted.get(i);
8441
8442             if (DEBUG_URI_PERMISSION) Slog.v(TAG_URI_PERMISSION,
8443                     "Trimming grant created at " + perm.persistedCreateTime);
8444
8445             perm.releasePersistableModes(~0);
8446             removeUriPermissionIfNeededLocked(perm);
8447         }
8448
8449         return true;
8450     }
8451
8452     @Override
8453     public ParceledListSlice<android.content.UriPermission> getPersistedUriPermissions(
8454             String packageName, boolean incoming) {
8455         enforceNotIsolatedCaller("getPersistedUriPermissions");
8456         Preconditions.checkNotNull(packageName, "packageName");
8457
8458         final int callingUid = Binder.getCallingUid();
8459         final IPackageManager pm = AppGlobals.getPackageManager();
8460         try {
8461             final int packageUid = pm.getPackageUid(packageName, UserHandle.getUserId(callingUid));
8462             if (packageUid != callingUid) {
8463                 throw new SecurityException(
8464                         "Package " + packageName + " does not belong to calling UID " + callingUid);
8465             }
8466         } catch (RemoteException e) {
8467             throw new SecurityException("Failed to verify package name ownership");
8468         }
8469
8470         final ArrayList<android.content.UriPermission> result = Lists.newArrayList();
8471         synchronized (this) {
8472             if (incoming) {
8473                 final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.get(
8474                         callingUid);
8475                 if (perms == null) {
8476                     Slog.w(TAG, "No permission grants found for " + packageName);
8477                 } else {
8478                     for (UriPermission perm : perms.values()) {
8479                         if (packageName.equals(perm.targetPkg) && perm.persistedModeFlags != 0) {
8480                             result.add(perm.buildPersistedPublicApiObject());
8481                         }
8482                     }
8483                 }
8484             } else {
8485                 final int size = mGrantedUriPermissions.size();
8486                 for (int i = 0; i < size; i++) {
8487                     final ArrayMap<GrantUri, UriPermission> perms =
8488                             mGrantedUriPermissions.valueAt(i);
8489                     for (UriPermission perm : perms.values()) {
8490                         if (packageName.equals(perm.sourcePkg) && perm.persistedModeFlags != 0) {
8491                             result.add(perm.buildPersistedPublicApiObject());
8492                         }
8493                     }
8494                 }
8495             }
8496         }
8497         return new ParceledListSlice<android.content.UriPermission>(result);
8498     }
8499
8500     @Override
8501     public void showWaitingForDebugger(IApplicationThread who, boolean waiting) {
8502         synchronized (this) {
8503             ProcessRecord app =
8504                 who != null ? getRecordForAppLocked(who) : null;
8505             if (app == null) return;
8506
8507             Message msg = Message.obtain();
8508             msg.what = WAIT_FOR_DEBUGGER_UI_MSG;
8509             msg.obj = app;
8510             msg.arg1 = waiting ? 1 : 0;
8511             mUiHandler.sendMessage(msg);
8512         }
8513     }
8514
8515     @Override
8516     public void getMemoryInfo(ActivityManager.MemoryInfo outInfo) {
8517         final long homeAppMem = mProcessList.getMemLevel(ProcessList.HOME_APP_ADJ);
8518         final long cachedAppMem = mProcessList.getMemLevel(ProcessList.CACHED_APP_MIN_ADJ);
8519         outInfo.availMem = Process.getFreeMemory();
8520         outInfo.totalMem = Process.getTotalMemory();
8521         outInfo.threshold = homeAppMem;
8522         outInfo.lowMemory = outInfo.availMem < (homeAppMem + ((cachedAppMem-homeAppMem)/2));
8523         outInfo.hiddenAppThreshold = cachedAppMem;
8524         outInfo.secondaryServerThreshold = mProcessList.getMemLevel(
8525                 ProcessList.SERVICE_ADJ);
8526         outInfo.visibleAppThreshold = mProcessList.getMemLevel(
8527                 ProcessList.VISIBLE_APP_ADJ);
8528         outInfo.foregroundAppThreshold = mProcessList.getMemLevel(
8529                 ProcessList.FOREGROUND_APP_ADJ);
8530     }
8531
8532     // =========================================================
8533     // TASK MANAGEMENT
8534     // =========================================================
8535
8536     @Override
8537     public List<IAppTask> getAppTasks(String callingPackage) {
8538         int callingUid = Binder.getCallingUid();
8539         long ident = Binder.clearCallingIdentity();
8540
8541         synchronized(this) {
8542             ArrayList<IAppTask> list = new ArrayList<IAppTask>();
8543             try {
8544                 if (DEBUG_ALL) Slog.v(TAG, "getAppTasks");
8545
8546                 final int N = mRecentTasks.size();
8547                 for (int i = 0; i < N; i++) {
8548                     TaskRecord tr = mRecentTasks.get(i);
8549                     // Skip tasks that do not match the caller.  We don't need to verify
8550                     // callingPackage, because we are also limiting to callingUid and know
8551                     // that will limit to the correct security sandbox.
8552                     if (tr.effectiveUid != callingUid) {
8553                         continue;
8554                     }
8555                     Intent intent = tr.getBaseIntent();
8556                     if (intent == null ||
8557                             !callingPackage.equals(intent.getComponent().getPackageName())) {
8558                         continue;
8559                     }
8560                     ActivityManager.RecentTaskInfo taskInfo =
8561                             createRecentTaskInfoFromTaskRecord(tr);
8562                     AppTaskImpl taskImpl = new AppTaskImpl(taskInfo.persistentId, callingUid);
8563                     list.add(taskImpl);
8564                 }
8565             } finally {
8566                 Binder.restoreCallingIdentity(ident);
8567             }
8568             return list;
8569         }
8570     }
8571
8572     @Override
8573     public List<RunningTaskInfo> getTasks(int maxNum, int flags) {
8574         final int callingUid = Binder.getCallingUid();
8575         ArrayList<RunningTaskInfo> list = new ArrayList<RunningTaskInfo>();
8576
8577         synchronized(this) {
8578             if (DEBUG_ALL) Slog.v(
8579                 TAG, "getTasks: max=" + maxNum + ", flags=" + flags);
8580
8581             final boolean allowed = isGetTasksAllowed("getTasks", Binder.getCallingPid(),
8582                     callingUid);
8583
8584             // TODO: Improve with MRU list from all ActivityStacks.
8585             mStackSupervisor.getTasksLocked(maxNum, list, callingUid, allowed);
8586         }
8587
8588         return list;
8589     }
8590
8591     /**
8592      * Creates a new RecentTaskInfo from a TaskRecord.
8593      */
8594     private ActivityManager.RecentTaskInfo createRecentTaskInfoFromTaskRecord(TaskRecord tr) {
8595         // Update the task description to reflect any changes in the task stack
8596         tr.updateTaskDescription();
8597
8598         // Compose the recent task info
8599         ActivityManager.RecentTaskInfo rti = new ActivityManager.RecentTaskInfo();
8600         rti.id = tr.getTopActivity() == null ? INVALID_TASK_ID : tr.taskId;
8601         rti.persistentId = tr.taskId;
8602         rti.baseIntent = new Intent(tr.getBaseIntent());
8603         rti.origActivity = tr.origActivity;
8604         rti.realActivity = tr.realActivity;
8605         rti.description = tr.lastDescription;
8606         rti.stackId = tr.stack != null ? tr.stack.mStackId : -1;
8607         rti.userId = tr.userId;
8608         rti.taskDescription = new ActivityManager.TaskDescription(tr.lastTaskDescription);
8609         rti.firstActiveTime = tr.firstActiveTime;
8610         rti.lastActiveTime = tr.lastActiveTime;
8611         rti.affiliatedTaskId = tr.mAffiliatedTaskId;
8612         rti.affiliatedTaskColor = tr.mAffiliatedTaskColor;
8613         rti.numActivities = 0;
8614         if (tr.mBounds != null) {
8615             rti.bounds = new Rect(tr.mBounds);
8616         }
8617
8618         ActivityRecord base = null;
8619         ActivityRecord top = null;
8620         ActivityRecord tmp;
8621
8622         for (int i = tr.mActivities.size() - 1; i >= 0; --i) {
8623             tmp = tr.mActivities.get(i);
8624             if (tmp.finishing) {
8625                 continue;
8626             }
8627             base = tmp;
8628             if (top == null || (top.state == ActivityState.INITIALIZING)) {
8629                 top = base;
8630             }
8631             rti.numActivities++;
8632         }
8633
8634         rti.baseActivity = (base != null) ? base.intent.getComponent() : null;
8635         rti.topActivity = (top != null) ? top.intent.getComponent() : null;
8636
8637         return rti;
8638     }
8639
8640     private boolean isGetTasksAllowed(String caller, int callingPid, int callingUid) {
8641         boolean allowed = checkPermission(android.Manifest.permission.REAL_GET_TASKS,
8642                 callingPid, callingUid) == PackageManager.PERMISSION_GRANTED;
8643         if (!allowed) {
8644             if (checkPermission(android.Manifest.permission.GET_TASKS,
8645                     callingPid, callingUid) == PackageManager.PERMISSION_GRANTED) {
8646                 // Temporary compatibility: some existing apps on the system image may
8647                 // still be requesting the old permission and not switched to the new
8648                 // one; if so, we'll still allow them full access.  This means we need
8649                 // to see if they are holding the old permission and are a system app.
8650                 try {
8651                     if (AppGlobals.getPackageManager().isUidPrivileged(callingUid)) {
8652                         allowed = true;
8653                         if (DEBUG_TASKS) Slog.w(TAG, caller + ": caller " + callingUid
8654                                 + " is using old GET_TASKS but privileged; allowing");
8655                     }
8656                 } catch (RemoteException e) {
8657                 }
8658             }
8659         }
8660         if (!allowed) {
8661             if (DEBUG_TASKS) Slog.w(TAG, caller + ": caller " + callingUid
8662                     + " does not hold REAL_GET_TASKS; limiting output");
8663         }
8664         return allowed;
8665     }
8666
8667     @Override
8668     public List<ActivityManager.RecentTaskInfo> getRecentTasks(int maxNum, int flags, int userId) {
8669         final int callingUid = Binder.getCallingUid();
8670         userId = mUserController.handleIncomingUser(Binder.getCallingPid(), callingUid, userId,
8671                 false, ALLOW_FULL_ONLY, "getRecentTasks", null);
8672
8673         final boolean includeProfiles = (flags & ActivityManager.RECENT_INCLUDE_PROFILES) != 0;
8674         final boolean withExcluded = (flags&ActivityManager.RECENT_WITH_EXCLUDED) != 0;
8675         synchronized (this) {
8676             final boolean allowed = isGetTasksAllowed("getRecentTasks", Binder.getCallingPid(),
8677                     callingUid);
8678             final boolean detailed = checkCallingPermission(
8679                     android.Manifest.permission.GET_DETAILED_TASKS)
8680                     == PackageManager.PERMISSION_GRANTED;
8681
8682             final int recentsCount = mRecentTasks.size();
8683             ArrayList<ActivityManager.RecentTaskInfo> res =
8684                     new ArrayList<>(maxNum < recentsCount ? maxNum : recentsCount);
8685
8686             final Set<Integer> includedUsers;
8687             if (includeProfiles) {
8688                 includedUsers = mUserController.getProfileIds(userId);
8689             } else {
8690                 includedUsers = new HashSet<>();
8691             }
8692             includedUsers.add(Integer.valueOf(userId));
8693
8694             for (int i = 0; i < recentsCount && maxNum > 0; i++) {
8695                 TaskRecord tr = mRecentTasks.get(i);
8696                 // Only add calling user or related users recent tasks
8697                 if (!includedUsers.contains(Integer.valueOf(tr.userId))) {
8698                     if (DEBUG_RECENTS) Slog.d(TAG_RECENTS, "Skipping, not user: " + tr);
8699                     continue;
8700                 }
8701
8702                 // Return the entry if desired by the caller.  We always return
8703                 // the first entry, because callers always expect this to be the
8704                 // foreground app.  We may filter others if the caller has
8705                 // not supplied RECENT_WITH_EXCLUDED and there is some reason
8706                 // we should exclude the entry.
8707
8708                 if (i == 0
8709                         || withExcluded
8710                         || (tr.intent == null)
8711                         || ((tr.intent.getFlags() & Intent.FLAG_ACTIVITY_EXCLUDE_FROM_RECENTS)
8712                                 == 0)) {
8713                     if (!allowed) {
8714                         // If the caller doesn't have the GET_TASKS permission, then only
8715                         // allow them to see a small subset of tasks -- their own and home.
8716                         if (!tr.isHomeTask() && tr.effectiveUid != callingUid) {
8717                             if (DEBUG_RECENTS) Slog.d(TAG_RECENTS, "Skipping, not allowed: " + tr);
8718                             continue;
8719                         }
8720                     }
8721                     if ((flags & ActivityManager.RECENT_IGNORE_HOME_STACK_TASKS) != 0) {
8722                         if (tr.stack != null && tr.stack.isHomeStack()) {
8723                             if (DEBUG_RECENTS) Slog.d(TAG_RECENTS,
8724                                     "Skipping, home stack task: " + tr);
8725                             continue;
8726                         }
8727                     }
8728                     if (tr.autoRemoveRecents && tr.getTopActivity() == null) {
8729                         // Don't include auto remove tasks that are finished or finishing.
8730                         if (DEBUG_RECENTS) Slog.d(TAG_RECENTS,
8731                                 "Skipping, auto-remove without activity: " + tr);
8732                         continue;
8733                     }
8734                     if ((flags&ActivityManager.RECENT_IGNORE_UNAVAILABLE) != 0
8735                             && !tr.isAvailable) {
8736                         if (DEBUG_RECENTS) Slog.d(TAG_RECENTS,
8737                                 "Skipping, unavail real act: " + tr);
8738                         continue;
8739                     }
8740
8741                     ActivityManager.RecentTaskInfo rti = createRecentTaskInfoFromTaskRecord(tr);
8742                     if (!detailed) {
8743                         rti.baseIntent.replaceExtras((Bundle)null);
8744                     }
8745
8746                     res.add(rti);
8747                     maxNum--;
8748                 }
8749             }
8750             return res;
8751         }
8752     }
8753
8754     @Override
8755     public ActivityManager.TaskThumbnail getTaskThumbnail(int id) {
8756         synchronized (this) {
8757             enforceCallingPermission(android.Manifest.permission.READ_FRAME_BUFFER,
8758                     "getTaskThumbnail()");
8759             final TaskRecord tr = mStackSupervisor.anyTaskForIdLocked(
8760                     id, !RESTORE_FROM_RECENTS, INVALID_STACK_ID);
8761             if (tr != null) {
8762                 return tr.getTaskThumbnailLocked();
8763             }
8764         }
8765         return null;
8766     }
8767
8768     @Override
8769     public int addAppTask(IBinder activityToken, Intent intent,
8770             ActivityManager.TaskDescription description, Bitmap thumbnail) throws RemoteException {
8771         final int callingUid = Binder.getCallingUid();
8772         final long callingIdent = Binder.clearCallingIdentity();
8773
8774         try {
8775             synchronized (this) {
8776                 ActivityRecord r = ActivityRecord.isInStackLocked(activityToken);
8777                 if (r == null) {
8778                     throw new IllegalArgumentException("Activity does not exist; token="
8779                             + activityToken);
8780                 }
8781                 ComponentName comp = intent.getComponent();
8782                 if (comp == null) {
8783                     throw new IllegalArgumentException("Intent " + intent
8784                             + " must specify explicit component");
8785                 }
8786                 if (thumbnail.getWidth() != mThumbnailWidth
8787                         || thumbnail.getHeight() != mThumbnailHeight) {
8788                     throw new IllegalArgumentException("Bad thumbnail size: got "
8789                             + thumbnail.getWidth() + "x" + thumbnail.getHeight() + ", require "
8790                             + mThumbnailWidth + "x" + mThumbnailHeight);
8791                 }
8792                 if (intent.getSelector() != null) {
8793                     intent.setSelector(null);
8794                 }
8795                 if (intent.getSourceBounds() != null) {
8796                     intent.setSourceBounds(null);
8797                 }
8798                 if ((intent.getFlags()&Intent.FLAG_ACTIVITY_NEW_DOCUMENT) != 0) {
8799                     if ((intent.getFlags()&Intent.FLAG_ACTIVITY_RETAIN_IN_RECENTS) == 0) {
8800                         // The caller has added this as an auto-remove task...  that makes no
8801                         // sense, so turn off auto-remove.
8802                         intent.addFlags(Intent.FLAG_ACTIVITY_RETAIN_IN_RECENTS);
8803                     }
8804                 } else if ((intent.getFlags()&Intent.FLAG_ACTIVITY_NEW_TASK) != 0) {
8805                     // Must be a new task.
8806                     intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
8807                 }
8808                 if (!comp.equals(mLastAddedTaskComponent) || callingUid != mLastAddedTaskUid) {
8809                     mLastAddedTaskActivity = null;
8810                 }
8811                 ActivityInfo ainfo = mLastAddedTaskActivity;
8812                 if (ainfo == null) {
8813                     ainfo = mLastAddedTaskActivity = AppGlobals.getPackageManager().getActivityInfo(
8814                             comp, 0, UserHandle.getUserId(callingUid));
8815                     if (ainfo.applicationInfo.uid != callingUid) {
8816                         throw new SecurityException(
8817                                 "Can't add task for another application: target uid="
8818                                 + ainfo.applicationInfo.uid + ", calling uid=" + callingUid);
8819                     }
8820                 }
8821
8822                 // Use the full screen as the context for the task thumbnail
8823                 final Point displaySize = new Point();
8824                 final TaskThumbnailInfo thumbnailInfo = new TaskThumbnailInfo();
8825                 r.task.stack.getDisplaySize(displaySize);
8826                 thumbnailInfo.taskWidth = displaySize.x;
8827                 thumbnailInfo.taskHeight = displaySize.y;
8828                 thumbnailInfo.screenOrientation = mConfiguration.orientation;
8829
8830                 TaskRecord task = new TaskRecord(this, mStackSupervisor.getNextTaskId(), ainfo,
8831                         intent, description, thumbnailInfo);
8832
8833                 int trimIdx = mRecentTasks.trimForTaskLocked(task, false);
8834                 if (trimIdx >= 0) {
8835                     // If this would have caused a trim, then we'll abort because that
8836                     // means it would be added at the end of the list but then just removed.
8837                     return INVALID_TASK_ID;
8838                 }
8839
8840                 final int N = mRecentTasks.size();
8841                 if (N >= (ActivityManager.getMaxRecentTasksStatic()-1)) {
8842                     final TaskRecord tr = mRecentTasks.remove(N - 1);
8843                     tr.removedFromRecents();
8844                 }
8845
8846                 task.inRecents = true;
8847                 mRecentTasks.add(task);
8848                 r.task.stack.addTask(task, false, false);
8849
8850                 task.setLastThumbnailLocked(thumbnail);
8851                 task.freeLastThumbnail();
8852
8853                 return task.taskId;
8854             }
8855         } finally {
8856             Binder.restoreCallingIdentity(callingIdent);
8857         }
8858     }
8859
8860     @Override
8861     public Point getAppTaskThumbnailSize() {
8862         synchronized (this) {
8863             return new Point(mThumbnailWidth,  mThumbnailHeight);
8864         }
8865     }
8866
8867     @Override
8868     public void setTaskDescription(IBinder token, ActivityManager.TaskDescription td) {
8869         synchronized (this) {
8870             ActivityRecord r = ActivityRecord.isInStackLocked(token);
8871             if (r != null) {
8872                 r.setTaskDescription(td);
8873                 r.task.updateTaskDescription();
8874             }
8875         }
8876     }
8877
8878     @Override
8879     public void setTaskResizeable(int taskId, boolean resizeable) {
8880         synchronized (this) {
8881             final TaskRecord task = mStackSupervisor.anyTaskForIdLocked(
8882                     taskId, !RESTORE_FROM_RECENTS, INVALID_STACK_ID);
8883             if (task == null) {
8884                 Slog.w(TAG, "setTaskResizeable: taskId=" + taskId + " not found");
8885                 return;
8886             }
8887             if (task.mResizeable != resizeable) {
8888                 task.mResizeable = resizeable;
8889                 mWindowManager.setTaskResizeable(taskId, resizeable);
8890                 mStackSupervisor.ensureActivitiesVisibleLocked(null, 0, !PRESERVE_WINDOWS);
8891                 mStackSupervisor.resumeTopActivitiesLocked();
8892             }
8893         }
8894     }
8895
8896     @Override
8897     public void resizeTask(int taskId, Rect bounds, int resizeMode) {
8898         enforceCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS,
8899                 "resizeTask()");
8900         long ident = Binder.clearCallingIdentity();
8901         try {
8902             synchronized (this) {
8903                 TaskRecord task = mStackSupervisor.anyTaskForIdLocked(taskId);
8904                 if (task == null) {
8905                     Slog.w(TAG, "resizeTask: taskId=" + taskId + " not found");
8906                     return;
8907                 }
8908                 int stackId = task.stack.mStackId;
8909                 // First, check if this is a non-resizeble task in docked stack or if the task size
8910                 // is affected by the docked stack changing size. If so, instead of resizing, we
8911                 // can only scroll the task. No need to update configuration.
8912                 if (bounds != null && !task.mResizeable
8913                         && mStackSupervisor.isStackDockedInEffect(stackId)) {
8914                     mWindowManager.scrollTask(task.taskId, bounds);
8915                     return;
8916                 }
8917
8918                 // Place the task in the right stack if it isn't there already based on
8919                 // the requested bounds.
8920                 // The stack transition logic is:
8921                 // - a null bounds on a freeform task moves that task to fullscreen
8922                 // - a non-null bounds on a non-freeform (fullscreen OR docked) task moves
8923                 //   that task to freeform
8924                 // - otherwise the task is not moved
8925                 if (!StackId.isTaskResizeAllowed(stackId)) {
8926                     throw new IllegalArgumentException("resizeTask not allowed on task=" + task);
8927                 }
8928                 if (bounds == null && stackId == FREEFORM_WORKSPACE_STACK_ID) {
8929                     stackId = FULLSCREEN_WORKSPACE_STACK_ID;
8930                 } else if (bounds != null && stackId != FREEFORM_WORKSPACE_STACK_ID ) {
8931                     stackId = FREEFORM_WORKSPACE_STACK_ID;
8932                 }
8933                 boolean preserveWindow = (resizeMode & RESIZE_MODE_PRESERVE_WINDOW) != 0;
8934                 if (stackId != task.stack.mStackId) {
8935                     mStackSupervisor.moveTaskToStackUncheckedLocked(
8936                             task, stackId, ON_TOP, !FORCE_FOCUS, "resizeTask");
8937                     preserveWindow = false;
8938                 }
8939
8940                 mStackSupervisor.resizeTaskLocked(task, bounds, resizeMode, preserveWindow);
8941             }
8942         } finally {
8943             Binder.restoreCallingIdentity(ident);
8944         }
8945     }
8946
8947     @Override
8948     public Rect getTaskBounds(int taskId) {
8949         enforceCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS,
8950                 "getTaskBounds()");
8951         long ident = Binder.clearCallingIdentity();
8952         Rect rect = new Rect();
8953         try {
8954             synchronized (this) {
8955                 final TaskRecord task = mStackSupervisor.anyTaskForIdLocked(
8956                         taskId, !RESTORE_FROM_RECENTS, INVALID_STACK_ID);
8957                 if (task == null) {
8958                     Slog.w(TAG, "getTaskBounds: taskId=" + taskId + " not found");
8959                     return rect;
8960                 }
8961                 if (task.stack != null) {
8962                     // Return the bounds from window manager since it will be adjusted for various
8963                     // things like the presense of a docked stack for tasks that aren't resizeable.
8964                     mWindowManager.getTaskBounds(task.taskId, rect);
8965                 } else {
8966                     // Task isn't in window manager yet since it isn't associated with a stack.
8967                     // Return the persist value from activity manager
8968                     if (task.mBounds != null) {
8969                         rect.set(task.mBounds);
8970                     } else if (task.mLastNonFullscreenBounds != null) {
8971                         rect.set(task.mLastNonFullscreenBounds);
8972                     }
8973                 }
8974             }
8975         } finally {
8976             Binder.restoreCallingIdentity(ident);
8977         }
8978         return rect;
8979     }
8980
8981     @Override
8982     public Bitmap getTaskDescriptionIcon(String filePath, int userId) {
8983         if (userId != UserHandle.getCallingUserId()) {
8984             enforceCallingPermission(android.Manifest.permission.INTERACT_ACROSS_USERS_FULL,
8985                     "getTaskDescriptionIcon");
8986         }
8987         final File passedIconFile = new File(filePath);
8988         final File legitIconFile = new File(TaskPersister.getUserImagesDir(userId),
8989                 passedIconFile.getName());
8990         if (!legitIconFile.getPath().equals(filePath)
8991                 || !filePath.contains(ActivityRecord.ACTIVITY_ICON_SUFFIX)) {
8992             throw new IllegalArgumentException("Bad file path: " + filePath);
8993         }
8994         return mTaskPersister.getTaskDescriptionIcon(filePath);
8995     }
8996
8997     @Override
8998     public void startInPlaceAnimationOnFrontMostApplication(ActivityOptions opts)
8999             throws RemoteException {
9000         if (opts.getAnimationType() != ActivityOptions.ANIM_CUSTOM_IN_PLACE ||
9001                 opts.getCustomInPlaceResId() == 0) {
9002             throw new IllegalArgumentException("Expected in-place ActivityOption " +
9003                     "with valid animation");
9004         }
9005         mWindowManager.prepareAppTransition(AppTransition.TRANSIT_TASK_IN_PLACE, false);
9006         mWindowManager.overridePendingAppTransitionInPlace(opts.getPackageName(),
9007                 opts.getCustomInPlaceResId());
9008         mWindowManager.executeAppTransition();
9009     }
9010
9011     private void cleanUpRemovedTaskLocked(TaskRecord tr, boolean killProcess,
9012             boolean removeFromRecents) {
9013         if (removeFromRecents) {
9014             mRecentTasks.remove(tr);
9015             tr.removedFromRecents();
9016         }
9017         ComponentName component = tr.getBaseIntent().getComponent();
9018         if (component == null) {
9019             Slog.w(TAG, "No component for base intent of task: " + tr);
9020             return;
9021         }
9022
9023         // Find any running services associated with this app and stop if needed.
9024         mServices.cleanUpRemovedTaskLocked(tr, component, new Intent(tr.getBaseIntent()));
9025
9026         if (!killProcess) {
9027             return;
9028         }
9029
9030         // Determine if the process(es) for this task should be killed.
9031         final String pkg = component.getPackageName();
9032         ArrayList<ProcessRecord> procsToKill = new ArrayList<>();
9033         ArrayMap<String, SparseArray<ProcessRecord>> pmap = mProcessNames.getMap();
9034         for (int i = 0; i < pmap.size(); i++) {
9035
9036             SparseArray<ProcessRecord> uids = pmap.valueAt(i);
9037             for (int j = 0; j < uids.size(); j++) {
9038                 ProcessRecord proc = uids.valueAt(j);
9039                 if (proc.userId != tr.userId) {
9040                     // Don't kill process for a different user.
9041                     continue;
9042                 }
9043                 if (proc == mHomeProcess) {
9044                     // Don't kill the home process along with tasks from the same package.
9045                     continue;
9046                 }
9047                 if (!proc.pkgList.containsKey(pkg)) {
9048                     // Don't kill process that is not associated with this task.
9049                     continue;
9050                 }
9051
9052                 for (int k = 0; k < proc.activities.size(); k++) {
9053                     TaskRecord otherTask = proc.activities.get(k).task;
9054                     if (tr.taskId != otherTask.taskId && otherTask.inRecents) {
9055                         // Don't kill process(es) that has an activity in a different task that is
9056                         // also in recents.
9057                         return;
9058                     }
9059                 }
9060
9061                 if (proc.foregroundServices) {
9062                     // Don't kill process(es) with foreground service.
9063                     return;
9064                 }
9065
9066                 // Add process to kill list.
9067                 procsToKill.add(proc);
9068             }
9069         }
9070
9071         // Kill the running processes.
9072         for (int i = 0; i < procsToKill.size(); i++) {
9073             ProcessRecord pr = procsToKill.get(i);
9074             if (pr.setSchedGroup == Process.THREAD_GROUP_BG_NONINTERACTIVE
9075                     && pr.curReceiver == null) {
9076                 pr.kill("remove task", true);
9077             } else {
9078                 // We delay killing processes that are not in the background or running a receiver.
9079                 pr.waitingToKill = "remove task";
9080             }
9081         }
9082     }
9083
9084     private void removeTasksByPackageNameLocked(String packageName, int userId) {
9085         // Remove all tasks with activities in the specified package from the list of recent tasks
9086         for (int i = mRecentTasks.size() - 1; i >= 0; i--) {
9087             TaskRecord tr = mRecentTasks.get(i);
9088             if (tr.userId != userId) continue;
9089
9090             ComponentName cn = tr.intent.getComponent();
9091             if (cn != null && cn.getPackageName().equals(packageName)) {
9092                 // If the package name matches, remove the task.
9093                 removeTaskByIdLocked(tr.taskId, true, REMOVE_FROM_RECENTS);
9094             }
9095         }
9096     }
9097
9098     private void cleanupDisabledPackageTasksLocked(String packageName, Set<String> filterByClasses,
9099             int userId) {
9100
9101         for (int i = mRecentTasks.size() - 1; i >= 0; i--) {
9102             TaskRecord tr = mRecentTasks.get(i);
9103             if (userId != UserHandle.USER_ALL && tr.userId != userId) {
9104                 continue;
9105             }
9106
9107             ComponentName cn = tr.intent.getComponent();
9108             final boolean sameComponent = cn != null && cn.getPackageName().equals(packageName)
9109                     && (filterByClasses == null || filterByClasses.contains(cn.getClassName()));
9110             if (sameComponent) {
9111                 removeTaskByIdLocked(tr.taskId, false, REMOVE_FROM_RECENTS);
9112             }
9113         }
9114     }
9115
9116     /**
9117      * Removes the task with the specified task id.
9118      *
9119      * @param taskId Identifier of the task to be removed.
9120      * @param killProcess Kill any process associated with the task if possible.
9121      * @param removeFromRecents Whether to also remove the task from recents.
9122      * @return Returns true if the given task was found and removed.
9123      */
9124     private boolean removeTaskByIdLocked(int taskId, boolean killProcess,
9125             boolean removeFromRecents) {
9126         final TaskRecord tr = mStackSupervisor.anyTaskForIdLocked(
9127                 taskId, !RESTORE_FROM_RECENTS, INVALID_STACK_ID);
9128         if (tr != null) {
9129             tr.removeTaskActivitiesLocked();
9130             cleanUpRemovedTaskLocked(tr, killProcess, removeFromRecents);
9131             if (tr.isPersistable) {
9132                 notifyTaskPersisterLocked(null, true);
9133             }
9134             return true;
9135         }
9136         Slog.w(TAG, "Request to remove task ignored for non-existent task " + taskId);
9137         return false;
9138     }
9139
9140     @Override
9141     public boolean removeTask(int taskId) {
9142         synchronized (this) {
9143             enforceCallingPermission(android.Manifest.permission.REMOVE_TASKS,
9144                     "removeTask()");
9145             long ident = Binder.clearCallingIdentity();
9146             try {
9147                 return removeTaskByIdLocked(taskId, true, REMOVE_FROM_RECENTS);
9148             } finally {
9149                 Binder.restoreCallingIdentity(ident);
9150             }
9151         }
9152     }
9153
9154     /**
9155      * TODO: Add mController hook
9156      */
9157     @Override
9158     public void moveTaskToFront(int taskId, int flags, Bundle bOptions) {
9159         enforceCallingPermission(android.Manifest.permission.REORDER_TASKS, "moveTaskToFront()");
9160
9161         if (DEBUG_STACK) Slog.d(TAG_STACK, "moveTaskToFront: moving taskId=" + taskId);
9162         synchronized(this) {
9163             moveTaskToFrontLocked(taskId, flags, bOptions);
9164         }
9165     }
9166
9167     void moveTaskToFrontLocked(int taskId, int flags, Bundle bOptions) {
9168         ActivityOptions options = ActivityOptions.fromBundle(bOptions);
9169
9170         if (!checkAppSwitchAllowedLocked(Binder.getCallingPid(),
9171                 Binder.getCallingUid(), -1, -1, "Task to front")) {
9172             ActivityOptions.abort(options);
9173             return;
9174         }
9175         final long origId = Binder.clearCallingIdentity();
9176         try {
9177             final TaskRecord task = mStackSupervisor.anyTaskForIdLocked(taskId);
9178             if (task == null) {
9179                 Slog.d(TAG, "Could not find task for id: "+ taskId);
9180                 return;
9181             }
9182             if (mStackSupervisor.isLockTaskModeViolation(task)) {
9183                 mStackSupervisor.showLockTaskToast();
9184                 Slog.e(TAG, "moveTaskToFront: Attempt to violate Lock Task Mode");
9185                 return;
9186             }
9187             final ActivityRecord prev = mStackSupervisor.topRunningActivityLocked();
9188             if (prev != null && prev.isRecentsActivity()) {
9189                 task.setTaskToReturnTo(ActivityRecord.RECENTS_ACTIVITY_TYPE);
9190             }
9191             mStackSupervisor.findTaskToMoveToFrontLocked(task, flags, options, "moveTaskToFront");
9192         } finally {
9193             Binder.restoreCallingIdentity(origId);
9194         }
9195         ActivityOptions.abort(options);
9196     }
9197
9198     /**
9199      * Moves an activity, and all of the other activities within the same task, to the bottom
9200      * of the history stack.  The activity's order within the task is unchanged.
9201      *
9202      * @param token A reference to the activity we wish to move
9203      * @param nonRoot If false then this only works if the activity is the root
9204      *                of a task; if true it will work for any activity in a task.
9205      * @return Returns true if the move completed, false if not.
9206      */
9207     @Override
9208     public boolean moveActivityTaskToBack(IBinder token, boolean nonRoot) {
9209         enforceNotIsolatedCaller("moveActivityTaskToBack");
9210         synchronized(this) {
9211             final long origId = Binder.clearCallingIdentity();
9212             try {
9213                 int taskId = ActivityRecord.getTaskForActivityLocked(token, !nonRoot);
9214                 final TaskRecord task = mStackSupervisor.anyTaskForIdLocked(taskId);
9215                 if (task != null) {
9216                     if (mStackSupervisor.isLockedTask(task)) {
9217                         mStackSupervisor.showLockTaskToast();
9218                         return false;
9219                     }
9220                     return ActivityRecord.getStackLocked(token).moveTaskToBackLocked(taskId);
9221                 }
9222             } finally {
9223                 Binder.restoreCallingIdentity(origId);
9224             }
9225         }
9226         return false;
9227     }
9228
9229     @Override
9230     public void moveTaskBackwards(int task) {
9231         enforceCallingPermission(android.Manifest.permission.REORDER_TASKS,
9232                 "moveTaskBackwards()");
9233
9234         synchronized(this) {
9235             if (!checkAppSwitchAllowedLocked(Binder.getCallingPid(),
9236                     Binder.getCallingUid(), -1, -1, "Task backwards")) {
9237                 return;
9238             }
9239             final long origId = Binder.clearCallingIdentity();
9240             moveTaskBackwardsLocked(task);
9241             Binder.restoreCallingIdentity(origId);
9242         }
9243     }
9244
9245     private final void moveTaskBackwardsLocked(int task) {
9246         Slog.e(TAG, "moveTaskBackwards not yet implemented!");
9247     }
9248
9249     @Override
9250     public IActivityContainer createVirtualActivityContainer(IBinder parentActivityToken,
9251             IActivityContainerCallback callback) throws RemoteException {
9252         enforceCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS,
9253                 "createActivityContainer()");
9254         synchronized (this) {
9255             if (parentActivityToken == null) {
9256                 throw new IllegalArgumentException("parent token must not be null");
9257             }
9258             ActivityRecord r = ActivityRecord.forTokenLocked(parentActivityToken);
9259             if (r == null) {
9260                 return null;
9261             }
9262             if (callback == null) {
9263                 throw new IllegalArgumentException("callback must not be null");
9264             }
9265             return mStackSupervisor.createVirtualActivityContainer(r, callback);
9266         }
9267     }
9268
9269     @Override
9270     public void deleteActivityContainer(IActivityContainer container) throws RemoteException {
9271         enforceCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS,
9272                 "deleteActivityContainer()");
9273         synchronized (this) {
9274             mStackSupervisor.deleteActivityContainer(container);
9275         }
9276     }
9277
9278     @Override
9279     public IActivityContainer createStackOnDisplay(int displayId) throws RemoteException {
9280         enforceCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS,
9281                 "createStackOnDisplay()");
9282         synchronized (this) {
9283             final int stackId = mStackSupervisor.getNextStackId();
9284             final ActivityStack stack =
9285                     mStackSupervisor.createStackOnDisplay(stackId, displayId, true /*onTop*/);
9286             if (stack == null) {
9287                 return null;
9288             }
9289             return stack.mActivityContainer;
9290         }
9291     }
9292
9293     @Override
9294     public int getActivityDisplayId(IBinder activityToken) throws RemoteException {
9295         synchronized (this) {
9296             ActivityStack stack = ActivityRecord.getStackLocked(activityToken);
9297             if (stack != null && stack.mActivityContainer.isAttachedLocked()) {
9298                 return stack.mActivityContainer.getDisplayId();
9299             }
9300             return Display.DEFAULT_DISPLAY;
9301         }
9302     }
9303
9304     @Override
9305     public int getActivityStackId(IBinder token) throws RemoteException {
9306         synchronized (this) {
9307             ActivityStack stack = ActivityRecord.getStackLocked(token);
9308             if (stack == null) {
9309                 return INVALID_STACK_ID;
9310             }
9311             return stack.mStackId;
9312         }
9313     }
9314
9315     @Override
9316     public void moveActivityToStack(IBinder token, int stackId) throws RemoteException {
9317         if (stackId == HOME_STACK_ID) {
9318             throw new IllegalArgumentException(
9319                     "moveActivityToStack: Attempt to move token " + token + " to home stack");
9320         }
9321         synchronized (this) {
9322             long ident = Binder.clearCallingIdentity();
9323             try {
9324                 final ActivityRecord r = ActivityRecord.forTokenLocked(token);
9325                 if (r == null) {
9326                     throw new IllegalArgumentException(
9327                             "moveActivityToStack: No activity record matching token=" + token);
9328                 }
9329                 if (DEBUG_STACK) Slog.d(TAG_STACK, "moveActivityToStack: moving r=" + r
9330                         + " to stackId=" + stackId);
9331                 mStackSupervisor.moveTaskToStackLocked(r.task.taskId, stackId, ON_TOP, !FORCE_FOCUS,
9332                         "moveActivityToStack", true /* animate */);
9333             } finally {
9334                 Binder.restoreCallingIdentity(ident);
9335             }
9336         }
9337     }
9338
9339     @Override
9340     public void moveTaskToStack(int taskId, int stackId, boolean toTop) {
9341         enforceCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS,
9342                 "moveTaskToStack()");
9343         if (stackId == HOME_STACK_ID) {
9344             throw new IllegalArgumentException(
9345                     "moveTaskToStack: Attempt to move task " + taskId + " to home stack");
9346         }
9347         synchronized (this) {
9348             long ident = Binder.clearCallingIdentity();
9349             try {
9350                 if (DEBUG_STACK) Slog.d(TAG_STACK, "moveTaskToStack: moving task=" + taskId
9351                         + " to stackId=" + stackId + " toTop=" + toTop);
9352                 mStackSupervisor.moveTaskToStackLocked(taskId, stackId, toTop, !FORCE_FOCUS,
9353                         "moveTaskToStack", true /* animate */);
9354             } finally {
9355                 Binder.restoreCallingIdentity(ident);
9356             }
9357         }
9358     }
9359
9360     /**
9361      * Moves the input task to the docked stack.
9362      *
9363      * @param taskId Id of task to move.
9364      * @param createMode The mode the docked stack should be created in if it doesn't exist
9365      *                   already. See
9366      *                   {@link android.app.ActivityManager#DOCKED_STACK_CREATE_MODE_TOP_OR_LEFT}
9367      *                   and
9368      *                   {@link android.app.ActivityManager#DOCKED_STACK_CREATE_MODE_BOTTOM_OR_RIGHT}
9369      * @param toTop If the task and stack should be moved to the top.
9370      * @param animate Whether we should play an animation for the moving the task
9371      * @param initialBounds If the docked stack gets created, it will use these bounds for the
9372      *                      docked stack. Pass {@code null} to use default bounds.
9373      */
9374     @Override
9375     public void moveTaskToDockedStack(int taskId, int createMode, boolean toTop, boolean animate,
9376             Rect initialBounds) {
9377         enforceCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS,
9378                 "moveTaskToDockedStack()");
9379         synchronized (this) {
9380             long ident = Binder.clearCallingIdentity();
9381             try {
9382                 if (DEBUG_STACK) Slog.d(TAG_STACK, "moveTaskToDockedStack: moving task=" + taskId
9383                         + " to createMode=" + createMode + " toTop=" + toTop);
9384                 mWindowManager.setDockedStackCreateState(createMode, initialBounds);
9385                 mStackSupervisor.moveTaskToStackLocked(taskId, DOCKED_STACK_ID, toTop, !FORCE_FOCUS,
9386                         "moveTaskToDockedStack", animate);
9387             } finally {
9388                 Binder.restoreCallingIdentity(ident);
9389             }
9390         }
9391     }
9392
9393     /**
9394      * Moves the top activity in the input stackId to the pinned stack.
9395      *
9396      * @param stackId Id of stack to move the top activity to pinned stack.
9397      * @param bounds Bounds to use for pinned stack.
9398      *
9399      * @return True if the top activity of the input stack was successfully moved to the pinned
9400      *          stack.
9401      */
9402     @Override
9403     public boolean moveTopActivityToPinnedStack(int stackId, Rect bounds) {
9404         enforceCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS,
9405                 "moveTopActivityToPinnedStack()");
9406         synchronized (this) {
9407             long ident = Binder.clearCallingIdentity();
9408             try {
9409                 return mStackSupervisor.moveTopStackActivityToPinnedStackLocked(stackId, bounds);
9410             } finally {
9411                 Binder.restoreCallingIdentity(ident);
9412             }
9413         }
9414     }
9415
9416     @Override
9417     public void resizeStack(int stackId, Rect bounds, boolean allowResizeInDockedMode) {
9418         enforceCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS,
9419                 "resizeStack()");
9420         long ident = Binder.clearCallingIdentity();
9421         try {
9422             synchronized (this) {
9423                 mStackSupervisor.resizeStackLocked(
9424                         stackId, bounds, !PRESERVE_WINDOWS, allowResizeInDockedMode);
9425             }
9426         } finally {
9427             Binder.restoreCallingIdentity(ident);
9428         }
9429     }
9430
9431     @Override
9432     public void positionTaskInStack(int taskId, int stackId, int position) {
9433         enforceCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS,
9434                 "positionTaskInStack()");
9435         if (stackId == HOME_STACK_ID) {
9436             throw new IllegalArgumentException(
9437                     "positionTaskInStack: Attempt to change the position of task "
9438                     + taskId + " in/to home stack");
9439         }
9440         synchronized (this) {
9441             long ident = Binder.clearCallingIdentity();
9442             try {
9443                 if (DEBUG_STACK) Slog.d(TAG_STACK,
9444                         "positionTaskInStack: positioning task=" + taskId
9445                         + " in stackId=" + stackId + " at position=" + position);
9446                 mStackSupervisor.positionTaskInStackLocked(taskId, stackId, position);
9447             } finally {
9448                 Binder.restoreCallingIdentity(ident);
9449             }
9450         }
9451     }
9452
9453     @Override
9454     public List<StackInfo> getAllStackInfos() {
9455         enforceCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS,
9456                 "getAllStackInfos()");
9457         long ident = Binder.clearCallingIdentity();
9458         try {
9459             synchronized (this) {
9460                 return mStackSupervisor.getAllStackInfosLocked();
9461             }
9462         } finally {
9463             Binder.restoreCallingIdentity(ident);
9464         }
9465     }
9466
9467     @Override
9468     public StackInfo getStackInfo(int stackId) {
9469         enforceCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS,
9470                 "getStackInfo()");
9471         long ident = Binder.clearCallingIdentity();
9472         try {
9473             synchronized (this) {
9474                 return mStackSupervisor.getStackInfoLocked(stackId);
9475             }
9476         } finally {
9477             Binder.restoreCallingIdentity(ident);
9478         }
9479     }
9480
9481     @Override
9482     public boolean isInHomeStack(int taskId) {
9483         enforceCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS,
9484                 "getStackInfo()");
9485         long ident = Binder.clearCallingIdentity();
9486         try {
9487             synchronized (this) {
9488                 final TaskRecord tr = mStackSupervisor.anyTaskForIdLocked(
9489                         taskId, !RESTORE_FROM_RECENTS, INVALID_STACK_ID);
9490                 return tr != null && tr.stack != null && tr.stack.isHomeStack();
9491             }
9492         } finally {
9493             Binder.restoreCallingIdentity(ident);
9494         }
9495     }
9496
9497     @Override
9498     public int getTaskForActivity(IBinder token, boolean onlyRoot) {
9499         synchronized(this) {
9500             return ActivityRecord.getTaskForActivityLocked(token, onlyRoot);
9501         }
9502     }
9503
9504     @Override
9505     public void updateDeviceOwner(String packageName) {
9506         final int callingUid = Binder.getCallingUid();
9507         if (callingUid != 0 && callingUid != Process.SYSTEM_UID) {
9508             throw new SecurityException("updateDeviceOwner called from non-system process");
9509         }
9510         synchronized (this) {
9511             mDeviceOwnerName = packageName;
9512         }
9513     }
9514
9515     @Override
9516     public void updateLockTaskPackages(int userId, String[] packages) {
9517         final int callingUid = Binder.getCallingUid();
9518         if (callingUid != 0 && callingUid != Process.SYSTEM_UID) {
9519             throw new SecurityException("updateLockTaskPackage called from non-system process");
9520         }
9521         synchronized (this) {
9522             if (DEBUG_LOCKTASK) Slog.w(TAG_LOCKTASK, "Whitelisting " + userId + ":" +
9523                     Arrays.toString(packages));
9524             mLockTaskPackages.put(userId, packages);
9525             mStackSupervisor.onLockTaskPackagesUpdatedLocked();
9526         }
9527     }
9528
9529
9530     void startLockTaskModeLocked(TaskRecord task) {
9531         if (DEBUG_LOCKTASK) Slog.w(TAG_LOCKTASK, "startLockTaskModeLocked: " + task);
9532         if (task.mLockTaskAuth == LOCK_TASK_AUTH_DONT_LOCK) {
9533             return;
9534         }
9535
9536         // isSystemInitiated is used to distinguish between locked and pinned mode, as pinned mode
9537         // is initiated by system after the pinning request was shown and locked mode is initiated
9538         // by an authorized app directly
9539         final int callingUid = Binder.getCallingUid();
9540         boolean isSystemInitiated = callingUid == Process.SYSTEM_UID;
9541         long ident = Binder.clearCallingIdentity();
9542         try {
9543             final ActivityStack stack = mStackSupervisor.getFocusedStack();
9544             if (!isSystemInitiated) {
9545                 task.mLockTaskUid = callingUid;
9546                 if (task.mLockTaskAuth == LOCK_TASK_AUTH_PINNABLE) {
9547                     // startLockTask() called by app and task mode is lockTaskModeDefault.
9548                     if (DEBUG_LOCKTASK) Slog.w(TAG_LOCKTASK, "Mode default, asking user");
9549                     StatusBarManagerInternal statusBarManager =
9550                             LocalServices.getService(StatusBarManagerInternal.class);
9551                     if (statusBarManager != null) {
9552                         statusBarManager.showScreenPinningRequest();
9553                     }
9554                     return;
9555                 }
9556
9557                 if (stack == null || task != stack.topTask()) {
9558                     throw new IllegalArgumentException("Invalid task, not in foreground");
9559                 }
9560             }
9561             if (DEBUG_LOCKTASK) Slog.w(TAG_LOCKTASK, isSystemInitiated ? "Locking pinned" :
9562                     "Locking fully");
9563             mStackSupervisor.setLockTaskModeLocked(task, isSystemInitiated ?
9564                     ActivityManager.LOCK_TASK_MODE_PINNED :
9565                     ActivityManager.LOCK_TASK_MODE_LOCKED,
9566                     "startLockTask", true);
9567         } finally {
9568             Binder.restoreCallingIdentity(ident);
9569         }
9570     }
9571
9572     @Override
9573     public void startLockTaskMode(int taskId) {
9574         synchronized (this) {
9575             final TaskRecord task = mStackSupervisor.anyTaskForIdLocked(taskId);
9576             if (task != null) {
9577                 startLockTaskModeLocked(task);
9578             }
9579         }
9580     }
9581
9582     @Override
9583     public void startLockTaskMode(IBinder token) {
9584         synchronized (this) {
9585             final ActivityRecord r = ActivityRecord.forTokenLocked(token);
9586             if (r == null) {
9587                 return;
9588             }
9589             final TaskRecord task = r.task;
9590             if (task != null) {
9591                 startLockTaskModeLocked(task);
9592             }
9593         }
9594     }
9595
9596     @Override
9597     public void startLockTaskModeOnCurrent() throws RemoteException {
9598         enforceCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS,
9599                 "startLockTaskModeOnCurrent");
9600         long ident = Binder.clearCallingIdentity();
9601         try {
9602             synchronized (this) {
9603                 ActivityRecord r = mStackSupervisor.topRunningActivityLocked();
9604                 if (r != null) {
9605                     startLockTaskModeLocked(r.task);
9606                 }
9607             }
9608         } finally {
9609             Binder.restoreCallingIdentity(ident);
9610         }
9611     }
9612
9613     @Override
9614     public void stopLockTaskMode() {
9615         final TaskRecord lockTask = mStackSupervisor.getLockedTaskLocked();
9616         if (lockTask == null) {
9617             // Our work here is done.
9618             return;
9619         }
9620
9621         final int callingUid = Binder.getCallingUid();
9622         final int lockTaskUid = lockTask.mLockTaskUid;
9623         // Ensure the same caller for startLockTaskMode and stopLockTaskMode.
9624         // It is possible lockTaskMode was started by the system process because
9625         // android:lockTaskMode is set to a locking value in the application manifest instead of
9626         // the app calling startLockTaskMode. In this case {@link TaskRecord.mLockTaskUid} will
9627         // be 0, so we compare the callingUid to the {@link TaskRecord.effectiveUid} instead.
9628         if (getLockTaskModeState() == ActivityManager.LOCK_TASK_MODE_LOCKED &&
9629                 callingUid != lockTaskUid
9630                 && (lockTaskUid != 0
9631                     || (lockTaskUid == 0 && callingUid != lockTask.effectiveUid))) {
9632             throw new SecurityException("Invalid uid, expected " + lockTaskUid
9633                     + " callingUid=" + callingUid + " effectiveUid=" + lockTask.effectiveUid);
9634         }
9635
9636         long ident = Binder.clearCallingIdentity();
9637         try {
9638             Log.d(TAG, "stopLockTaskMode");
9639             // Stop lock task
9640             synchronized (this) {
9641                 mStackSupervisor.setLockTaskModeLocked(null, ActivityManager.LOCK_TASK_MODE_NONE,
9642                         "stopLockTask", true);
9643             }
9644         } finally {
9645             Binder.restoreCallingIdentity(ident);
9646         }
9647     }
9648
9649     @Override
9650     public void stopLockTaskModeOnCurrent() throws RemoteException {
9651         enforceCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS,
9652                 "stopLockTaskModeOnCurrent");
9653         long ident = Binder.clearCallingIdentity();
9654         try {
9655             stopLockTaskMode();
9656         } finally {
9657             Binder.restoreCallingIdentity(ident);
9658         }
9659     }
9660
9661     @Override
9662     public boolean isInLockTaskMode() {
9663         return getLockTaskModeState() != ActivityManager.LOCK_TASK_MODE_NONE;
9664     }
9665
9666     @Override
9667     public int getLockTaskModeState() {
9668         synchronized (this) {
9669             return mStackSupervisor.getLockTaskModeState();
9670         }
9671     }
9672
9673     @Override
9674     public void showLockTaskEscapeMessage(IBinder token) {
9675         synchronized (this) {
9676             final ActivityRecord r = ActivityRecord.forTokenLocked(token);
9677             if (r == null) {
9678                 return;
9679             }
9680             mStackSupervisor.showLockTaskEscapeMessageLocked(r.task);
9681         }
9682     }
9683
9684     // =========================================================
9685     // CONTENT PROVIDERS
9686     // =========================================================
9687
9688     private final List<ProviderInfo> generateApplicationProvidersLocked(ProcessRecord app) {
9689         List<ProviderInfo> providers = null;
9690         try {
9691             ParceledListSlice<ProviderInfo> slice = AppGlobals.getPackageManager().
9692                 queryContentProviders(app.processName, app.uid,
9693                         STOCK_PM_FLAGS | PackageManager.GET_URI_PERMISSION_PATTERNS);
9694             providers = slice != null ? slice.getList() : null;
9695         } catch (RemoteException ex) {
9696         }
9697         if (DEBUG_MU) Slog.v(TAG_MU,
9698                 "generateApplicationProvidersLocked, app.info.uid = " + app.uid);
9699         int userId = app.userId;
9700         if (providers != null) {
9701             int N = providers.size();
9702             app.pubProviders.ensureCapacity(N + app.pubProviders.size());
9703             for (int i=0; i<N; i++) {
9704                 ProviderInfo cpi =
9705                     (ProviderInfo)providers.get(i);
9706                 boolean singleton = isSingleton(cpi.processName, cpi.applicationInfo,
9707                         cpi.name, cpi.flags);
9708                 if (singleton && UserHandle.getUserId(app.uid) != UserHandle.USER_SYSTEM) {
9709                     // This is a singleton provider, but a user besides the
9710                     // default user is asking to initialize a process it runs
9711                     // in...  well, no, it doesn't actually run in this process,
9712                     // it runs in the process of the default user.  Get rid of it.
9713                     providers.remove(i);
9714                     N--;
9715                     i--;
9716                     continue;
9717                 }
9718
9719                 ComponentName comp = new ComponentName(cpi.packageName, cpi.name);
9720                 ContentProviderRecord cpr = mProviderMap.getProviderByClass(comp, userId);
9721                 if (cpr == null) {
9722                     cpr = new ContentProviderRecord(this, cpi, app.info, comp, singleton);
9723                     mProviderMap.putProviderByClass(comp, cpr);
9724                 }
9725                 if (DEBUG_MU) Slog.v(TAG_MU,
9726                         "generateApplicationProvidersLocked, cpi.uid = " + cpr.uid);
9727                 app.pubProviders.put(cpi.name, cpr);
9728                 if (!cpi.multiprocess || !"android".equals(cpi.packageName)) {
9729                     // Don't add this if it is a platform component that is marked
9730                     // to run in multiple processes, because this is actually
9731                     // part of the framework so doesn't make sense to track as a
9732                     // separate apk in the process.
9733                     app.addPackage(cpi.applicationInfo.packageName, cpi.applicationInfo.versionCode,
9734                             mProcessStats);
9735                 }
9736                 notifyPackageUse(cpi.applicationInfo.packageName);
9737             }
9738         }
9739         return providers;
9740     }
9741
9742     /**
9743      * Check if {@link ProcessRecord} has a possible chance at accessing the
9744      * given {@link ProviderInfo}. Final permission checking is always done
9745      * in {@link ContentProvider}.
9746      */
9747     private final String checkContentProviderPermissionLocked(
9748             ProviderInfo cpi, ProcessRecord r, int userId, boolean checkUser) {
9749         final int callingPid = (r != null) ? r.pid : Binder.getCallingPid();
9750         final int callingUid = (r != null) ? r.uid : Binder.getCallingUid();
9751         boolean checkedGrants = false;
9752         if (checkUser) {
9753             // Looking for cross-user grants before enforcing the typical cross-users permissions
9754             int tmpTargetUserId = mUserController.unsafeConvertIncomingUserLocked(userId);
9755             if (tmpTargetUserId != UserHandle.getUserId(callingUid)) {
9756                 if (checkAuthorityGrants(callingUid, cpi, tmpTargetUserId, checkUser)) {
9757                     return null;
9758                 }
9759                 checkedGrants = true;
9760             }
9761             userId = mUserController.handleIncomingUser(callingPid, callingUid, userId, false,
9762                     ALLOW_NON_FULL, "checkContentProviderPermissionLocked " + cpi.authority, null);
9763             if (userId != tmpTargetUserId) {
9764                 // When we actually went to determine the final targer user ID, this ended
9765                 // up different than our initial check for the authority.  This is because
9766                 // they had asked for USER_CURRENT_OR_SELF and we ended up switching to
9767                 // SELF.  So we need to re-check the grants again.
9768                 checkedGrants = false;
9769             }
9770         }
9771         if (checkComponentPermission(cpi.readPermission, callingPid, callingUid,
9772                 cpi.applicationInfo.uid, cpi.exported)
9773                 == PackageManager.PERMISSION_GRANTED) {
9774             return null;
9775         }
9776         if (checkComponentPermission(cpi.writePermission, callingPid, callingUid,
9777                 cpi.applicationInfo.uid, cpi.exported)
9778                 == PackageManager.PERMISSION_GRANTED) {
9779             return null;
9780         }
9781
9782         PathPermission[] pps = cpi.pathPermissions;
9783         if (pps != null) {
9784             int i = pps.length;
9785             while (i > 0) {
9786                 i--;
9787                 PathPermission pp = pps[i];
9788                 String pprperm = pp.getReadPermission();
9789                 if (pprperm != null && checkComponentPermission(pprperm, callingPid, callingUid,
9790                         cpi.applicationInfo.uid, cpi.exported)
9791                         == PackageManager.PERMISSION_GRANTED) {
9792                     return null;
9793                 }
9794                 String ppwperm = pp.getWritePermission();
9795                 if (ppwperm != null && checkComponentPermission(ppwperm, callingPid, callingUid,
9796                         cpi.applicationInfo.uid, cpi.exported)
9797                         == PackageManager.PERMISSION_GRANTED) {
9798                     return null;
9799                 }
9800             }
9801         }
9802         if (!checkedGrants && checkAuthorityGrants(callingUid, cpi, userId, checkUser)) {
9803             return null;
9804         }
9805
9806         String msg;
9807         if (!cpi.exported) {
9808             msg = "Permission Denial: opening provider " + cpi.name
9809                     + " from " + (r != null ? r : "(null)") + " (pid=" + callingPid
9810                     + ", uid=" + callingUid + ") that is not exported from uid "
9811                     + cpi.applicationInfo.uid;
9812         } else {
9813             msg = "Permission Denial: opening provider " + cpi.name
9814                     + " from " + (r != null ? r : "(null)") + " (pid=" + callingPid
9815                     + ", uid=" + callingUid + ") requires "
9816                     + cpi.readPermission + " or " + cpi.writePermission;
9817         }
9818         Slog.w(TAG, msg);
9819         return msg;
9820     }
9821
9822     /**
9823      * Returns if the ContentProvider has granted a uri to callingUid
9824      */
9825     boolean checkAuthorityGrants(int callingUid, ProviderInfo cpi, int userId, boolean checkUser) {
9826         final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.get(callingUid);
9827         if (perms != null) {
9828             for (int i=perms.size()-1; i>=0; i--) {
9829                 GrantUri grantUri = perms.keyAt(i);
9830                 if (grantUri.sourceUserId == userId || !checkUser) {
9831                     if (matchesProvider(grantUri.uri, cpi)) {
9832                         return true;
9833                     }
9834                 }
9835             }
9836         }
9837         return false;
9838     }
9839
9840     /**
9841      * Returns true if the uri authority is one of the authorities specified in the provider.
9842      */
9843     boolean matchesProvider(Uri uri, ProviderInfo cpi) {
9844         String uriAuth = uri.getAuthority();
9845         String cpiAuth = cpi.authority;
9846         if (cpiAuth.indexOf(';') == -1) {
9847             return cpiAuth.equals(uriAuth);
9848         }
9849         String[] cpiAuths = cpiAuth.split(";");
9850         int length = cpiAuths.length;
9851         for (int i = 0; i < length; i++) {
9852             if (cpiAuths[i].equals(uriAuth)) return true;
9853         }
9854         return false;
9855     }
9856
9857     ContentProviderConnection incProviderCountLocked(ProcessRecord r,
9858             final ContentProviderRecord cpr, IBinder externalProcessToken, boolean stable) {
9859         if (r != null) {
9860             for (int i=0; i<r.conProviders.size(); i++) {
9861                 ContentProviderConnection conn = r.conProviders.get(i);
9862                 if (conn.provider == cpr) {
9863                     if (DEBUG_PROVIDER) Slog.v(TAG_PROVIDER,
9864                             "Adding provider requested by "
9865                             + r.processName + " from process "
9866                             + cpr.info.processName + ": " + cpr.name.flattenToShortString()
9867                             + " scnt=" + conn.stableCount + " uscnt=" + conn.unstableCount);
9868                     if (stable) {
9869                         conn.stableCount++;
9870                         conn.numStableIncs++;
9871                     } else {
9872                         conn.unstableCount++;
9873                         conn.numUnstableIncs++;
9874                     }
9875                     return conn;
9876                 }
9877             }
9878             ContentProviderConnection conn = new ContentProviderConnection(cpr, r);
9879             if (stable) {
9880                 conn.stableCount = 1;
9881                 conn.numStableIncs = 1;
9882             } else {
9883                 conn.unstableCount = 1;
9884                 conn.numUnstableIncs = 1;
9885             }
9886             cpr.connections.add(conn);
9887             r.conProviders.add(conn);
9888             startAssociationLocked(r.uid, r.processName, cpr.uid, cpr.name, cpr.info.processName);
9889             return conn;
9890         }
9891         cpr.addExternalProcessHandleLocked(externalProcessToken);
9892         return null;
9893     }
9894
9895     boolean decProviderCountLocked(ContentProviderConnection conn,
9896             ContentProviderRecord cpr, IBinder externalProcessToken, boolean stable) {
9897         if (conn != null) {
9898             cpr = conn.provider;
9899             if (DEBUG_PROVIDER) Slog.v(TAG_PROVIDER,
9900                     "Removing provider requested by "
9901                     + conn.client.processName + " from process "
9902                     + cpr.info.processName + ": " + cpr.name.flattenToShortString()
9903                     + " scnt=" + conn.stableCount + " uscnt=" + conn.unstableCount);
9904             if (stable) {
9905                 conn.stableCount--;
9906             } else {
9907                 conn.unstableCount--;
9908             }
9909             if (conn.stableCount == 0 && conn.unstableCount == 0) {
9910                 cpr.connections.remove(conn);
9911                 conn.client.conProviders.remove(conn);
9912                 if (conn.client.setProcState < ActivityManager.PROCESS_STATE_LAST_ACTIVITY) {
9913                     // The client is more important than last activity -- note the time this
9914                     // is happening, so we keep the old provider process around a bit as last
9915                     // activity to avoid thrashing it.
9916                     if (cpr.proc != null) {
9917                         cpr.proc.lastProviderTime = SystemClock.uptimeMillis();
9918                     }
9919                 }
9920                 stopAssociationLocked(conn.client.uid, conn.client.processName, cpr.uid, cpr.name);
9921                 return true;
9922             }
9923             return false;
9924         }
9925         cpr.removeExternalProcessHandleLocked(externalProcessToken);
9926         return false;
9927     }
9928
9929     private void checkTime(long startTime, String where) {
9930         long now = SystemClock.elapsedRealtime();
9931         if ((now-startTime) > 1000) {
9932             // If we are taking more than a second, log about it.
9933             Slog.w(TAG, "Slow operation: " + (now-startTime) + "ms so far, now at " + where);
9934         }
9935     }
9936
9937     private ContentProviderHolder getContentProviderImpl(IApplicationThread caller,
9938             String name, IBinder token, boolean stable, int userId) {
9939         ContentProviderRecord cpr;
9940         ContentProviderConnection conn = null;
9941         ProviderInfo cpi = null;
9942
9943         synchronized(this) {
9944             long startTime = SystemClock.elapsedRealtime();
9945
9946             ProcessRecord r = null;
9947             if (caller != null) {
9948                 r = getRecordForAppLocked(caller);
9949                 if (r == null) {
9950                     throw new SecurityException(
9951                             "Unable to find app for caller " + caller
9952                           + " (pid=" + Binder.getCallingPid()
9953                           + ") when getting content provider " + name);
9954                 }
9955             }
9956
9957             boolean checkCrossUser = true;
9958
9959             checkTime(startTime, "getContentProviderImpl: getProviderByName");
9960
9961             // First check if this content provider has been published...
9962             cpr = mProviderMap.getProviderByName(name, userId);
9963             // If that didn't work, check if it exists for user 0 and then
9964             // verify that it's a singleton provider before using it.
9965             if (cpr == null && userId != UserHandle.USER_SYSTEM) {
9966                 cpr = mProviderMap.getProviderByName(name, UserHandle.USER_SYSTEM);
9967                 if (cpr != null) {
9968                     cpi = cpr.info;
9969                     if (isSingleton(cpi.processName, cpi.applicationInfo,
9970                             cpi.name, cpi.flags)
9971                             && isValidSingletonCall(r.uid, cpi.applicationInfo.uid)) {
9972                         userId = UserHandle.USER_SYSTEM;
9973                         checkCrossUser = false;
9974                     } else {
9975                         cpr = null;
9976                         cpi = null;
9977                     }
9978                 }
9979             }
9980
9981             boolean providerRunning = cpr != null;
9982             if (providerRunning) {
9983                 cpi = cpr.info;
9984                 String msg;
9985                 checkTime(startTime, "getContentProviderImpl: before checkContentProviderPermission");
9986                 if ((msg = checkContentProviderPermissionLocked(cpi, r, userId, checkCrossUser))
9987                         != null) {
9988                     throw new SecurityException(msg);
9989                 }
9990                 checkTime(startTime, "getContentProviderImpl: after checkContentProviderPermission");
9991
9992                 if (r != null && cpr.canRunHere(r)) {
9993                     // This provider has been published or is in the process
9994                     // of being published...  but it is also allowed to run
9995                     // in the caller's process, so don't make a connection
9996                     // and just let the caller instantiate its own instance.
9997                     ContentProviderHolder holder = cpr.newHolder(null);
9998                     // don't give caller the provider object, it needs
9999                     // to make its own.
10000                     holder.provider = null;
10001                     return holder;
10002                 }
10003
10004                 final long origId = Binder.clearCallingIdentity();
10005
10006                 checkTime(startTime, "getContentProviderImpl: incProviderCountLocked");
10007
10008                 // In this case the provider instance already exists, so we can
10009                 // return it right away.
10010                 conn = incProviderCountLocked(r, cpr, token, stable);
10011                 if (conn != null && (conn.stableCount+conn.unstableCount) == 1) {
10012                     if (cpr.proc != null && r.setAdj <= ProcessList.PERCEPTIBLE_APP_ADJ) {
10013                         // If this is a perceptible app accessing the provider,
10014                         // make sure to count it as being accessed and thus
10015                         // back up on the LRU list.  This is good because
10016                         // content providers are often expensive to start.
10017                         checkTime(startTime, "getContentProviderImpl: before updateLruProcess");
10018                         updateLruProcessLocked(cpr.proc, false, null);
10019                         checkTime(startTime, "getContentProviderImpl: after updateLruProcess");
10020                     }
10021                 }
10022
10023                 if (cpr.proc != null) {
10024                     checkTime(startTime, "getContentProviderImpl: before updateOomAdj");
10025                     boolean success = updateOomAdjLocked(cpr.proc);
10026                     maybeUpdateProviderUsageStatsLocked(r, cpr.info.packageName, name);
10027                     checkTime(startTime, "getContentProviderImpl: after updateOomAdj");
10028                     if (DEBUG_PROVIDER) Slog.i(TAG_PROVIDER, "Adjust success: " + success);
10029                     // NOTE: there is still a race here where a signal could be
10030                     // pending on the process even though we managed to update its
10031                     // adj level.  Not sure what to do about this, but at least
10032                     // the race is now smaller.
10033                     if (!success) {
10034                         // Uh oh...  it looks like the provider's process
10035                         // has been killed on us.  We need to wait for a new
10036                         // process to be started, and make sure its death
10037                         // doesn't kill our process.
10038                         Slog.i(TAG, "Existing provider " + cpr.name.flattenToShortString()
10039                                 + " is crashing; detaching " + r);
10040                         boolean lastRef = decProviderCountLocked(conn, cpr, token, stable);
10041                         checkTime(startTime, "getContentProviderImpl: before appDied");
10042                         appDiedLocked(cpr.proc);
10043                         checkTime(startTime, "getContentProviderImpl: after appDied");
10044                         if (!lastRef) {
10045                             // This wasn't the last ref our process had on
10046                             // the provider...  we have now been killed, bail.
10047                             return null;
10048                         }
10049                         providerRunning = false;
10050                         conn = null;
10051                     }
10052                 }
10053
10054                 Binder.restoreCallingIdentity(origId);
10055             }
10056
10057             if (!providerRunning) {
10058                 try {
10059                     checkTime(startTime, "getContentProviderImpl: before resolveContentProvider");
10060                     cpi = AppGlobals.getPackageManager().
10061                         resolveContentProvider(name,
10062                             STOCK_PM_FLAGS | PackageManager.GET_URI_PERMISSION_PATTERNS, userId);
10063                     checkTime(startTime, "getContentProviderImpl: after resolveContentProvider");
10064                 } catch (RemoteException ex) {
10065                 }
10066                 if (cpi == null) {
10067                     return null;
10068                 }
10069                 // If the provider is a singleton AND
10070                 // (it's a call within the same user || the provider is a
10071                 // privileged app)
10072                 // Then allow connecting to the singleton provider
10073                 boolean singleton = isSingleton(cpi.processName, cpi.applicationInfo,
10074                         cpi.name, cpi.flags)
10075                         && isValidSingletonCall(r.uid, cpi.applicationInfo.uid);
10076                 if (singleton) {
10077                     userId = UserHandle.USER_SYSTEM;
10078                 }
10079                 cpi.applicationInfo = getAppInfoForUser(cpi.applicationInfo, userId);
10080                 checkTime(startTime, "getContentProviderImpl: got app info for user");
10081
10082                 String msg;
10083                 checkTime(startTime, "getContentProviderImpl: before checkContentProviderPermission");
10084                 if ((msg = checkContentProviderPermissionLocked(cpi, r, userId, !singleton))
10085                         != null) {
10086                     throw new SecurityException(msg);
10087                 }
10088                 checkTime(startTime, "getContentProviderImpl: after checkContentProviderPermission");
10089
10090                 if (!mProcessesReady && !mDidUpdate && !mWaitingUpdate
10091                         && !cpi.processName.equals("system")) {
10092                     // If this content provider does not run in the system
10093                     // process, and the system is not yet ready to run other
10094                     // processes, then fail fast instead of hanging.
10095                     throw new IllegalArgumentException(
10096                             "Attempt to launch content provider before system ready");
10097                 }
10098
10099                 // Make sure that the user who owns this provider is running.  If not,
10100                 // we don't want to allow it to run.
10101                 if (!mUserController.isUserRunningLocked(userId, 0)) {
10102                     Slog.w(TAG, "Unable to launch app "
10103                             + cpi.applicationInfo.packageName + "/"
10104                             + cpi.applicationInfo.uid + " for provider "
10105                             + name + ": user " + userId + " is stopped");
10106                     return null;
10107                 }
10108
10109                 ComponentName comp = new ComponentName(cpi.packageName, cpi.name);
10110                 checkTime(startTime, "getContentProviderImpl: before getProviderByClass");
10111                 cpr = mProviderMap.getProviderByClass(comp, userId);
10112                 checkTime(startTime, "getContentProviderImpl: after getProviderByClass");
10113                 final boolean firstClass = cpr == null;
10114                 if (firstClass) {
10115                     final long ident = Binder.clearCallingIdentity();
10116
10117                     // If permissions need a review before any of the app components can run,
10118                     // we return no provider and launch a review activity if the calling app
10119                     // is in the foreground.
10120                     if (Build.PERMISSIONS_REVIEW_REQUIRED) {
10121                         if (!requestTargetProviderPermissionsReviewIfNeededLocked(cpi, r, userId)) {
10122                             return null;
10123                         }
10124                     }
10125
10126                     try {
10127                         checkTime(startTime, "getContentProviderImpl: before getApplicationInfo");
10128                         ApplicationInfo ai =
10129                             AppGlobals.getPackageManager().
10130                                 getApplicationInfo(
10131                                         cpi.applicationInfo.packageName,
10132                                         STOCK_PM_FLAGS, userId);
10133                         checkTime(startTime, "getContentProviderImpl: after getApplicationInfo");
10134                         if (ai == null) {
10135                             Slog.w(TAG, "No package info for content provider "
10136                                     + cpi.name);
10137                             return null;
10138                         }
10139                         ai = getAppInfoForUser(ai, userId);
10140                         cpr = new ContentProviderRecord(this, cpi, ai, comp, singleton);
10141                     } catch (RemoteException ex) {
10142                         // pm is in same process, this will never happen.
10143                     } finally {
10144                         Binder.restoreCallingIdentity(ident);
10145                     }
10146                 }
10147
10148                 checkTime(startTime, "getContentProviderImpl: now have ContentProviderRecord");
10149
10150                 if (r != null && cpr.canRunHere(r)) {
10151                     // If this is a multiprocess provider, then just return its
10152                     // info and allow the caller to instantiate it.  Only do
10153                     // this if the provider is the same user as the caller's
10154                     // process, or can run as root (so can be in any process).
10155                     return cpr.newHolder(null);
10156                 }
10157
10158                 if (DEBUG_PROVIDER) Slog.w(TAG_PROVIDER, "LAUNCHING REMOTE PROVIDER (myuid "
10159                             + (r != null ? r.uid : null) + " pruid " + cpr.appInfo.uid + "): "
10160                             + cpr.info.name + " callers=" + Debug.getCallers(6));
10161
10162                 // This is single process, and our app is now connecting to it.
10163                 // See if we are already in the process of launching this
10164                 // provider.
10165                 final int N = mLaunchingProviders.size();
10166                 int i;
10167                 for (i = 0; i < N; i++) {
10168                     if (mLaunchingProviders.get(i) == cpr) {
10169                         break;
10170                     }
10171                 }
10172
10173                 // If the provider is not already being launched, then get it
10174                 // started.
10175                 if (i >= N) {
10176                     final long origId = Binder.clearCallingIdentity();
10177
10178                     try {
10179                         // Content provider is now in use, its package can't be stopped.
10180                         try {
10181                             checkTime(startTime, "getContentProviderImpl: before set stopped state");
10182                             AppGlobals.getPackageManager().setPackageStoppedState(
10183                                     cpr.appInfo.packageName, false, userId);
10184                             checkTime(startTime, "getContentProviderImpl: after set stopped state");
10185                         } catch (RemoteException e) {
10186                         } catch (IllegalArgumentException e) {
10187                             Slog.w(TAG, "Failed trying to unstop package "
10188                                     + cpr.appInfo.packageName + ": " + e);
10189                         }
10190
10191                         // Use existing process if already started
10192                         checkTime(startTime, "getContentProviderImpl: looking for process record");
10193                         ProcessRecord proc = getProcessRecordLocked(
10194                                 cpi.processName, cpr.appInfo.uid, false);
10195                         if (proc != null && proc.thread != null) {
10196                             if (DEBUG_PROVIDER) Slog.d(TAG_PROVIDER,
10197                                     "Installing in existing process " + proc);
10198                             if (!proc.pubProviders.containsKey(cpi.name)) {
10199                                 checkTime(startTime, "getContentProviderImpl: scheduling install");
10200                                 proc.pubProviders.put(cpi.name, cpr);
10201                                 try {
10202                                     proc.thread.scheduleInstallProvider(cpi);
10203                                 } catch (RemoteException e) {
10204                                 }
10205                             }
10206                         } else {
10207                             checkTime(startTime, "getContentProviderImpl: before start process");
10208                             proc = startProcessLocked(cpi.processName,
10209                                     cpr.appInfo, false, 0, "content provider",
10210                                     new ComponentName(cpi.applicationInfo.packageName,
10211                                             cpi.name), false, false, false);
10212                             checkTime(startTime, "getContentProviderImpl: after start process");
10213                             if (proc == null) {
10214                                 Slog.w(TAG, "Unable to launch app "
10215                                         + cpi.applicationInfo.packageName + "/"
10216                                         + cpi.applicationInfo.uid + " for provider "
10217                                         + name + ": process is bad");
10218                                 return null;
10219                             }
10220                         }
10221                         cpr.launchingApp = proc;
10222                         mLaunchingProviders.add(cpr);
10223                     } finally {
10224                         Binder.restoreCallingIdentity(origId);
10225                     }
10226                 }
10227
10228                 checkTime(startTime, "getContentProviderImpl: updating data structures");
10229
10230                 // Make sure the provider is published (the same provider class
10231                 // may be published under multiple names).
10232                 if (firstClass) {
10233                     mProviderMap.putProviderByClass(comp, cpr);
10234                 }
10235
10236                 mProviderMap.putProviderByName(name, cpr);
10237                 conn = incProviderCountLocked(r, cpr, token, stable);
10238                 if (conn != null) {
10239                     conn.waiting = true;
10240                 }
10241             }
10242             checkTime(startTime, "getContentProviderImpl: done!");
10243         }
10244
10245         // Wait for the provider to be published...
10246         synchronized (cpr) {
10247             while (cpr.provider == null) {
10248                 if (cpr.launchingApp == null) {
10249                     Slog.w(TAG, "Unable to launch app "
10250                             + cpi.applicationInfo.packageName + "/"
10251                             + cpi.applicationInfo.uid + " for provider "
10252                             + name + ": launching app became null");
10253                     EventLog.writeEvent(EventLogTags.AM_PROVIDER_LOST_PROCESS,
10254                             UserHandle.getUserId(cpi.applicationInfo.uid),
10255                             cpi.applicationInfo.packageName,
10256                             cpi.applicationInfo.uid, name);
10257                     return null;
10258                 }
10259                 try {
10260                     if (DEBUG_MU) Slog.v(TAG_MU,
10261                             "Waiting to start provider " + cpr
10262                             + " launchingApp=" + cpr.launchingApp);
10263                     if (conn != null) {
10264                         conn.waiting = true;
10265                     }
10266                     cpr.wait();
10267                 } catch (InterruptedException ex) {
10268                 } finally {
10269                     if (conn != null) {
10270                         conn.waiting = false;
10271                     }
10272                 }
10273             }
10274         }
10275         return cpr != null ? cpr.newHolder(conn) : null;
10276     }
10277
10278     private boolean requestTargetProviderPermissionsReviewIfNeededLocked(ProviderInfo cpi,
10279             ProcessRecord r, final int userId) {
10280         if (getPackageManagerInternalLocked().isPermissionsReviewRequired(
10281                 cpi.packageName, r.userId)) {
10282
10283             final boolean callerForeground = r != null ? r.setSchedGroup
10284                     != Process.THREAD_GROUP_BG_NONINTERACTIVE : true;
10285
10286             // Show a permission review UI only for starting from a foreground app
10287             if (!callerForeground) {
10288                 Slog.w(TAG, "u" + r.userId + " Instantiating a provider in package"
10289                         + cpi.packageName + " requires a permissions review");
10290                 return false;
10291             }
10292
10293             final Intent intent = new Intent(Intent.ACTION_REVIEW_PERMISSIONS);
10294             intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK
10295                     | Intent.FLAG_ACTIVITY_EXCLUDE_FROM_RECENTS);
10296             intent.putExtra(Intent.EXTRA_PACKAGE_NAME, cpi.packageName);
10297
10298             if (DEBUG_PERMISSIONS_REVIEW) {
10299                 Slog.i(TAG, "u" + r.userId + " Launching permission review "
10300                         + "for package " + cpi.packageName);
10301             }
10302
10303             final UserHandle userHandle = new UserHandle(userId);
10304             mHandler.post(new Runnable() {
10305                 @Override
10306                 public void run() {
10307                     mContext.startActivityAsUser(intent, userHandle);
10308                 }
10309             });
10310
10311             return false;
10312         }
10313
10314         return true;
10315     }
10316
10317     PackageManagerInternal getPackageManagerInternalLocked() {
10318         if (mPackageManagerInt == null) {
10319             mPackageManagerInt = LocalServices.getService(PackageManagerInternal.class);
10320         }
10321         return mPackageManagerInt;
10322     }
10323
10324     @Override
10325     public final ContentProviderHolder getContentProvider(
10326             IApplicationThread caller, String name, int userId, boolean stable) {
10327         enforceNotIsolatedCaller("getContentProvider");
10328         if (caller == null) {
10329             String msg = "null IApplicationThread when getting content provider "
10330                     + name;
10331             Slog.w(TAG, msg);
10332             throw new SecurityException(msg);
10333         }
10334         // The incoming user check is now handled in checkContentProviderPermissionLocked() to deal
10335         // with cross-user grant.
10336         return getContentProviderImpl(caller, name, null, stable, userId);
10337     }
10338
10339     public ContentProviderHolder getContentProviderExternal(
10340             String name, int userId, IBinder token) {
10341         enforceCallingPermission(android.Manifest.permission.ACCESS_CONTENT_PROVIDERS_EXTERNALLY,
10342             "Do not have permission in call getContentProviderExternal()");
10343         userId = mUserController.handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(),
10344                 userId, false, ALLOW_FULL_ONLY, "getContentProvider", null);
10345         return getContentProviderExternalUnchecked(name, token, userId);
10346     }
10347
10348     private ContentProviderHolder getContentProviderExternalUnchecked(String name,
10349             IBinder token, int userId) {
10350         return getContentProviderImpl(null, name, token, true, userId);
10351     }
10352
10353     /**
10354      * Drop a content provider from a ProcessRecord's bookkeeping
10355      */
10356     public void removeContentProvider(IBinder connection, boolean stable) {
10357         enforceNotIsolatedCaller("removeContentProvider");
10358         long ident = Binder.clearCallingIdentity();
10359         try {
10360             synchronized (this) {
10361                 ContentProviderConnection conn;
10362                 try {
10363                     conn = (ContentProviderConnection)connection;
10364                 } catch (ClassCastException e) {
10365                     String msg ="removeContentProvider: " + connection
10366                             + " not a ContentProviderConnection";
10367                     Slog.w(TAG, msg);
10368                     throw new IllegalArgumentException(msg);
10369                 }
10370                 if (conn == null) {
10371                     throw new NullPointerException("connection is null");
10372                 }
10373                 if (decProviderCountLocked(conn, null, null, stable)) {
10374                     updateOomAdjLocked();
10375                 }
10376             }
10377         } finally {
10378             Binder.restoreCallingIdentity(ident);
10379         }
10380     }
10381
10382     public void removeContentProviderExternal(String name, IBinder token) {
10383         enforceCallingPermission(android.Manifest.permission.ACCESS_CONTENT_PROVIDERS_EXTERNALLY,
10384             "Do not have permission in call removeContentProviderExternal()");
10385         int userId = UserHandle.getCallingUserId();
10386         long ident = Binder.clearCallingIdentity();
10387         try {
10388             removeContentProviderExternalUnchecked(name, token, userId);
10389         } finally {
10390             Binder.restoreCallingIdentity(ident);
10391         }
10392     }
10393
10394     private void removeContentProviderExternalUnchecked(String name, IBinder token, int userId) {
10395         synchronized (this) {
10396             ContentProviderRecord cpr = mProviderMap.getProviderByName(name, userId);
10397             if(cpr == null) {
10398                 //remove from mProvidersByClass
10399                 if(DEBUG_ALL) Slog.v(TAG, name+" content provider not found in providers list");
10400                 return;
10401             }
10402
10403             //update content provider record entry info
10404             ComponentName comp = new ComponentName(cpr.info.packageName, cpr.info.name);
10405             ContentProviderRecord localCpr = mProviderMap.getProviderByClass(comp, userId);
10406             if (localCpr.hasExternalProcessHandles()) {
10407                 if (localCpr.removeExternalProcessHandleLocked(token)) {
10408                     updateOomAdjLocked();
10409                 } else {
10410                     Slog.e(TAG, "Attmpt to remove content provider " + localCpr
10411                             + " with no external reference for token: "
10412                             + token + ".");
10413                 }
10414             } else {
10415                 Slog.e(TAG, "Attmpt to remove content provider: " + localCpr
10416                         + " with no external references.");
10417             }
10418         }
10419     }
10420
10421     public final void publishContentProviders(IApplicationThread caller,
10422             List<ContentProviderHolder> providers) {
10423         if (providers == null) {
10424             return;
10425         }
10426
10427         enforceNotIsolatedCaller("publishContentProviders");
10428         synchronized (this) {
10429             final ProcessRecord r = getRecordForAppLocked(caller);
10430             if (DEBUG_MU) Slog.v(TAG_MU, "ProcessRecord uid = " + r.uid);
10431             if (r == null) {
10432                 throw new SecurityException(
10433                         "Unable to find app for caller " + caller
10434                       + " (pid=" + Binder.getCallingPid()
10435                       + ") when publishing content providers");
10436             }
10437
10438             final long origId = Binder.clearCallingIdentity();
10439
10440             final int N = providers.size();
10441             for (int i = 0; i < N; i++) {
10442                 ContentProviderHolder src = providers.get(i);
10443                 if (src == null || src.info == null || src.provider == null) {
10444                     continue;
10445                 }
10446                 ContentProviderRecord dst = r.pubProviders.get(src.info.name);
10447                 if (DEBUG_MU) Slog.v(TAG_MU, "ContentProviderRecord uid = " + dst.uid);
10448                 if (dst != null) {
10449                     ComponentName comp = new ComponentName(dst.info.packageName, dst.info.name);
10450                     mProviderMap.putProviderByClass(comp, dst);
10451                     String names[] = dst.info.authority.split(";");
10452                     for (int j = 0; j < names.length; j++) {
10453                         mProviderMap.putProviderByName(names[j], dst);
10454                     }
10455
10456                     int launchingCount = mLaunchingProviders.size();
10457                     int j;
10458                     boolean wasInLaunchingProviders = false;
10459                     for (j = 0; j < launchingCount; j++) {
10460                         if (mLaunchingProviders.get(j) == dst) {
10461                             mLaunchingProviders.remove(j);
10462                             wasInLaunchingProviders = true;
10463                             j--;
10464                             launchingCount--;
10465                         }
10466                     }
10467                     if (wasInLaunchingProviders) {
10468                         mHandler.removeMessages(CONTENT_PROVIDER_PUBLISH_TIMEOUT_MSG, r);
10469                     }
10470                     synchronized (dst) {
10471                         dst.provider = src.provider;
10472                         dst.proc = r;
10473                         dst.notifyAll();
10474                     }
10475                     updateOomAdjLocked(r);
10476                     maybeUpdateProviderUsageStatsLocked(r, src.info.packageName,
10477                             src.info.authority);
10478                 }
10479             }
10480
10481             Binder.restoreCallingIdentity(origId);
10482         }
10483     }
10484
10485     public boolean refContentProvider(IBinder connection, int stable, int unstable) {
10486         ContentProviderConnection conn;
10487         try {
10488             conn = (ContentProviderConnection)connection;
10489         } catch (ClassCastException e) {
10490             String msg ="refContentProvider: " + connection
10491                     + " not a ContentProviderConnection";
10492             Slog.w(TAG, msg);
10493             throw new IllegalArgumentException(msg);
10494         }
10495         if (conn == null) {
10496             throw new NullPointerException("connection is null");
10497         }
10498
10499         synchronized (this) {
10500             if (stable > 0) {
10501                 conn.numStableIncs += stable;
10502             }
10503             stable = conn.stableCount + stable;
10504             if (stable < 0) {
10505                 throw new IllegalStateException("stableCount < 0: " + stable);
10506             }
10507
10508             if (unstable > 0) {
10509                 conn.numUnstableIncs += unstable;
10510             }
10511             unstable = conn.unstableCount + unstable;
10512             if (unstable < 0) {
10513                 throw new IllegalStateException("unstableCount < 0: " + unstable);
10514             }
10515
10516             if ((stable+unstable) <= 0) {
10517                 throw new IllegalStateException("ref counts can't go to zero here: stable="
10518                         + stable + " unstable=" + unstable);
10519             }
10520             conn.stableCount = stable;
10521             conn.unstableCount = unstable;
10522             return !conn.dead;
10523         }
10524     }
10525
10526     public void unstableProviderDied(IBinder connection) {
10527         ContentProviderConnection conn;
10528         try {
10529             conn = (ContentProviderConnection)connection;
10530         } catch (ClassCastException e) {
10531             String msg ="refContentProvider: " + connection
10532                     + " not a ContentProviderConnection";
10533             Slog.w(TAG, msg);
10534             throw new IllegalArgumentException(msg);
10535         }
10536         if (conn == null) {
10537             throw new NullPointerException("connection is null");
10538         }
10539
10540         // Safely retrieve the content provider associated with the connection.
10541         IContentProvider provider;
10542         synchronized (this) {
10543             provider = conn.provider.provider;
10544         }
10545
10546         if (provider == null) {
10547             // Um, yeah, we're way ahead of you.
10548             return;
10549         }
10550
10551         // Make sure the caller is being honest with us.
10552         if (provider.asBinder().pingBinder()) {
10553             // Er, no, still looks good to us.
10554             synchronized (this) {
10555                 Slog.w(TAG, "unstableProviderDied: caller " + Binder.getCallingUid()
10556                         + " says " + conn + " died, but we don't agree");
10557                 return;
10558             }
10559         }
10560
10561         // Well look at that!  It's dead!
10562         synchronized (this) {
10563             if (conn.provider.provider != provider) {
10564                 // But something changed...  good enough.
10565                 return;
10566             }
10567
10568             ProcessRecord proc = conn.provider.proc;
10569             if (proc == null || proc.thread == null) {
10570                 // Seems like the process is already cleaned up.
10571                 return;
10572             }
10573
10574             // As far as we're concerned, this is just like receiving a
10575             // death notification...  just a bit prematurely.
10576             Slog.i(TAG, "Process " + proc.processName + " (pid " + proc.pid
10577                     + ") early provider death");
10578             final long ident = Binder.clearCallingIdentity();
10579             try {
10580                 appDiedLocked(proc);
10581             } finally {
10582                 Binder.restoreCallingIdentity(ident);
10583             }
10584         }
10585     }
10586
10587     @Override
10588     public void appNotRespondingViaProvider(IBinder connection) {
10589         enforceCallingPermission(
10590                 android.Manifest.permission.REMOVE_TASKS, "appNotRespondingViaProvider()");
10591
10592         final ContentProviderConnection conn = (ContentProviderConnection) connection;
10593         if (conn == null) {
10594             Slog.w(TAG, "ContentProviderConnection is null");
10595             return;
10596         }
10597
10598         final ProcessRecord host = conn.provider.proc;
10599         if (host == null) {
10600             Slog.w(TAG, "Failed to find hosting ProcessRecord");
10601             return;
10602         }
10603
10604         final long token = Binder.clearCallingIdentity();
10605         try {
10606             appNotResponding(host, null, null, false, "ContentProvider not responding");
10607         } finally {
10608             Binder.restoreCallingIdentity(token);
10609         }
10610     }
10611
10612     public final void installSystemProviders() {
10613         List<ProviderInfo> providers;
10614         synchronized (this) {
10615             ProcessRecord app = mProcessNames.get("system", Process.SYSTEM_UID);
10616             providers = generateApplicationProvidersLocked(app);
10617             if (providers != null) {
10618                 for (int i=providers.size()-1; i>=0; i--) {
10619                     ProviderInfo pi = (ProviderInfo)providers.get(i);
10620                     if ((pi.applicationInfo.flags&ApplicationInfo.FLAG_SYSTEM) == 0) {
10621                         Slog.w(TAG, "Not installing system proc provider " + pi.name
10622                                 + ": not system .apk");
10623                         providers.remove(i);
10624                     }
10625                 }
10626             }
10627         }
10628         if (providers != null) {
10629             mSystemThread.installSystemProviders(providers);
10630         }
10631
10632         mCoreSettingsObserver = new CoreSettingsObserver(this);
10633
10634         //mUsageStatsService.monitorPackages();
10635     }
10636
10637     /**
10638      * Allows apps to retrieve the MIME type of a URI.
10639      * If an app is in the same user as the ContentProvider, or if it is allowed to interact across
10640      * users, then it does not need permission to access the ContentProvider.
10641      * Either, it needs cross-user uri grants.
10642      *
10643      * CTS tests for this functionality can be run with "runtest cts-appsecurity".
10644      *
10645      * Test cases are at cts/tests/appsecurity-tests/test-apps/UsePermissionDiffCert/
10646      *     src/com/android/cts/usespermissiondiffcertapp/AccessPermissionWithDiffSigTest.java
10647      */
10648     public String getProviderMimeType(Uri uri, int userId) {
10649         enforceNotIsolatedCaller("getProviderMimeType");
10650         final String name = uri.getAuthority();
10651         int callingUid = Binder.getCallingUid();
10652         int callingPid = Binder.getCallingPid();
10653         long ident = 0;
10654         boolean clearedIdentity = false;
10655         synchronized (this) {
10656             userId = mUserController.unsafeConvertIncomingUserLocked(userId);
10657         }
10658         if (canClearIdentity(callingPid, callingUid, userId)) {
10659             clearedIdentity = true;
10660             ident = Binder.clearCallingIdentity();
10661         }
10662         ContentProviderHolder holder = null;
10663         try {
10664             holder = getContentProviderExternalUnchecked(name, null, userId);
10665             if (holder != null) {
10666                 return holder.provider.getType(uri);
10667             }
10668         } catch (RemoteException e) {
10669             Log.w(TAG, "Content provider dead retrieving " + uri, e);
10670             return null;
10671         } finally {
10672             // We need to clear the identity to call removeContentProviderExternalUnchecked
10673             if (!clearedIdentity) {
10674                 ident = Binder.clearCallingIdentity();
10675             }
10676             try {
10677                 if (holder != null) {
10678                     removeContentProviderExternalUnchecked(name, null, userId);
10679                 }
10680             } finally {
10681                 Binder.restoreCallingIdentity(ident);
10682             }
10683         }
10684
10685         return null;
10686     }
10687
10688     private boolean canClearIdentity(int callingPid, int callingUid, int userId) {
10689         if (UserHandle.getUserId(callingUid) == userId) {
10690             return true;
10691         }
10692         if (checkComponentPermission(INTERACT_ACROSS_USERS, callingPid,
10693                 callingUid, -1, true) == PackageManager.PERMISSION_GRANTED
10694                 || checkComponentPermission(INTERACT_ACROSS_USERS_FULL, callingPid,
10695                 callingUid, -1, true) == PackageManager.PERMISSION_GRANTED) {
10696                 return true;
10697         }
10698         return false;
10699     }
10700
10701     // =========================================================
10702     // GLOBAL MANAGEMENT
10703     // =========================================================
10704
10705     final ProcessRecord newProcessRecordLocked(ApplicationInfo info, String customProcess,
10706             boolean isolated, int isolatedUid) {
10707         String proc = customProcess != null ? customProcess : info.processName;
10708         BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
10709         final int userId = UserHandle.getUserId(info.uid);
10710         int uid = info.uid;
10711         if (isolated) {
10712             if (isolatedUid == 0) {
10713                 int stepsLeft = Process.LAST_ISOLATED_UID - Process.FIRST_ISOLATED_UID + 1;
10714                 while (true) {
10715                     if (mNextIsolatedProcessUid < Process.FIRST_ISOLATED_UID
10716                             || mNextIsolatedProcessUid > Process.LAST_ISOLATED_UID) {
10717                         mNextIsolatedProcessUid = Process.FIRST_ISOLATED_UID;
10718                     }
10719                     uid = UserHandle.getUid(userId, mNextIsolatedProcessUid);
10720                     mNextIsolatedProcessUid++;
10721                     if (mIsolatedProcesses.indexOfKey(uid) < 0) {
10722                         // No process for this uid, use it.
10723                         break;
10724                     }
10725                     stepsLeft--;
10726                     if (stepsLeft <= 0) {
10727                         return null;
10728                     }
10729                 }
10730             } else {
10731                 // Special case for startIsolatedProcess (internal only), where
10732                 // the uid of the isolated process is specified by the caller.
10733                 uid = isolatedUid;
10734             }
10735         }
10736         final ProcessRecord r = new ProcessRecord(stats, info, proc, uid);
10737         if (!mBooted && !mBooting
10738                 && userId == UserHandle.USER_SYSTEM
10739                 && (info.flags & PERSISTENT_MASK) == PERSISTENT_MASK) {
10740             r.persistent = true;
10741         }
10742         addProcessNameLocked(r);
10743         return r;
10744     }
10745
10746     final ProcessRecord addAppLocked(ApplicationInfo info, boolean isolated,
10747             String abiOverride) {
10748         ProcessRecord app;
10749         if (!isolated) {
10750             app = getProcessRecordLocked(info.processName, info.uid, true);
10751         } else {
10752             app = null;
10753         }
10754
10755         if (app == null) {
10756             app = newProcessRecordLocked(info, null, isolated, 0);
10757             updateLruProcessLocked(app, false, null);
10758             updateOomAdjLocked();
10759         }
10760
10761         // This package really, really can not be stopped.
10762         try {
10763             AppGlobals.getPackageManager().setPackageStoppedState(
10764                     info.packageName, false, UserHandle.getUserId(app.uid));
10765         } catch (RemoteException e) {
10766         } catch (IllegalArgumentException e) {
10767             Slog.w(TAG, "Failed trying to unstop package "
10768                     + info.packageName + ": " + e);
10769         }
10770
10771         if ((info.flags & PERSISTENT_MASK) == PERSISTENT_MASK) {
10772             app.persistent = true;
10773             app.maxAdj = ProcessList.PERSISTENT_PROC_ADJ;
10774         }
10775         if (app.thread == null && mPersistentStartingProcesses.indexOf(app) < 0) {
10776             mPersistentStartingProcesses.add(app);
10777             startProcessLocked(app, "added application", app.processName, abiOverride,
10778                     null /* entryPoint */, null /* entryPointArgs */);
10779         }
10780
10781         return app;
10782     }
10783
10784     public void unhandledBack() {
10785         enforceCallingPermission(android.Manifest.permission.FORCE_BACK,
10786                 "unhandledBack()");
10787
10788         synchronized(this) {
10789             final long origId = Binder.clearCallingIdentity();
10790             try {
10791                 getFocusedStack().unhandledBackLocked();
10792             } finally {
10793                 Binder.restoreCallingIdentity(origId);
10794             }
10795         }
10796     }
10797
10798     public ParcelFileDescriptor openContentUri(Uri uri) throws RemoteException {
10799         enforceNotIsolatedCaller("openContentUri");
10800         final int userId = UserHandle.getCallingUserId();
10801         String name = uri.getAuthority();
10802         ContentProviderHolder cph = getContentProviderExternalUnchecked(name, null, userId);
10803         ParcelFileDescriptor pfd = null;
10804         if (cph != null) {
10805             // We record the binder invoker's uid in thread-local storage before
10806             // going to the content provider to open the file.  Later, in the code
10807             // that handles all permissions checks, we look for this uid and use
10808             // that rather than the Activity Manager's own uid.  The effect is that
10809             // we do the check against the caller's permissions even though it looks
10810             // to the content provider like the Activity Manager itself is making
10811             // the request.
10812             Binder token = new Binder();
10813             sCallerIdentity.set(new Identity(
10814                     token, Binder.getCallingPid(), Binder.getCallingUid()));
10815             try {
10816                 pfd = cph.provider.openFile(null, uri, "r", null, token);
10817             } catch (FileNotFoundException e) {
10818                 // do nothing; pfd will be returned null
10819             } finally {
10820                 // Ensure that whatever happens, we clean up the identity state
10821                 sCallerIdentity.remove();
10822                 // Ensure we're done with the provider.
10823                 removeContentProviderExternalUnchecked(name, null, userId);
10824             }
10825         } else {
10826             Slog.d(TAG, "Failed to get provider for authority '" + name + "'");
10827         }
10828         return pfd;
10829     }
10830
10831     // Actually is sleeping or shutting down or whatever else in the future
10832     // is an inactive state.
10833     public boolean isSleepingOrShuttingDown() {
10834         return isSleeping() || mShuttingDown;
10835     }
10836
10837     public boolean isSleeping() {
10838         return mSleeping;
10839     }
10840
10841     void onWakefulnessChanged(int wakefulness) {
10842         synchronized(this) {
10843             mWakefulness = wakefulness;
10844             updateSleepIfNeededLocked();
10845         }
10846     }
10847
10848     void finishRunningVoiceLocked() {
10849         if (mRunningVoice != null) {
10850             mRunningVoice = null;
10851             mVoiceWakeLock.release();
10852             updateSleepIfNeededLocked();
10853         }
10854     }
10855
10856     void startTimeTrackingFocusedActivityLocked() {
10857         if (!mSleeping && mCurAppTimeTracker != null && mFocusedActivity != null) {
10858             mCurAppTimeTracker.start(mFocusedActivity.packageName);
10859         }
10860     }
10861
10862     void updateSleepIfNeededLocked() {
10863         if (mSleeping && !shouldSleepLocked()) {
10864             mSleeping = false;
10865             startTimeTrackingFocusedActivityLocked();
10866             mTopProcessState = ActivityManager.PROCESS_STATE_TOP;
10867             mStackSupervisor.comeOutOfSleepIfNeededLocked();
10868             updateOomAdjLocked();
10869         } else if (!mSleeping && shouldSleepLocked()) {
10870             mSleeping = true;
10871             if (mCurAppTimeTracker != null) {
10872                 mCurAppTimeTracker.stop();
10873             }
10874             mTopProcessState = ActivityManager.PROCESS_STATE_TOP_SLEEPING;
10875             mStackSupervisor.goingToSleepLocked();
10876             updateOomAdjLocked();
10877
10878             // Initialize the wake times of all processes.
10879             checkExcessivePowerUsageLocked(false);
10880             mHandler.removeMessages(CHECK_EXCESSIVE_WAKE_LOCKS_MSG);
10881             Message nmsg = mHandler.obtainMessage(CHECK_EXCESSIVE_WAKE_LOCKS_MSG);
10882             mHandler.sendMessageDelayed(nmsg, POWER_CHECK_DELAY);
10883         }
10884     }
10885
10886     private boolean shouldSleepLocked() {
10887         // Resume applications while running a voice interactor.
10888         if (mRunningVoice != null) {
10889             return false;
10890         }
10891
10892         // TODO: Transform the lock screen state into a sleep token instead.
10893         switch (mWakefulness) {
10894             case PowerManagerInternal.WAKEFULNESS_AWAKE:
10895             case PowerManagerInternal.WAKEFULNESS_DREAMING:
10896             case PowerManagerInternal.WAKEFULNESS_DOZING:
10897                 // Pause applications whenever the lock screen is shown or any sleep
10898                 // tokens have been acquired.
10899                 return (mLockScreenShown != LOCK_SCREEN_HIDDEN || !mSleepTokens.isEmpty());
10900             case PowerManagerInternal.WAKEFULNESS_ASLEEP:
10901             default:
10902                 // If we're asleep then pause applications unconditionally.
10903                 return true;
10904         }
10905     }
10906
10907     /** Pokes the task persister. */
10908     void notifyTaskPersisterLocked(TaskRecord task, boolean flush) {
10909         if (task != null && task.stack != null && task.stack.isHomeStack()) {
10910             // Never persist the home stack.
10911             return;
10912         }
10913         mTaskPersister.wakeup(task, flush);
10914     }
10915
10916     /** Notifies all listeners when the task stack has changed. */
10917     void notifyTaskStackChangedLocked() {
10918         mHandler.removeMessages(NOTIFY_TASK_STACK_CHANGE_LISTENERS_MSG);
10919         Message nmsg = mHandler.obtainMessage(NOTIFY_TASK_STACK_CHANGE_LISTENERS_MSG);
10920         mHandler.sendMessageDelayed(nmsg, NOTIFY_TASK_STACK_CHANGE_LISTENERS_DELAY);
10921     }
10922
10923     @Override
10924     public void notifyCleartextNetwork(int uid, byte[] firstPacket) {
10925         mHandler.obtainMessage(NOTIFY_CLEARTEXT_NETWORK_MSG, uid, 0, firstPacket).sendToTarget();
10926     }
10927
10928     @Override
10929     public boolean shutdown(int timeout) {
10930         if (checkCallingPermission(android.Manifest.permission.SHUTDOWN)
10931                 != PackageManager.PERMISSION_GRANTED) {
10932             throw new SecurityException("Requires permission "
10933                     + android.Manifest.permission.SHUTDOWN);
10934         }
10935
10936         boolean timedout = false;
10937
10938         synchronized(this) {
10939             mShuttingDown = true;
10940             updateEventDispatchingLocked();
10941             timedout = mStackSupervisor.shutdownLocked(timeout);
10942         }
10943
10944         mAppOpsService.shutdown();
10945         if (mUsageStatsService != null) {
10946             mUsageStatsService.prepareShutdown();
10947         }
10948         mBatteryStatsService.shutdown();
10949         synchronized (this) {
10950             mProcessStats.shutdownLocked();
10951             notifyTaskPersisterLocked(null, true);
10952         }
10953
10954         return timedout;
10955     }
10956
10957     public final void activitySlept(IBinder token) {
10958         if (DEBUG_ALL) Slog.v(TAG, "Activity slept: token=" + token);
10959
10960         final long origId = Binder.clearCallingIdentity();
10961
10962         synchronized (this) {
10963             final ActivityRecord r = ActivityRecord.isInStackLocked(token);
10964             if (r != null) {
10965                 mStackSupervisor.activitySleptLocked(r);
10966             }
10967         }
10968
10969         Binder.restoreCallingIdentity(origId);
10970     }
10971
10972     private String lockScreenShownToString() {
10973         switch (mLockScreenShown) {
10974             case LOCK_SCREEN_HIDDEN: return "LOCK_SCREEN_HIDDEN";
10975             case LOCK_SCREEN_LEAVING: return "LOCK_SCREEN_LEAVING";
10976             case LOCK_SCREEN_SHOWN: return "LOCK_SCREEN_SHOWN";
10977             default: return "Unknown=" + mLockScreenShown;
10978         }
10979     }
10980
10981     void logLockScreen(String msg) {
10982         if (DEBUG_LOCKSCREEN) Slog.d(TAG_LOCKSCREEN, Debug.getCallers(2) + ":" + msg
10983                 + " mLockScreenShown=" + lockScreenShownToString() + " mWakefulness="
10984                 + PowerManagerInternal.wakefulnessToString(mWakefulness)
10985                 + " mSleeping=" + mSleeping);
10986     }
10987
10988     void startRunningVoiceLocked(IVoiceInteractionSession session, int targetUid) {
10989         mVoiceWakeLock.setWorkSource(new WorkSource(targetUid));
10990         if (mRunningVoice == null || mRunningVoice.asBinder() != session.asBinder()) {
10991             boolean wasRunningVoice = mRunningVoice != null;
10992             mRunningVoice = session;
10993             if (!wasRunningVoice) {
10994                 mVoiceWakeLock.acquire();
10995                 updateSleepIfNeededLocked();
10996             }
10997         }
10998     }
10999
11000     private void updateEventDispatchingLocked() {
11001         mWindowManager.setEventDispatching(mBooted && !mShuttingDown);
11002     }
11003
11004     public void setLockScreenShown(boolean shown) {
11005         if (checkCallingPermission(android.Manifest.permission.DEVICE_POWER)
11006                 != PackageManager.PERMISSION_GRANTED) {
11007             throw new SecurityException("Requires permission "
11008                     + android.Manifest.permission.DEVICE_POWER);
11009         }
11010
11011         synchronized(this) {
11012             long ident = Binder.clearCallingIdentity();
11013             try {
11014                 if (DEBUG_LOCKSCREEN) logLockScreen(" shown=" + shown);
11015                 mLockScreenShown = shown ? LOCK_SCREEN_SHOWN : LOCK_SCREEN_HIDDEN;
11016                 updateSleepIfNeededLocked();
11017             } finally {
11018                 Binder.restoreCallingIdentity(ident);
11019             }
11020         }
11021     }
11022
11023     @Override
11024     public void stopAppSwitches() {
11025         if (checkCallingPermission(android.Manifest.permission.STOP_APP_SWITCHES)
11026                 != PackageManager.PERMISSION_GRANTED) {
11027             throw new SecurityException("viewquires permission "
11028                     + android.Manifest.permission.STOP_APP_SWITCHES);
11029         }
11030
11031         synchronized(this) {
11032             mAppSwitchesAllowedTime = SystemClock.uptimeMillis()
11033                     + APP_SWITCH_DELAY_TIME;
11034             mDidAppSwitch = false;
11035             mHandler.removeMessages(DO_PENDING_ACTIVITY_LAUNCHES_MSG);
11036             Message msg = mHandler.obtainMessage(DO_PENDING_ACTIVITY_LAUNCHES_MSG);
11037             mHandler.sendMessageDelayed(msg, APP_SWITCH_DELAY_TIME);
11038         }
11039     }
11040
11041     public void resumeAppSwitches() {
11042         if (checkCallingPermission(android.Manifest.permission.STOP_APP_SWITCHES)
11043                 != PackageManager.PERMISSION_GRANTED) {
11044             throw new SecurityException("Requires permission "
11045                     + android.Manifest.permission.STOP_APP_SWITCHES);
11046         }
11047
11048         synchronized(this) {
11049             // Note that we don't execute any pending app switches... we will
11050             // let those wait until either the timeout, or the next start
11051             // activity request.
11052             mAppSwitchesAllowedTime = 0;
11053         }
11054     }
11055
11056     boolean checkAppSwitchAllowedLocked(int sourcePid, int sourceUid,
11057             int callingPid, int callingUid, String name) {
11058         if (mAppSwitchesAllowedTime < SystemClock.uptimeMillis()) {
11059             return true;
11060         }
11061
11062         int perm = checkComponentPermission(
11063                 android.Manifest.permission.STOP_APP_SWITCHES, sourcePid,
11064                 sourceUid, -1, true);
11065         if (perm == PackageManager.PERMISSION_GRANTED) {
11066             return true;
11067         }
11068
11069         // If the actual IPC caller is different from the logical source, then
11070         // also see if they are allowed to control app switches.
11071         if (callingUid != -1 && callingUid != sourceUid) {
11072             perm = checkComponentPermission(
11073                     android.Manifest.permission.STOP_APP_SWITCHES, callingPid,
11074                     callingUid, -1, true);
11075             if (perm == PackageManager.PERMISSION_GRANTED) {
11076                 return true;
11077             }
11078         }
11079
11080         Slog.w(TAG, name + " request from " + sourceUid + " stopped");
11081         return false;
11082     }
11083
11084     public void setDebugApp(String packageName, boolean waitForDebugger,
11085             boolean persistent) {
11086         enforceCallingPermission(android.Manifest.permission.SET_DEBUG_APP,
11087                 "setDebugApp()");
11088
11089         long ident = Binder.clearCallingIdentity();
11090         try {
11091             // Note that this is not really thread safe if there are multiple
11092             // callers into it at the same time, but that's not a situation we
11093             // care about.
11094             if (persistent) {
11095                 final ContentResolver resolver = mContext.getContentResolver();
11096                 Settings.Global.putString(
11097                     resolver, Settings.Global.DEBUG_APP,
11098                     packageName);
11099                 Settings.Global.putInt(
11100                     resolver, Settings.Global.WAIT_FOR_DEBUGGER,
11101                     waitForDebugger ? 1 : 0);
11102             }
11103
11104             synchronized (this) {
11105                 if (!persistent) {
11106                     mOrigDebugApp = mDebugApp;
11107                     mOrigWaitForDebugger = mWaitForDebugger;
11108                 }
11109                 mDebugApp = packageName;
11110                 mWaitForDebugger = waitForDebugger;
11111                 mDebugTransient = !persistent;
11112                 if (packageName != null) {
11113                     forceStopPackageLocked(packageName, -1, false, false, true, true,
11114                             false, UserHandle.USER_ALL, "set debug app");
11115                 }
11116             }
11117         } finally {
11118             Binder.restoreCallingIdentity(ident);
11119         }
11120     }
11121
11122     void setTrackAllocationApp(ApplicationInfo app, String processName) {
11123         synchronized (this) {
11124             boolean isDebuggable = "1".equals(SystemProperties.get(SYSTEM_DEBUGGABLE, "0"));
11125             if (!isDebuggable) {
11126                 if ((app.flags & ApplicationInfo.FLAG_DEBUGGABLE) == 0) {
11127                     throw new SecurityException("Process not debuggable: " + app.packageName);
11128                 }
11129             }
11130
11131             mTrackAllocationApp = processName;
11132         }
11133     }
11134
11135     void setProfileApp(ApplicationInfo app, String processName, ProfilerInfo profilerInfo) {
11136         synchronized (this) {
11137             boolean isDebuggable = "1".equals(SystemProperties.get(SYSTEM_DEBUGGABLE, "0"));
11138             if (!isDebuggable) {
11139                 if ((app.flags & ApplicationInfo.FLAG_DEBUGGABLE) == 0) {
11140                     throw new SecurityException("Process not debuggable: " + app.packageName);
11141                 }
11142             }
11143             mProfileApp = processName;
11144             mProfileFile = profilerInfo.profileFile;
11145             if (mProfileFd != null) {
11146                 try {
11147                     mProfileFd.close();
11148                 } catch (IOException e) {
11149                 }
11150                 mProfileFd = null;
11151             }
11152             mProfileFd = profilerInfo.profileFd;
11153             mSamplingInterval = profilerInfo.samplingInterval;
11154             mAutoStopProfiler = profilerInfo.autoStopProfiler;
11155             mProfileType = 0;
11156         }
11157     }
11158
11159     @Override
11160     public void setAlwaysFinish(boolean enabled) {
11161         enforceCallingPermission(android.Manifest.permission.SET_ALWAYS_FINISH,
11162                 "setAlwaysFinish()");
11163
11164         Settings.Global.putInt(
11165                 mContext.getContentResolver(),
11166                 Settings.Global.ALWAYS_FINISH_ACTIVITIES, enabled ? 1 : 0);
11167
11168         synchronized (this) {
11169             mAlwaysFinishActivities = enabled;
11170         }
11171     }
11172
11173     @Override
11174     public void setActivityController(IActivityController controller) {
11175         enforceCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER,
11176                 "setActivityController()");
11177         synchronized (this) {
11178             mController = controller;
11179             Watchdog.getInstance().setActivityController(controller);
11180         }
11181     }
11182
11183     @Override
11184     public void setUserIsMonkey(boolean userIsMonkey) {
11185         synchronized (this) {
11186             synchronized (mPidsSelfLocked) {
11187                 final int callingPid = Binder.getCallingPid();
11188                 ProcessRecord precessRecord = mPidsSelfLocked.get(callingPid);
11189                 if (precessRecord == null) {
11190                     throw new SecurityException("Unknown process: " + callingPid);
11191                 }
11192                 if (precessRecord.instrumentationUiAutomationConnection  == null) {
11193                     throw new SecurityException("Only an instrumentation process "
11194                             + "with a UiAutomation can call setUserIsMonkey");
11195                 }
11196             }
11197             mUserIsMonkey = userIsMonkey;
11198         }
11199     }
11200
11201     @Override
11202     public boolean isUserAMonkey() {
11203         synchronized (this) {
11204             // If there is a controller also implies the user is a monkey.
11205             return (mUserIsMonkey || mController != null);
11206         }
11207     }
11208
11209     public void requestBugReport() {
11210         enforceCallingPermission(android.Manifest.permission.DUMP, "requestBugReport");
11211         SystemProperties.set("ctl.start", "bugreport");
11212     }
11213
11214     public static long getInputDispatchingTimeoutLocked(ActivityRecord r) {
11215         return r != null ? getInputDispatchingTimeoutLocked(r.app) : KEY_DISPATCHING_TIMEOUT;
11216     }
11217
11218     public static long getInputDispatchingTimeoutLocked(ProcessRecord r) {
11219         if (r != null && (r.instrumentationClass != null || r.usingWrapper)) {
11220             return INSTRUMENTATION_KEY_DISPATCHING_TIMEOUT;
11221         }
11222         return KEY_DISPATCHING_TIMEOUT;
11223     }
11224
11225     @Override
11226     public long inputDispatchingTimedOut(int pid, final boolean aboveSystem, String reason) {
11227         if (checkCallingPermission(android.Manifest.permission.FILTER_EVENTS)
11228                 != PackageManager.PERMISSION_GRANTED) {
11229             throw new SecurityException("Requires permission "
11230                     + android.Manifest.permission.FILTER_EVENTS);
11231         }
11232         ProcessRecord proc;
11233         long timeout;
11234         synchronized (this) {
11235             synchronized (mPidsSelfLocked) {
11236                 proc = mPidsSelfLocked.get(pid);
11237             }
11238             timeout = getInputDispatchingTimeoutLocked(proc);
11239         }
11240
11241         if (!inputDispatchingTimedOut(proc, null, null, aboveSystem, reason)) {
11242             return -1;
11243         }
11244
11245         return timeout;
11246     }
11247
11248     /**
11249      * Handle input dispatching timeouts.
11250      * Returns whether input dispatching should be aborted or not.
11251      */
11252     public boolean inputDispatchingTimedOut(final ProcessRecord proc,
11253             final ActivityRecord activity, final ActivityRecord parent,
11254             final boolean aboveSystem, String reason) {
11255         if (checkCallingPermission(android.Manifest.permission.FILTER_EVENTS)
11256                 != PackageManager.PERMISSION_GRANTED) {
11257             throw new SecurityException("Requires permission "
11258                     + android.Manifest.permission.FILTER_EVENTS);
11259         }
11260
11261         final String annotation;
11262         if (reason == null) {
11263             annotation = "Input dispatching timed out";
11264         } else {
11265             annotation = "Input dispatching timed out (" + reason + ")";
11266         }
11267
11268         if (proc != null) {
11269             synchronized (this) {
11270                 if (proc.debugging) {
11271                     return false;
11272                 }
11273
11274                 if (mDidDexOpt) {
11275                     // Give more time since we were dexopting.
11276                     mDidDexOpt = false;
11277                     return false;
11278                 }
11279
11280                 if (proc.instrumentationClass != null) {
11281                     Bundle info = new Bundle();
11282                     info.putString("shortMsg", "keyDispatchingTimedOut");
11283                     info.putString("longMsg", annotation);
11284                     finishInstrumentationLocked(proc, Activity.RESULT_CANCELED, info);
11285                     return true;
11286                 }
11287             }
11288             mHandler.post(new Runnable() {
11289                 @Override
11290                 public void run() {
11291                     appNotResponding(proc, activity, parent, aboveSystem, annotation);
11292                 }
11293             });
11294         }
11295
11296         return true;
11297     }
11298
11299     @Override
11300     public Bundle getAssistContextExtras(int requestType) {
11301         PendingAssistExtras pae = enqueueAssistContext(requestType, null, null, null,
11302                 null, UserHandle.getCallingUserId(), null, PENDING_ASSIST_EXTRAS_TIMEOUT);
11303         if (pae == null) {
11304             return null;
11305         }
11306         synchronized (pae) {
11307             while (!pae.haveResult) {
11308                 try {
11309                     pae.wait();
11310                 } catch (InterruptedException e) {
11311                 }
11312             }
11313         }
11314         synchronized (this) {
11315             buildAssistBundleLocked(pae, pae.result);
11316             mPendingAssistExtras.remove(pae);
11317             mUiHandler.removeCallbacks(pae);
11318         }
11319         return pae.extras;
11320     }
11321
11322     @Override
11323     public boolean isAssistDataAllowedOnCurrentActivity() {
11324         int userId;
11325         synchronized (this) {
11326             userId = mUserController.getCurrentUserIdLocked();
11327             ActivityRecord activity = getFocusedStack().topActivity();
11328             if (activity == null) {
11329                 return false;
11330             }
11331             userId = activity.userId;
11332         }
11333         DevicePolicyManager dpm = (DevicePolicyManager) mContext.getSystemService(
11334                 Context.DEVICE_POLICY_SERVICE);
11335         return (dpm == null) || (!dpm.getScreenCaptureDisabled(null, userId));
11336     }
11337
11338     @Override
11339     public boolean showAssistFromActivity(IBinder token, Bundle args) {
11340         long ident = Binder.clearCallingIdentity();
11341         try {
11342             synchronized (this) {
11343                 ActivityRecord caller = ActivityRecord.forTokenLocked(token);
11344                 ActivityRecord top = getFocusedStack().topActivity();
11345                 if (top != caller) {
11346                     Slog.w(TAG, "showAssistFromActivity failed: caller " + caller
11347                             + " is not current top " + top);
11348                     return false;
11349                 }
11350                 if (!top.nowVisible) {
11351                     Slog.w(TAG, "showAssistFromActivity failed: caller " + caller
11352                             + " is not visible");
11353                     return false;
11354                 }
11355             }
11356             AssistUtils utils = new AssistUtils(mContext);
11357             return utils.showSessionForActiveService(args,
11358                     VoiceInteractionSession.SHOW_SOURCE_APPLICATION, null, token);
11359         } finally {
11360             Binder.restoreCallingIdentity(ident);
11361         }
11362     }
11363
11364     @Override
11365     public boolean requestAssistContextExtras(int requestType, IResultReceiver receiver,
11366             IBinder activityToken) {
11367         return enqueueAssistContext(requestType, null, null, receiver, activityToken,
11368                 UserHandle.getCallingUserId(), null, PENDING_ASSIST_EXTRAS_LONG_TIMEOUT) != null;
11369     }
11370
11371     private PendingAssistExtras enqueueAssistContext(int requestType, Intent intent, String hint,
11372             IResultReceiver receiver, IBinder activityToken, int userHandle, Bundle args,
11373             long timeout) {
11374         enforceCallingPermission(android.Manifest.permission.GET_TOP_ACTIVITY_INFO,
11375                 "enqueueAssistContext()");
11376         synchronized (this) {
11377             ActivityRecord activity = getFocusedStack().topActivity();
11378             if (activity == null) {
11379                 Slog.w(TAG, "getAssistContextExtras failed: no top activity");
11380                 return null;
11381             }
11382             if (activity.app == null || activity.app.thread == null) {
11383                 Slog.w(TAG, "getAssistContextExtras failed: no process for " + activity);
11384                 return null;
11385             }
11386             if (activityToken != null) {
11387                 ActivityRecord caller = ActivityRecord.forTokenLocked(activityToken);
11388                 if (activity != caller) {
11389                     Slog.w(TAG, "enqueueAssistContext failed: caller " + caller
11390                             + " is not current top " + activity);
11391                     return null;
11392                 }
11393             }
11394             PendingAssistExtras pae;
11395             Bundle extras = new Bundle();
11396             if (args != null) {
11397                 extras.putAll(args);
11398             }
11399             extras.putString(Intent.EXTRA_ASSIST_PACKAGE, activity.packageName);
11400             extras.putInt(Intent.EXTRA_ASSIST_UID, activity.app.uid);
11401             pae = new PendingAssistExtras(activity, extras, intent, hint, receiver, userHandle);
11402             try {
11403                 activity.app.thread.requestAssistContextExtras(activity.appToken, pae,
11404                         requestType);
11405                 mPendingAssistExtras.add(pae);
11406                 mUiHandler.postDelayed(pae, timeout);
11407             } catch (RemoteException e) {
11408                 Slog.w(TAG, "getAssistContextExtras failed: crash calling " + activity);
11409                 return null;
11410             }
11411             return pae;
11412         }
11413     }
11414
11415     void pendingAssistExtrasTimedOut(PendingAssistExtras pae) {
11416         IResultReceiver receiver;
11417         synchronized (this) {
11418             mPendingAssistExtras.remove(pae);
11419             receiver = pae.receiver;
11420         }
11421         if (receiver != null) {
11422             // Caller wants result sent back to them.
11423             try {
11424                 pae.receiver.send(0, null);
11425             } catch (RemoteException e) {
11426             }
11427         }
11428     }
11429
11430     private void buildAssistBundleLocked(PendingAssistExtras pae, Bundle result) {
11431         if (result != null) {
11432             pae.extras.putBundle(Intent.EXTRA_ASSIST_CONTEXT, result);
11433         }
11434         if (pae.hint != null) {
11435             pae.extras.putBoolean(pae.hint, true);
11436         }
11437     }
11438
11439     public void reportAssistContextExtras(IBinder token, Bundle extras, AssistStructure structure,
11440             AssistContent content, Uri referrer) {
11441         PendingAssistExtras pae = (PendingAssistExtras)token;
11442         synchronized (pae) {
11443             pae.result = extras;
11444             pae.structure = structure;
11445             pae.content = content;
11446             if (referrer != null) {
11447                 pae.extras.putParcelable(Intent.EXTRA_REFERRER, referrer);
11448             }
11449             pae.haveResult = true;
11450             pae.notifyAll();
11451             if (pae.intent == null && pae.receiver == null) {
11452                 // Caller is just waiting for the result.
11453                 return;
11454             }
11455         }
11456
11457         // We are now ready to launch the assist activity.
11458         IResultReceiver sendReceiver = null;
11459         Bundle sendBundle = null;
11460         synchronized (this) {
11461             buildAssistBundleLocked(pae, extras);
11462             boolean exists = mPendingAssistExtras.remove(pae);
11463             mUiHandler.removeCallbacks(pae);
11464             if (!exists) {
11465                 // Timed out.
11466                 return;
11467             }
11468             if ((sendReceiver=pae.receiver) != null) {
11469                 // Caller wants result sent back to them.
11470                 sendBundle = new Bundle();
11471                 sendBundle.putBundle("data", pae.extras);
11472                 sendBundle.putParcelable("structure", pae.structure);
11473                 sendBundle.putParcelable("content", pae.content);
11474             }
11475         }
11476         if (sendReceiver != null) {
11477             try {
11478                 sendReceiver.send(0, sendBundle);
11479             } catch (RemoteException e) {
11480             }
11481             return;
11482         }
11483
11484         long ident = Binder.clearCallingIdentity();
11485         try {
11486             pae.intent.replaceExtras(pae.extras);
11487             pae.intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK
11488                     | Intent.FLAG_ACTIVITY_SINGLE_TOP
11489                     | Intent.FLAG_ACTIVITY_CLEAR_TOP);
11490             closeSystemDialogs("assist");
11491             try {
11492                 mContext.startActivityAsUser(pae.intent, new UserHandle(pae.userHandle));
11493             } catch (ActivityNotFoundException e) {
11494                 Slog.w(TAG, "No activity to handle assist action.", e);
11495             }
11496         } finally {
11497             Binder.restoreCallingIdentity(ident);
11498         }
11499     }
11500
11501     public boolean launchAssistIntent(Intent intent, int requestType, String hint, int userHandle,
11502             Bundle args) {
11503         return enqueueAssistContext(requestType, intent, hint, null, null, userHandle, args,
11504                 PENDING_ASSIST_EXTRAS_TIMEOUT) != null;
11505     }
11506
11507     public void registerProcessObserver(IProcessObserver observer) {
11508         enforceCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER,
11509                 "registerProcessObserver()");
11510         synchronized (this) {
11511             mProcessObservers.register(observer);
11512         }
11513     }
11514
11515     @Override
11516     public void unregisterProcessObserver(IProcessObserver observer) {
11517         synchronized (this) {
11518             mProcessObservers.unregister(observer);
11519         }
11520     }
11521
11522     @Override
11523     public void registerUidObserver(IUidObserver observer, int which) {
11524         enforceCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER,
11525                 "registerUidObserver()");
11526         synchronized (this) {
11527             mUidObservers.register(observer, which);
11528         }
11529     }
11530
11531     @Override
11532     public void unregisterUidObserver(IUidObserver observer) {
11533         synchronized (this) {
11534             mUidObservers.unregister(observer);
11535         }
11536     }
11537
11538     @Override
11539     public boolean convertFromTranslucent(IBinder token) {
11540         final long origId = Binder.clearCallingIdentity();
11541         try {
11542             synchronized (this) {
11543                 final ActivityRecord r = ActivityRecord.isInStackLocked(token);
11544                 if (r == null) {
11545                     return false;
11546                 }
11547                 final boolean translucentChanged = r.changeWindowTranslucency(true);
11548                 if (translucentChanged) {
11549                     r.task.stack.releaseBackgroundResources(r);
11550                     mStackSupervisor.ensureActivitiesVisibleLocked(null, 0, !PRESERVE_WINDOWS);
11551                 }
11552                 mWindowManager.setAppFullscreen(token, true);
11553                 return translucentChanged;
11554             }
11555         } finally {
11556             Binder.restoreCallingIdentity(origId);
11557         }
11558     }
11559
11560     @Override
11561     public boolean convertToTranslucent(IBinder token, ActivityOptions options) {
11562         final long origId = Binder.clearCallingIdentity();
11563         try {
11564             synchronized (this) {
11565                 final ActivityRecord r = ActivityRecord.isInStackLocked(token);
11566                 if (r == null) {
11567                     return false;
11568                 }
11569                 int index = r.task.mActivities.lastIndexOf(r);
11570                 if (index > 0) {
11571                     ActivityRecord under = r.task.mActivities.get(index - 1);
11572                     under.returningOptions = options;
11573                 }
11574                 final boolean translucentChanged = r.changeWindowTranslucency(false);
11575                 if (translucentChanged) {
11576                     r.task.stack.convertActivityToTranslucent(r);
11577                 }
11578                 mStackSupervisor.ensureActivitiesVisibleLocked(null, 0, !PRESERVE_WINDOWS);
11579                 mWindowManager.setAppFullscreen(token, false);
11580                 return translucentChanged;
11581             }
11582         } finally {
11583             Binder.restoreCallingIdentity(origId);
11584         }
11585     }
11586
11587     @Override
11588     public boolean requestVisibleBehind(IBinder token, boolean visible) {
11589         final long origId = Binder.clearCallingIdentity();
11590         try {
11591             synchronized (this) {
11592                 final ActivityRecord r = ActivityRecord.isInStackLocked(token);
11593                 if (r != null) {
11594                     return mStackSupervisor.requestVisibleBehindLocked(r, visible);
11595                 }
11596             }
11597             return false;
11598         } finally {
11599             Binder.restoreCallingIdentity(origId);
11600         }
11601     }
11602
11603     @Override
11604     public boolean isBackgroundVisibleBehind(IBinder token) {
11605         final long origId = Binder.clearCallingIdentity();
11606         try {
11607             synchronized (this) {
11608                 final ActivityStack stack = ActivityRecord.getStackLocked(token);
11609                 final boolean visible = stack == null ? false : stack.hasVisibleBehindActivity();
11610                 if (DEBUG_VISIBLE_BEHIND) Slog.d(TAG_VISIBLE_BEHIND,
11611                         "isBackgroundVisibleBehind: stack=" + stack + " visible=" + visible);
11612                 return visible;
11613             }
11614         } finally {
11615             Binder.restoreCallingIdentity(origId);
11616         }
11617     }
11618
11619     @Override
11620     public ActivityOptions getActivityOptions(IBinder token) {
11621         final long origId = Binder.clearCallingIdentity();
11622         try {
11623             synchronized (this) {
11624                 final ActivityRecord r = ActivityRecord.isInStackLocked(token);
11625                 if (r != null) {
11626                     final ActivityOptions activityOptions = r.pendingOptions;
11627                     r.pendingOptions = null;
11628                     return activityOptions;
11629                 }
11630                 return null;
11631             }
11632         } finally {
11633             Binder.restoreCallingIdentity(origId);
11634         }
11635     }
11636
11637     @Override
11638     public void setImmersive(IBinder token, boolean immersive) {
11639         synchronized(this) {
11640             final ActivityRecord r = ActivityRecord.isInStackLocked(token);
11641             if (r == null) {
11642                 throw new IllegalArgumentException();
11643             }
11644             r.immersive = immersive;
11645
11646             // update associated state if we're frontmost
11647             if (r == mFocusedActivity) {
11648                 if (DEBUG_IMMERSIVE) Slog.d(TAG_IMMERSIVE, "Frontmost changed immersion: "+ r);
11649                 applyUpdateLockStateLocked(r);
11650             }
11651         }
11652     }
11653
11654     @Override
11655     public boolean isImmersive(IBinder token) {
11656         synchronized (this) {
11657             ActivityRecord r = ActivityRecord.isInStackLocked(token);
11658             if (r == null) {
11659                 throw new IllegalArgumentException();
11660             }
11661             return r.immersive;
11662         }
11663     }
11664
11665     public boolean isTopActivityImmersive() {
11666         enforceNotIsolatedCaller("startActivity");
11667         synchronized (this) {
11668             ActivityRecord r = getFocusedStack().topRunningActivityLocked();
11669             return (r != null) ? r.immersive : false;
11670         }
11671     }
11672
11673     @Override
11674     public boolean isTopOfTask(IBinder token) {
11675         synchronized (this) {
11676             ActivityRecord r = ActivityRecord.isInStackLocked(token);
11677             if (r == null) {
11678                 throw new IllegalArgumentException();
11679             }
11680             return r.task.getTopActivity() == r;
11681         }
11682     }
11683
11684     public final void enterSafeMode() {
11685         synchronized(this) {
11686             // It only makes sense to do this before the system is ready
11687             // and started launching other packages.
11688             if (!mSystemReady) {
11689                 try {
11690                     AppGlobals.getPackageManager().enterSafeMode();
11691                 } catch (RemoteException e) {
11692                 }
11693             }
11694
11695             mSafeMode = true;
11696         }
11697     }
11698
11699     public final void showSafeModeOverlay() {
11700         View v = LayoutInflater.from(mContext).inflate(
11701                 com.android.internal.R.layout.safe_mode, null);
11702         WindowManager.LayoutParams lp = new WindowManager.LayoutParams();
11703         lp.type = WindowManager.LayoutParams.TYPE_SECURE_SYSTEM_OVERLAY;
11704         lp.width = WindowManager.LayoutParams.WRAP_CONTENT;
11705         lp.height = WindowManager.LayoutParams.WRAP_CONTENT;
11706         lp.gravity = Gravity.BOTTOM | Gravity.START;
11707         lp.format = v.getBackground().getOpacity();
11708         lp.flags = WindowManager.LayoutParams.FLAG_NOT_FOCUSABLE
11709                 | WindowManager.LayoutParams.FLAG_NOT_TOUCHABLE;
11710         lp.privateFlags |= WindowManager.LayoutParams.PRIVATE_FLAG_SHOW_FOR_ALL_USERS;
11711         ((WindowManager)mContext.getSystemService(
11712                 Context.WINDOW_SERVICE)).addView(v, lp);
11713     }
11714
11715     public void noteWakeupAlarm(IIntentSender sender, int sourceUid, String sourcePkg, String tag) {
11716         if (sender != null && !(sender instanceof PendingIntentRecord)) {
11717             return;
11718         }
11719         final PendingIntentRecord rec = (PendingIntentRecord)sender;
11720         final BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
11721         synchronized (stats) {
11722             if (mBatteryStatsService.isOnBattery()) {
11723                 mBatteryStatsService.enforceCallingPermission();
11724                 int MY_UID = Binder.getCallingUid();
11725                 final int uid;
11726                 if (sender == null) {
11727                     uid = sourceUid;
11728                 } else {
11729                     uid = rec.uid == MY_UID ? Process.SYSTEM_UID : rec.uid;
11730                 }
11731                 BatteryStatsImpl.Uid.Pkg pkg =
11732                     stats.getPackageStatsLocked(sourceUid >= 0 ? sourceUid : uid,
11733                             sourcePkg != null ? sourcePkg : rec.key.packageName);
11734                 pkg.noteWakeupAlarmLocked(tag);
11735             }
11736         }
11737     }
11738
11739     public void noteAlarmStart(IIntentSender sender, int sourceUid, String tag) {
11740         if (sender != null && !(sender instanceof PendingIntentRecord)) {
11741             return;
11742         }
11743         final PendingIntentRecord rec = (PendingIntentRecord)sender;
11744         final BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
11745         synchronized (stats) {
11746             mBatteryStatsService.enforceCallingPermission();
11747             int MY_UID = Binder.getCallingUid();
11748             final int uid;
11749             if (sender == null) {
11750                 uid = sourceUid;
11751             } else {
11752                 uid = rec.uid == MY_UID ? Process.SYSTEM_UID : rec.uid;
11753             }
11754             mBatteryStatsService.noteAlarmStart(tag, sourceUid >= 0 ? sourceUid : uid);
11755         }
11756     }
11757
11758     public void noteAlarmFinish(IIntentSender sender, int sourceUid, String tag) {
11759         if (sender != null && !(sender instanceof PendingIntentRecord)) {
11760             return;
11761         }
11762         final PendingIntentRecord rec = (PendingIntentRecord)sender;
11763         final BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
11764         synchronized (stats) {
11765             mBatteryStatsService.enforceCallingPermission();
11766             int MY_UID = Binder.getCallingUid();
11767             final int uid;
11768             if (sender == null) {
11769                 uid = sourceUid;
11770             } else {
11771                 uid = rec.uid == MY_UID ? Process.SYSTEM_UID : rec.uid;
11772             }
11773             mBatteryStatsService.noteAlarmFinish(tag, sourceUid >= 0 ? sourceUid : uid);
11774         }
11775     }
11776
11777     public boolean killPids(int[] pids, String pReason, boolean secure) {
11778         if (Binder.getCallingUid() != Process.SYSTEM_UID) {
11779             throw new SecurityException("killPids only available to the system");
11780         }
11781         String reason = (pReason == null) ? "Unknown" : pReason;
11782         // XXX Note: don't acquire main activity lock here, because the window
11783         // manager calls in with its locks held.
11784
11785         boolean killed = false;
11786         synchronized (mPidsSelfLocked) {
11787             int[] types = new int[pids.length];
11788             int worstType = 0;
11789             for (int i=0; i<pids.length; i++) {
11790                 ProcessRecord proc = mPidsSelfLocked.get(pids[i]);
11791                 if (proc != null) {
11792                     int type = proc.setAdj;
11793                     types[i] = type;
11794                     if (type > worstType) {
11795                         worstType = type;
11796                     }
11797                 }
11798             }
11799
11800             // If the worst oom_adj is somewhere in the cached proc LRU range,
11801             // then constrain it so we will kill all cached procs.
11802             if (worstType < ProcessList.CACHED_APP_MAX_ADJ
11803                     && worstType > ProcessList.CACHED_APP_MIN_ADJ) {
11804                 worstType = ProcessList.CACHED_APP_MIN_ADJ;
11805             }
11806
11807             // If this is not a secure call, don't let it kill processes that
11808             // are important.
11809             if (!secure && worstType < ProcessList.SERVICE_ADJ) {
11810                 worstType = ProcessList.SERVICE_ADJ;
11811             }
11812
11813             Slog.w(TAG, "Killing processes " + reason + " at adjustment " + worstType);
11814             for (int i=0; i<pids.length; i++) {
11815                 ProcessRecord proc = mPidsSelfLocked.get(pids[i]);
11816                 if (proc == null) {
11817                     continue;
11818                 }
11819                 int adj = proc.setAdj;
11820                 if (adj >= worstType && !proc.killedByAm) {
11821                     proc.kill(reason, true);
11822                     killed = true;
11823                 }
11824             }
11825         }
11826         return killed;
11827     }
11828
11829     @Override
11830     public void killUid(int appId, int userId, String reason) {
11831         enforceCallingPermission(Manifest.permission.KILL_UID, "killUid");
11832         synchronized (this) {
11833             final long identity = Binder.clearCallingIdentity();
11834             try {
11835                 killPackageProcessesLocked(null, appId, userId,
11836                         ProcessList.PERSISTENT_PROC_ADJ, false, true, true, true,
11837                         reason != null ? reason : "kill uid");
11838             } finally {
11839                 Binder.restoreCallingIdentity(identity);
11840             }
11841         }
11842     }
11843
11844     @Override
11845     public boolean killProcessesBelowForeground(String reason) {
11846         if (Binder.getCallingUid() != Process.SYSTEM_UID) {
11847             throw new SecurityException("killProcessesBelowForeground() only available to system");
11848         }
11849
11850         return killProcessesBelowAdj(ProcessList.FOREGROUND_APP_ADJ, reason);
11851     }
11852
11853     private boolean killProcessesBelowAdj(int belowAdj, String reason) {
11854         if (Binder.getCallingUid() != Process.SYSTEM_UID) {
11855             throw new SecurityException("killProcessesBelowAdj() only available to system");
11856         }
11857
11858         boolean killed = false;
11859         synchronized (mPidsSelfLocked) {
11860             final int size = mPidsSelfLocked.size();
11861             for (int i = 0; i < size; i++) {
11862                 final int pid = mPidsSelfLocked.keyAt(i);
11863                 final ProcessRecord proc = mPidsSelfLocked.valueAt(i);
11864                 if (proc == null) continue;
11865
11866                 final int adj = proc.setAdj;
11867                 if (adj > belowAdj && !proc.killedByAm) {
11868                     proc.kill(reason, true);
11869                     killed = true;
11870                 }
11871             }
11872         }
11873         return killed;
11874     }
11875
11876     @Override
11877     public void hang(final IBinder who, boolean allowRestart) {
11878         if (checkCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER)
11879                 != PackageManager.PERMISSION_GRANTED) {
11880             throw new SecurityException("Requires permission "
11881                     + android.Manifest.permission.SET_ACTIVITY_WATCHER);
11882         }
11883
11884         final IBinder.DeathRecipient death = new DeathRecipient() {
11885             @Override
11886             public void binderDied() {
11887                 synchronized (this) {
11888                     notifyAll();
11889                 }
11890             }
11891         };
11892
11893         try {
11894             who.linkToDeath(death, 0);
11895         } catch (RemoteException e) {
11896             Slog.w(TAG, "hang: given caller IBinder is already dead.");
11897             return;
11898         }
11899
11900         synchronized (this) {
11901             Watchdog.getInstance().setAllowRestart(allowRestart);
11902             Slog.i(TAG, "Hanging system process at request of pid " + Binder.getCallingPid());
11903             synchronized (death) {
11904                 while (who.isBinderAlive()) {
11905                     try {
11906                         death.wait();
11907                     } catch (InterruptedException e) {
11908                     }
11909                 }
11910             }
11911             Watchdog.getInstance().setAllowRestart(true);
11912         }
11913     }
11914
11915     @Override
11916     public void restart() {
11917         if (checkCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER)
11918                 != PackageManager.PERMISSION_GRANTED) {
11919             throw new SecurityException("Requires permission "
11920                     + android.Manifest.permission.SET_ACTIVITY_WATCHER);
11921         }
11922
11923         Log.i(TAG, "Sending shutdown broadcast...");
11924
11925         BroadcastReceiver br = new BroadcastReceiver() {
11926             @Override public void onReceive(Context context, Intent intent) {
11927                 // Now the broadcast is done, finish up the low-level shutdown.
11928                 Log.i(TAG, "Shutting down activity manager...");
11929                 shutdown(10000);
11930                 Log.i(TAG, "Shutdown complete, restarting!");
11931                 Process.killProcess(Process.myPid());
11932                 System.exit(10);
11933             }
11934         };
11935
11936         // First send the high-level shut down broadcast.
11937         Intent intent = new Intent(Intent.ACTION_SHUTDOWN);
11938         intent.addFlags(Intent.FLAG_RECEIVER_FOREGROUND);
11939         intent.putExtra(Intent.EXTRA_SHUTDOWN_USERSPACE_ONLY, true);
11940         /* For now we are not doing a clean shutdown, because things seem to get unhappy.
11941         mContext.sendOrderedBroadcastAsUser(intent,
11942                 UserHandle.ALL, null, br, mHandler, 0, null, null);
11943         */
11944         br.onReceive(mContext, intent);
11945     }
11946
11947     private long getLowRamTimeSinceIdle(long now) {
11948         return mLowRamTimeSinceLastIdle + (mLowRamStartTime > 0 ? (now-mLowRamStartTime) : 0);
11949     }
11950
11951     @Override
11952     public void performIdleMaintenance() {
11953         if (checkCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER)
11954                 != PackageManager.PERMISSION_GRANTED) {
11955             throw new SecurityException("Requires permission "
11956                     + android.Manifest.permission.SET_ACTIVITY_WATCHER);
11957         }
11958
11959         synchronized (this) {
11960             final long now = SystemClock.uptimeMillis();
11961             final long timeSinceLastIdle = now - mLastIdleTime;
11962             final long lowRamSinceLastIdle = getLowRamTimeSinceIdle(now);
11963             mLastIdleTime = now;
11964             mLowRamTimeSinceLastIdle = 0;
11965             if (mLowRamStartTime != 0) {
11966                 mLowRamStartTime = now;
11967             }
11968
11969             StringBuilder sb = new StringBuilder(128);
11970             sb.append("Idle maintenance over ");
11971             TimeUtils.formatDuration(timeSinceLastIdle, sb);
11972             sb.append(" low RAM for ");
11973             TimeUtils.formatDuration(lowRamSinceLastIdle, sb);
11974             Slog.i(TAG, sb.toString());
11975
11976             // If at least 1/3 of our time since the last idle period has been spent
11977             // with RAM low, then we want to kill processes.
11978             boolean doKilling = lowRamSinceLastIdle > (timeSinceLastIdle/3);
11979
11980             for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) {
11981                 ProcessRecord proc = mLruProcesses.get(i);
11982                 if (proc.notCachedSinceIdle) {
11983                     if (proc.setProcState != ActivityManager.PROCESS_STATE_TOP_SLEEPING
11984                             && proc.setProcState >= ActivityManager.PROCESS_STATE_FOREGROUND_SERVICE
11985                             && proc.setProcState <= ActivityManager.PROCESS_STATE_SERVICE) {
11986                         if (doKilling && proc.initialIdlePss != 0
11987                                 && proc.lastPss > ((proc.initialIdlePss*3)/2)) {
11988                             sb = new StringBuilder(128);
11989                             sb.append("Kill");
11990                             sb.append(proc.processName);
11991                             sb.append(" in idle maint: pss=");
11992                             sb.append(proc.lastPss);
11993                             sb.append(", initialPss=");
11994                             sb.append(proc.initialIdlePss);
11995                             sb.append(", period=");
11996                             TimeUtils.formatDuration(timeSinceLastIdle, sb);
11997                             sb.append(", lowRamPeriod=");
11998                             TimeUtils.formatDuration(lowRamSinceLastIdle, sb);
11999                             Slog.wtfQuiet(TAG, sb.toString());
12000                             proc.kill("idle maint (pss " + proc.lastPss
12001                                     + " from " + proc.initialIdlePss + ")", true);
12002                         }
12003                     }
12004                 } else if (proc.setProcState < ActivityManager.PROCESS_STATE_HOME) {
12005                     proc.notCachedSinceIdle = true;
12006                     proc.initialIdlePss = 0;
12007                     proc.nextPssTime = ProcessList.computeNextPssTime(proc.curProcState, true,
12008                             mTestPssMode, isSleeping(), now);
12009                 }
12010             }
12011
12012             mHandler.removeMessages(REQUEST_ALL_PSS_MSG);
12013             mHandler.sendEmptyMessageDelayed(REQUEST_ALL_PSS_MSG, 2*60*1000);
12014         }
12015     }
12016
12017     private void retrieveSettings() {
12018         final ContentResolver resolver = mContext.getContentResolver();
12019         final boolean freeformWindowManagement =
12020                 mContext.getPackageManager().hasSystemFeature(FEATURE_FREEFORM_WINDOW_MANAGEMENT);
12021
12022         final String debugApp = Settings.Global.getString(resolver, DEBUG_APP);
12023         final String fsScreenshots = Settings.Secure.getString(resolver,
12024                 "overview_fullscreen_thumbnails");
12025         final boolean waitForDebugger = Settings.Global.getInt(resolver, WAIT_FOR_DEBUGGER, 0) != 0;
12026         final boolean alwaysFinishActivities =
12027                 Settings.Global.getInt(resolver, ALWAYS_FINISH_ACTIVITIES, 0) != 0;
12028         final boolean takeFullscreenScreenshots = fsScreenshots != null &&
12029                 Integer.parseInt(fsScreenshots) != 0;
12030         final boolean forceRtl = Settings.Global.getInt(resolver, DEVELOPMENT_FORCE_RTL, 0) != 0;
12031         final int defaultForceResizable = Build.IS_DEBUGGABLE ? 1 : 0;
12032         final boolean forceResizable = Settings.Global.getInt(
12033                 resolver, DEVELOPMENT_FORCE_RESIZABLE_ACTIVITIES, defaultForceResizable) != 0;
12034         // Transfer any global setting for forcing RTL layout, into a System Property
12035         SystemProperties.set(DEVELOPMENT_FORCE_RTL, forceRtl ? "1":"0");
12036
12037         final Configuration configuration = new Configuration();
12038         Settings.System.getConfiguration(resolver, configuration);
12039         if (forceRtl) {
12040             // This will take care of setting the correct layout direction flags
12041             configuration.setLayoutDirection(configuration.locale);
12042         }
12043
12044         synchronized (this) {
12045             mDebugApp = mOrigDebugApp = debugApp;
12046             mWaitForDebugger = mOrigWaitForDebugger = waitForDebugger;
12047             mAlwaysFinishActivities = alwaysFinishActivities;
12048             mForceResizableActivities = forceResizable;
12049             mSupportsFreeformWindowManagement = freeformWindowManagement || forceResizable;
12050             mTakeFullscreenScreenshots = takeFullscreenScreenshots;
12051             // This happens before any activities are started, so we can
12052             // change mConfiguration in-place.
12053             updateConfigurationLocked(configuration, null, true);
12054             if (DEBUG_CONFIGURATION) Slog.v(TAG_CONFIGURATION,
12055                     "Initial config: " + mConfiguration);
12056         }
12057     }
12058
12059     /** Loads resources after the current configuration has been set. */
12060     private void loadResourcesOnSystemReady() {
12061         final Resources res = mContext.getResources();
12062         mHasRecents = res.getBoolean(com.android.internal.R.bool.config_hasRecents);
12063         mThumbnailWidth = res.getDimensionPixelSize(com.android.internal.R.dimen.thumbnail_width);
12064         mThumbnailHeight = res.getDimensionPixelSize(com.android.internal.R.dimen.thumbnail_height);
12065     }
12066
12067     public boolean testIsSystemReady() {
12068         // no need to synchronize(this) just to read & return the value
12069         return mSystemReady;
12070     }
12071
12072     private static File getCalledPreBootReceiversFile() {
12073         File dataDir = Environment.getDataDirectory();
12074         File systemDir = new File(dataDir, "system");
12075         File fname = new File(systemDir, CALLED_PRE_BOOTS_FILENAME);
12076         return fname;
12077     }
12078
12079     private static ArrayList<ComponentName> readLastDonePreBootReceivers() {
12080         ArrayList<ComponentName> lastDoneReceivers = new ArrayList<ComponentName>();
12081         File file = getCalledPreBootReceiversFile();
12082         FileInputStream fis = null;
12083         try {
12084             fis = new FileInputStream(file);
12085             DataInputStream dis = new DataInputStream(new BufferedInputStream(fis, 2048));
12086             int fvers = dis.readInt();
12087             if (fvers == LAST_PREBOOT_DELIVERED_FILE_VERSION) {
12088                 String vers = dis.readUTF();
12089                 String codename = dis.readUTF();
12090                 String build = dis.readUTF();
12091                 if (android.os.Build.VERSION.RELEASE.equals(vers)
12092                         && android.os.Build.VERSION.CODENAME.equals(codename)
12093                         && android.os.Build.VERSION.INCREMENTAL.equals(build)) {
12094                     int num = dis.readInt();
12095                     while (num > 0) {
12096                         num--;
12097                         String pkg = dis.readUTF();
12098                         String cls = dis.readUTF();
12099                         lastDoneReceivers.add(new ComponentName(pkg, cls));
12100                     }
12101                 }
12102             }
12103         } catch (FileNotFoundException e) {
12104         } catch (IOException e) {
12105             Slog.w(TAG, "Failure reading last done pre-boot receivers", e);
12106         } finally {
12107             if (fis != null) {
12108                 try {
12109                     fis.close();
12110                 } catch (IOException e) {
12111                 }
12112             }
12113         }
12114         return lastDoneReceivers;
12115     }
12116
12117     private static void writeLastDonePreBootReceivers(ArrayList<ComponentName> list) {
12118         File file = getCalledPreBootReceiversFile();
12119         FileOutputStream fos = null;
12120         DataOutputStream dos = null;
12121         try {
12122             fos = new FileOutputStream(file);
12123             dos = new DataOutputStream(new BufferedOutputStream(fos, 2048));
12124             dos.writeInt(LAST_PREBOOT_DELIVERED_FILE_VERSION);
12125             dos.writeUTF(android.os.Build.VERSION.RELEASE);
12126             dos.writeUTF(android.os.Build.VERSION.CODENAME);
12127             dos.writeUTF(android.os.Build.VERSION.INCREMENTAL);
12128             dos.writeInt(list.size());
12129             for (int i=0; i<list.size(); i++) {
12130                 dos.writeUTF(list.get(i).getPackageName());
12131                 dos.writeUTF(list.get(i).getClassName());
12132             }
12133         } catch (IOException e) {
12134             Slog.w(TAG, "Failure writing last done pre-boot receivers", e);
12135             file.delete();
12136         } finally {
12137             FileUtils.sync(fos);
12138             if (dos != null) {
12139                 try {
12140                     dos.close();
12141                 } catch (IOException e) {
12142                     // TODO Auto-generated catch block
12143                     e.printStackTrace();
12144                 }
12145             }
12146         }
12147     }
12148
12149     final class PreBootContinuation extends IIntentReceiver.Stub {
12150         final Intent intent;
12151         final Runnable onFinishCallback;
12152         final ArrayList<ComponentName> doneReceivers;
12153         final List<ResolveInfo> ris;
12154         final int[] users;
12155         int lastRi = -1;
12156         int curRi = 0;
12157         int curUser = 0;
12158
12159         PreBootContinuation(Intent _intent, Runnable _onFinishCallback,
12160                 ArrayList<ComponentName> _doneReceivers, List<ResolveInfo> _ris, int[] _users) {
12161             intent = _intent;
12162             onFinishCallback = _onFinishCallback;
12163             doneReceivers = _doneReceivers;
12164             ris = _ris;
12165             users = _users;
12166         }
12167
12168         void go() {
12169             if (lastRi != curRi) {
12170                 ActivityInfo ai = ris.get(curRi).activityInfo;
12171                 ComponentName comp = new ComponentName(ai.packageName, ai.name);
12172                 intent.setComponent(comp);
12173                 doneReceivers.add(comp);
12174                 lastRi = curRi;
12175                 CharSequence label = ai.loadLabel(mContext.getPackageManager());
12176                 showBootMessage(mContext.getString(R.string.android_preparing_apk, label), false);
12177             }
12178             Slog.i(TAG, "Pre-boot of " + intent.getComponent().toShortString()
12179                     + " for user " + users[curUser]);
12180             EventLogTags.writeAmPreBoot(users[curUser], intent.getComponent().getPackageName());
12181             broadcastIntentLocked(null, null, intent, null, this,
12182                     0, null, null, null, AppOpsManager.OP_NONE,
12183                     null, true, false, MY_PID, Process.SYSTEM_UID, users[curUser]);
12184         }
12185
12186         public void performReceive(Intent intent, int resultCode,
12187                 String data, Bundle extras, boolean ordered,
12188                 boolean sticky, int sendingUser) {
12189             curUser++;
12190             if (curUser >= users.length) {
12191                 curUser = 0;
12192                 curRi++;
12193                 if (curRi >= ris.size()) {
12194                     // All done sending broadcasts!
12195                     if (onFinishCallback != null) {
12196                         // The raw IIntentReceiver interface is called
12197                         // with the AM lock held, so redispatch to
12198                         // execute our code without the lock.
12199                         mHandler.post(onFinishCallback);
12200                     }
12201                     return;
12202                 }
12203             }
12204             go();
12205         }
12206     }
12207
12208     private boolean deliverPreBootCompleted(final Runnable onFinishCallback,
12209             ArrayList<ComponentName> doneReceivers) {
12210         Intent intent = new Intent(Intent.ACTION_PRE_BOOT_COMPLETED);
12211         List<ResolveInfo> ris = null;
12212         try {
12213             ris = AppGlobals.getPackageManager().queryIntentReceivers(
12214                     intent, null, 0, UserHandle.USER_SYSTEM);
12215         } catch (RemoteException e) {
12216         }
12217         if (ris == null) {
12218             return false;
12219         }
12220         for (int i=ris.size()-1; i>=0; i--) {
12221             if ((ris.get(i).activityInfo.applicationInfo.flags
12222                     &ApplicationInfo.FLAG_SYSTEM) == 0) {
12223                 ris.remove(i);
12224             }
12225         }
12226         intent.addFlags(Intent.FLAG_RECEIVER_BOOT_UPGRADE);
12227
12228         ArrayList<ComponentName> lastDoneReceivers = readLastDonePreBootReceivers();
12229         for (int i=0; i<ris.size(); i++) {
12230             ActivityInfo ai = ris.get(i).activityInfo;
12231             ComponentName comp = new ComponentName(ai.packageName, ai.name);
12232             if (lastDoneReceivers.contains(comp)) {
12233                 // We already did the pre boot receiver for this app with the current
12234                 // platform version, so don't do it again...
12235                 ris.remove(i);
12236                 i--;
12237                 // ...however, do keep it as one that has been done, so we don't
12238                 // forget about it when rewriting the file of last done receivers.
12239                 doneReceivers.add(comp);
12240             }
12241         }
12242
12243         if (ris.size() <= 0) {
12244             return false;
12245         }
12246
12247         // TODO: can we still do this with per user encryption?
12248         final int[] users = mUserController.getUsers();
12249         if (users.length <= 0) {
12250             return false;
12251         }
12252
12253         PreBootContinuation cont = new PreBootContinuation(intent, onFinishCallback, doneReceivers,
12254                 ris, users);
12255         cont.go();
12256         return true;
12257     }
12258
12259     public void systemReady(final Runnable goingCallback) {
12260         synchronized(this) {
12261             if (mSystemReady) {
12262                 // If we're done calling all the receivers, run the next "boot phase" passed in
12263                 // by the SystemServer
12264                 if (goingCallback != null) {
12265                     goingCallback.run();
12266                 }
12267                 return;
12268             }
12269
12270             mLocalDeviceIdleController
12271                     = LocalServices.getService(DeviceIdleController.LocalService.class);
12272
12273             // Make sure we have the current profile info, since it is needed for
12274             // security checks.
12275             mUserController.updateCurrentProfileIdsLocked();
12276
12277             mRecentTasks.clear();
12278             mRecentTasks.addAll(mTaskPersister.restoreTasksLocked(mUserController.getUserIds()));
12279             mRecentTasks.cleanupLocked(UserHandle.USER_ALL);
12280             mTaskPersister.startPersisting();
12281
12282             // Check to see if there are any update receivers to run.
12283             if (!mDidUpdate) {
12284                 if (mWaitingUpdate) {
12285                     return;
12286                 }
12287                 final ArrayList<ComponentName> doneReceivers = new ArrayList<ComponentName>();
12288                 mWaitingUpdate = deliverPreBootCompleted(new Runnable() {
12289                     public void run() {
12290                         synchronized (ActivityManagerService.this) {
12291                             mDidUpdate = true;
12292                         }
12293                         showBootMessage(mContext.getText(
12294                                 R.string.android_upgrading_complete),
12295                                 false);
12296                         writeLastDonePreBootReceivers(doneReceivers);
12297                         systemReady(goingCallback);
12298                     }
12299                 }, doneReceivers);
12300
12301                 if (mWaitingUpdate) {
12302                     return;
12303                 }
12304                 mDidUpdate = true;
12305             }
12306
12307             mAppOpsService.systemReady();
12308             mSystemReady = true;
12309         }
12310
12311         ArrayList<ProcessRecord> procsToKill = null;
12312         synchronized(mPidsSelfLocked) {
12313             for (int i=mPidsSelfLocked.size()-1; i>=0; i--) {
12314                 ProcessRecord proc = mPidsSelfLocked.valueAt(i);
12315                 if (!isAllowedWhileBooting(proc.info)){
12316                     if (procsToKill == null) {
12317                         procsToKill = new ArrayList<ProcessRecord>();
12318                     }
12319                     procsToKill.add(proc);
12320                 }
12321             }
12322         }
12323
12324         synchronized(this) {
12325             if (procsToKill != null) {
12326                 for (int i=procsToKill.size()-1; i>=0; i--) {
12327                     ProcessRecord proc = procsToKill.get(i);
12328                     Slog.i(TAG, "Removing system update proc: " + proc);
12329                     removeProcessLocked(proc, true, false, "system update done");
12330                 }
12331             }
12332
12333             // Now that we have cleaned up any update processes, we
12334             // are ready to start launching real processes and know that
12335             // we won't trample on them any more.
12336             mProcessesReady = true;
12337         }
12338
12339         Slog.i(TAG, "System now ready");
12340         EventLog.writeEvent(EventLogTags.BOOT_PROGRESS_AMS_READY,
12341             SystemClock.uptimeMillis());
12342
12343         synchronized(this) {
12344             // Make sure we have no pre-ready processes sitting around.
12345
12346             if (mFactoryTest == FactoryTest.FACTORY_TEST_LOW_LEVEL) {
12347                 ResolveInfo ri = mContext.getPackageManager()
12348                         .resolveActivity(new Intent(Intent.ACTION_FACTORY_TEST),
12349                                 STOCK_PM_FLAGS);
12350                 CharSequence errorMsg = null;
12351                 if (ri != null) {
12352                     ActivityInfo ai = ri.activityInfo;
12353                     ApplicationInfo app = ai.applicationInfo;
12354                     if ((app.flags&ApplicationInfo.FLAG_SYSTEM) != 0) {
12355                         mTopAction = Intent.ACTION_FACTORY_TEST;
12356                         mTopData = null;
12357                         mTopComponent = new ComponentName(app.packageName,
12358                                 ai.name);
12359                     } else {
12360                         errorMsg = mContext.getResources().getText(
12361                                 com.android.internal.R.string.factorytest_not_system);
12362                     }
12363                 } else {
12364                     errorMsg = mContext.getResources().getText(
12365                             com.android.internal.R.string.factorytest_no_action);
12366                 }
12367                 if (errorMsg != null) {
12368                     mTopAction = null;
12369                     mTopData = null;
12370                     mTopComponent = null;
12371                     Message msg = Message.obtain();
12372                     msg.what = SHOW_FACTORY_ERROR_UI_MSG;
12373                     msg.getData().putCharSequence("msg", errorMsg);
12374                     mUiHandler.sendMessage(msg);
12375                 }
12376             }
12377         }
12378
12379         retrieveSettings();
12380         loadResourcesOnSystemReady();
12381         final int currentUserId;
12382         synchronized (this) {
12383             currentUserId = mUserController.getCurrentUserIdLocked();
12384             readGrantedUriPermissionsLocked();
12385         }
12386
12387         if (goingCallback != null) goingCallback.run();
12388
12389
12390         mBatteryStatsService.noteEvent(BatteryStats.HistoryItem.EVENT_USER_RUNNING_START,
12391                 Integer.toString(currentUserId), currentUserId);
12392         mBatteryStatsService.noteEvent(BatteryStats.HistoryItem.EVENT_USER_FOREGROUND_START,
12393                 Integer.toString(currentUserId), currentUserId);
12394         mSystemServiceManager.startUser(currentUserId);
12395
12396         synchronized (this) {
12397             if (mFactoryTest != FactoryTest.FACTORY_TEST_LOW_LEVEL) {
12398                 try {
12399                     List apps = AppGlobals.getPackageManager().
12400                         getPersistentApplications(STOCK_PM_FLAGS);
12401                     if (apps != null) {
12402                         int N = apps.size();
12403                         int i;
12404                         for (i=0; i<N; i++) {
12405                             ApplicationInfo info
12406                                 = (ApplicationInfo)apps.get(i);
12407                             if (info != null &&
12408                                     !info.packageName.equals("android")) {
12409                                 addAppLocked(info, false, null /* ABI override */);
12410                             }
12411                         }
12412                     }
12413                 } catch (RemoteException ex) {
12414                     // pm is in same process, this will never happen.
12415                 }
12416             }
12417
12418             // Start up initial activity.
12419             mBooting = true;
12420             // Enable home activity for system user, so that the system can always boot
12421             if (UserManager.isSplitSystemUser()) {
12422                 ComponentName cName = new ComponentName(mContext, SystemUserHomeActivity.class);
12423                 try {
12424                     AppGlobals.getPackageManager().setComponentEnabledSetting(cName,
12425                             PackageManager.COMPONENT_ENABLED_STATE_ENABLED, 0,
12426                             UserHandle.USER_SYSTEM);
12427                 } catch (RemoteException e) {
12428                     e.rethrowAsRuntimeException();
12429                 }
12430             }
12431             startHomeActivityLocked(currentUserId, "systemReady");
12432
12433             try {
12434                 if (AppGlobals.getPackageManager().hasSystemUidErrors()) {
12435                     Slog.e(TAG, "UIDs on the system are inconsistent, you need to wipe your"
12436                             + " data partition or your device will be unstable.");
12437                     mUiHandler.obtainMessage(SHOW_UID_ERROR_UI_MSG).sendToTarget();
12438                 }
12439             } catch (RemoteException e) {
12440             }
12441
12442             if (!Build.isBuildConsistent()) {
12443                 Slog.e(TAG, "Build fingerprint is not consistent, warning user");
12444                 mUiHandler.obtainMessage(SHOW_FINGERPRINT_ERROR_UI_MSG).sendToTarget();
12445             }
12446
12447             long ident = Binder.clearCallingIdentity();
12448             try {
12449                 Intent intent = new Intent(Intent.ACTION_USER_STARTED);
12450                 intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY
12451                         | Intent.FLAG_RECEIVER_FOREGROUND);
12452                 intent.putExtra(Intent.EXTRA_USER_HANDLE, currentUserId);
12453                 broadcastIntentLocked(null, null, intent,
12454                         null, null, 0, null, null, null, AppOpsManager.OP_NONE,
12455                         null, false, false, MY_PID, Process.SYSTEM_UID,
12456                         currentUserId);
12457                 intent = new Intent(Intent.ACTION_USER_STARTING);
12458                 intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY);
12459                 intent.putExtra(Intent.EXTRA_USER_HANDLE, currentUserId);
12460                 broadcastIntentLocked(null, null, intent,
12461                         null, new IIntentReceiver.Stub() {
12462                             @Override
12463                             public void performReceive(Intent intent, int resultCode, String data,
12464                                     Bundle extras, boolean ordered, boolean sticky, int sendingUser)
12465                                     throws RemoteException {
12466                             }
12467                         }, 0, null, null,
12468                         new String[] {INTERACT_ACROSS_USERS}, AppOpsManager.OP_NONE,
12469                         null, true, false, MY_PID, Process.SYSTEM_UID, UserHandle.USER_ALL);
12470             } catch (Throwable t) {
12471                 Slog.wtf(TAG, "Failed sending first user broadcasts", t);
12472             } finally {
12473                 Binder.restoreCallingIdentity(ident);
12474             }
12475             mStackSupervisor.resumeTopActivitiesLocked();
12476             mUserController.sendUserSwitchBroadcastsLocked(-1, currentUserId);
12477         }
12478     }
12479
12480     private boolean makeAppCrashingLocked(ProcessRecord app,
12481             String shortMsg, String longMsg, String stackTrace) {
12482         app.crashing = true;
12483         app.crashingReport = generateProcessError(app,
12484                 ActivityManager.ProcessErrorStateInfo.CRASHED, null, shortMsg, longMsg, stackTrace);
12485         startAppProblemLocked(app);
12486         app.stopFreezingAllLocked();
12487         return handleAppCrashLocked(app, "force-crash" /*reason*/, shortMsg, longMsg, stackTrace);
12488     }
12489
12490     private void makeAppNotRespondingLocked(ProcessRecord app,
12491             String activity, String shortMsg, String longMsg) {
12492         app.notResponding = true;
12493         app.notRespondingReport = generateProcessError(app,
12494                 ActivityManager.ProcessErrorStateInfo.NOT_RESPONDING,
12495                 activity, shortMsg, longMsg, null);
12496         startAppProblemLocked(app);
12497         app.stopFreezingAllLocked();
12498     }
12499
12500     /**
12501      * Generate a process error record, suitable for attachment to a ProcessRecord.
12502      *
12503      * @param app The ProcessRecord in which the error occurred.
12504      * @param condition Crashing, Application Not Responding, etc.  Values are defined in
12505      *                      ActivityManager.AppErrorStateInfo
12506      * @param activity The activity associated with the crash, if known.
12507      * @param shortMsg Short message describing the crash.
12508      * @param longMsg Long message describing the crash.
12509      * @param stackTrace Full crash stack trace, may be null.
12510      *
12511      * @return Returns a fully-formed AppErrorStateInfo record.
12512      */
12513     private ActivityManager.ProcessErrorStateInfo generateProcessError(ProcessRecord app,
12514             int condition, String activity, String shortMsg, String longMsg, String stackTrace) {
12515         ActivityManager.ProcessErrorStateInfo report = new ActivityManager.ProcessErrorStateInfo();
12516
12517         report.condition = condition;
12518         report.processName = app.processName;
12519         report.pid = app.pid;
12520         report.uid = app.info.uid;
12521         report.tag = activity;
12522         report.shortMsg = shortMsg;
12523         report.longMsg = longMsg;
12524         report.stackTrace = stackTrace;
12525
12526         return report;
12527     }
12528
12529     void killAppAtUsersRequest(ProcessRecord app, Dialog fromDialog) {
12530         synchronized (this) {
12531             app.crashing = false;
12532             app.crashingReport = null;
12533             app.notResponding = false;
12534             app.notRespondingReport = null;
12535             if (app.anrDialog == fromDialog) {
12536                 app.anrDialog = null;
12537             }
12538             if (app.waitDialog == fromDialog) {
12539                 app.waitDialog = null;
12540             }
12541             if (app.pid > 0 && app.pid != MY_PID) {
12542                 handleAppCrashLocked(app, "user-terminated" /*reason*/,
12543                         null /*shortMsg*/, null /*longMsg*/, null /*stackTrace*/);
12544                 app.kill("user request after error", true);
12545             }
12546         }
12547     }
12548
12549     private boolean handleAppCrashLocked(ProcessRecord app, String reason,
12550             String shortMsg, String longMsg, String stackTrace) {
12551         long now = SystemClock.uptimeMillis();
12552
12553         Long crashTime;
12554         if (!app.isolated) {
12555             crashTime = mProcessCrashTimes.get(app.info.processName, app.uid);
12556         } else {
12557             crashTime = null;
12558         }
12559         if (crashTime != null && now < crashTime+ProcessList.MIN_CRASH_INTERVAL) {
12560             // This process loses!
12561             Slog.w(TAG, "Process " + app.info.processName
12562                     + " has crashed too many times: killing!");
12563             EventLog.writeEvent(EventLogTags.AM_PROCESS_CRASHED_TOO_MUCH,
12564                     app.userId, app.info.processName, app.uid);
12565             mStackSupervisor.handleAppCrashLocked(app);
12566             if (!app.persistent) {
12567                 // We don't want to start this process again until the user
12568                 // explicitly does so...  but for persistent process, we really
12569                 // need to keep it running.  If a persistent process is actually
12570                 // repeatedly crashing, then badness for everyone.
12571                 EventLog.writeEvent(EventLogTags.AM_PROC_BAD, app.userId, app.uid,
12572                         app.info.processName);
12573                 if (!app.isolated) {
12574                     // XXX We don't have a way to mark isolated processes
12575                     // as bad, since they don't have a peristent identity.
12576                     mBadProcesses.put(app.info.processName, app.uid,
12577                             new BadProcessInfo(now, shortMsg, longMsg, stackTrace));
12578                     mProcessCrashTimes.remove(app.info.processName, app.uid);
12579                 }
12580                 app.bad = true;
12581                 app.removed = true;
12582                 // Don't let services in this process be restarted and potentially
12583                 // annoy the user repeatedly.  Unless it is persistent, since those
12584                 // processes run critical code.
12585                 removeProcessLocked(app, false, false, "crash");
12586                 mStackSupervisor.resumeTopActivitiesLocked();
12587                 return false;
12588             }
12589             mStackSupervisor.resumeTopActivitiesLocked();
12590         } else {
12591             mStackSupervisor.finishTopRunningActivityLocked(app, reason);
12592         }
12593
12594         // Bump up the crash count of any services currently running in the proc.
12595         for (int i=app.services.size()-1; i>=0; i--) {
12596             // Any services running in the application need to be placed
12597             // back in the pending list.
12598             ServiceRecord sr = app.services.valueAt(i);
12599             sr.crashCount++;
12600         }
12601
12602         // If the crashing process is what we consider to be the "home process" and it has been
12603         // replaced by a third-party app, clear the package preferred activities from packages
12604         // with a home activity running in the process to prevent a repeatedly crashing app
12605         // from blocking the user to manually clear the list.
12606         final ArrayList<ActivityRecord> activities = app.activities;
12607         if (app == mHomeProcess && activities.size() > 0
12608                     && (mHomeProcess.info.flags & ApplicationInfo.FLAG_SYSTEM) == 0) {
12609             for (int activityNdx = activities.size() - 1; activityNdx >= 0; --activityNdx) {
12610                 final ActivityRecord r = activities.get(activityNdx);
12611                 if (r.isHomeActivity()) {
12612                     Log.i(TAG, "Clearing package preferred activities from " + r.packageName);
12613                     try {
12614                         ActivityThread.getPackageManager()
12615                                 .clearPackagePreferredActivities(r.packageName);
12616                     } catch (RemoteException c) {
12617                         // pm is in same process, this will never happen.
12618                     }
12619                 }
12620             }
12621         }
12622
12623         if (!app.isolated) {
12624             // XXX Can't keep track of crash times for isolated processes,
12625             // because they don't have a perisistent identity.
12626             mProcessCrashTimes.put(app.info.processName, app.uid, now);
12627         }
12628
12629         if (app.crashHandler != null) mHandler.post(app.crashHandler);
12630         return true;
12631     }
12632
12633     void startAppProblemLocked(ProcessRecord app) {
12634         // If this app is not running under the current user, then we
12635         // can't give it a report button because that would require
12636         // launching the report UI under a different user.
12637         app.errorReportReceiver = null;
12638
12639         for (int userId : mUserController.getCurrentProfileIdsLocked()) {
12640             if (app.userId == userId) {
12641                 app.errorReportReceiver = ApplicationErrorReport.getErrorReportReceiver(
12642                         mContext, app.info.packageName, app.info.flags);
12643             }
12644         }
12645         skipCurrentReceiverLocked(app);
12646     }
12647
12648     void skipCurrentReceiverLocked(ProcessRecord app) {
12649         for (BroadcastQueue queue : mBroadcastQueues) {
12650             queue.skipCurrentReceiverLocked(app);
12651         }
12652     }
12653
12654     /**
12655      * Used by {@link com.android.internal.os.RuntimeInit} to report when an application crashes.
12656      * The application process will exit immediately after this call returns.
12657      * @param app object of the crashing app, null for the system server
12658      * @param crashInfo describing the exception
12659      */
12660     public void handleApplicationCrash(IBinder app, ApplicationErrorReport.CrashInfo crashInfo) {
12661         ProcessRecord r = findAppProcess(app, "Crash");
12662         final String processName = app == null ? "system_server"
12663                 : (r == null ? "unknown" : r.processName);
12664
12665         handleApplicationCrashInner("crash", r, processName, crashInfo);
12666     }
12667
12668     /* Native crash reporting uses this inner version because it needs to be somewhat
12669      * decoupled from the AM-managed cleanup lifecycle
12670      */
12671     void handleApplicationCrashInner(String eventType, ProcessRecord r, String processName,
12672             ApplicationErrorReport.CrashInfo crashInfo) {
12673         EventLog.writeEvent(EventLogTags.AM_CRASH, Binder.getCallingPid(),
12674                 UserHandle.getUserId(Binder.getCallingUid()), processName,
12675                 r == null ? -1 : r.info.flags,
12676                 crashInfo.exceptionClassName,
12677                 crashInfo.exceptionMessage,
12678                 crashInfo.throwFileName,
12679                 crashInfo.throwLineNumber);
12680
12681         addErrorToDropBox(eventType, r, processName, null, null, null, null, null, crashInfo);
12682
12683         crashApplication(r, crashInfo);
12684     }
12685
12686     public void handleApplicationStrictModeViolation(
12687             IBinder app,
12688             int violationMask,
12689             StrictMode.ViolationInfo info) {
12690         ProcessRecord r = findAppProcess(app, "StrictMode");
12691         if (r == null) {
12692             return;
12693         }
12694
12695         if ((violationMask & StrictMode.PENALTY_DROPBOX) != 0) {
12696             Integer stackFingerprint = info.hashCode();
12697             boolean logIt = true;
12698             synchronized (mAlreadyLoggedViolatedStacks) {
12699                 if (mAlreadyLoggedViolatedStacks.contains(stackFingerprint)) {
12700                     logIt = false;
12701                     // TODO: sub-sample into EventLog for these, with
12702                     // the info.durationMillis?  Then we'd get
12703                     // the relative pain numbers, without logging all
12704                     // the stack traces repeatedly.  We'd want to do
12705                     // likewise in the client code, which also does
12706                     // dup suppression, before the Binder call.
12707                 } else {
12708                     if (mAlreadyLoggedViolatedStacks.size() >= MAX_DUP_SUPPRESSED_STACKS) {
12709                         mAlreadyLoggedViolatedStacks.clear();
12710                     }
12711                     mAlreadyLoggedViolatedStacks.add(stackFingerprint);
12712                 }
12713             }
12714             if (logIt) {
12715                 logStrictModeViolationToDropBox(r, info);
12716             }
12717         }
12718
12719         if ((violationMask & StrictMode.PENALTY_DIALOG) != 0) {
12720             AppErrorResult result = new AppErrorResult();
12721             synchronized (this) {
12722                 final long origId = Binder.clearCallingIdentity();
12723
12724                 Message msg = Message.obtain();
12725                 msg.what = SHOW_STRICT_MODE_VIOLATION_UI_MSG;
12726                 HashMap<String, Object> data = new HashMap<String, Object>();
12727                 data.put("result", result);
12728                 data.put("app", r);
12729                 data.put("violationMask", violationMask);
12730                 data.put("info", info);
12731                 msg.obj = data;
12732                 mUiHandler.sendMessage(msg);
12733
12734                 Binder.restoreCallingIdentity(origId);
12735             }
12736             int res = result.get();
12737             Slog.w(TAG, "handleApplicationStrictModeViolation; res=" + res);
12738         }
12739     }
12740
12741     // Depending on the policy in effect, there could be a bunch of
12742     // these in quick succession so we try to batch these together to
12743     // minimize disk writes, number of dropbox entries, and maximize
12744     // compression, by having more fewer, larger records.
12745     private void logStrictModeViolationToDropBox(
12746             ProcessRecord process,
12747             StrictMode.ViolationInfo info) {
12748         if (info == null) {
12749             return;
12750         }
12751         final boolean isSystemApp = process == null ||
12752                 (process.info.flags & (ApplicationInfo.FLAG_SYSTEM |
12753                                        ApplicationInfo.FLAG_UPDATED_SYSTEM_APP)) != 0;
12754         final String processName = process == null ? "unknown" : process.processName;
12755         final String dropboxTag = isSystemApp ? "system_app_strictmode" : "data_app_strictmode";
12756         final DropBoxManager dbox = (DropBoxManager)
12757                 mContext.getSystemService(Context.DROPBOX_SERVICE);
12758
12759         // Exit early if the dropbox isn't configured to accept this report type.
12760         if (dbox == null || !dbox.isTagEnabled(dropboxTag)) return;
12761
12762         boolean bufferWasEmpty;
12763         boolean needsFlush;
12764         final StringBuilder sb = isSystemApp ? mStrictModeBuffer : new StringBuilder(1024);
12765         synchronized (sb) {
12766             bufferWasEmpty = sb.length() == 0;
12767             appendDropBoxProcessHeaders(process, processName, sb);
12768             sb.append("Build: ").append(Build.FINGERPRINT).append("\n");
12769             sb.append("System-App: ").append(isSystemApp).append("\n");
12770             sb.append("Uptime-Millis: ").append(info.violationUptimeMillis).append("\n");
12771             if (info.violationNumThisLoop != 0) {
12772                 sb.append("Loop-Violation-Number: ").append(info.violationNumThisLoop).append("\n");
12773             }
12774             if (info.numAnimationsRunning != 0) {
12775                 sb.append("Animations-Running: ").append(info.numAnimationsRunning).append("\n");
12776             }
12777             if (info.broadcastIntentAction != null) {
12778                 sb.append("Broadcast-Intent-Action: ").append(info.broadcastIntentAction).append("\n");
12779             }
12780             if (info.durationMillis != -1) {
12781                 sb.append("Duration-Millis: ").append(info.durationMillis).append("\n");
12782             }
12783             if (info.numInstances != -1) {
12784                 sb.append("Instance-Count: ").append(info.numInstances).append("\n");
12785             }
12786             if (info.tags != null) {
12787                 for (String tag : info.tags) {
12788                     sb.append("Span-Tag: ").append(tag).append("\n");
12789                 }
12790             }
12791             sb.append("\n");
12792             if (info.crashInfo != null && info.crashInfo.stackTrace != null) {
12793                 sb.append(info.crashInfo.stackTrace);
12794                 sb.append("\n");
12795             }
12796             if (info.message != null) {
12797                 sb.append(info.message);
12798                 sb.append("\n");
12799             }
12800
12801             // Only buffer up to ~64k.  Various logging bits truncate
12802             // things at 128k.
12803             needsFlush = (sb.length() > 64 * 1024);
12804         }
12805
12806         // Flush immediately if the buffer's grown too large, or this
12807         // is a non-system app.  Non-system apps are isolated with a
12808         // different tag & policy and not batched.
12809         //
12810         // Batching is useful during internal testing with
12811         // StrictMode settings turned up high.  Without batching,
12812         // thousands of separate files could be created on boot.
12813         if (!isSystemApp || needsFlush) {
12814             new Thread("Error dump: " + dropboxTag) {
12815                 @Override
12816                 public void run() {
12817                     String report;
12818                     synchronized (sb) {
12819                         report = sb.toString();
12820                         sb.delete(0, sb.length());
12821                         sb.trimToSize();
12822                     }
12823                     if (report.length() != 0) {
12824                         dbox.addText(dropboxTag, report);
12825                     }
12826                 }
12827             }.start();
12828             return;
12829         }
12830
12831         // System app batching:
12832         if (!bufferWasEmpty) {
12833             // An existing dropbox-writing thread is outstanding, so
12834             // we don't need to start it up.  The existing thread will
12835             // catch the buffer appends we just did.
12836             return;
12837         }
12838
12839         // Worker thread to both batch writes and to avoid blocking the caller on I/O.
12840         // (After this point, we shouldn't access AMS internal data structures.)
12841         new Thread("Error dump: " + dropboxTag) {
12842             @Override
12843             public void run() {
12844                 // 5 second sleep to let stacks arrive and be batched together
12845                 try {
12846                     Thread.sleep(5000);  // 5 seconds
12847                 } catch (InterruptedException e) {}
12848
12849                 String errorReport;
12850                 synchronized (mStrictModeBuffer) {
12851                     errorReport = mStrictModeBuffer.toString();
12852                     if (errorReport.length() == 0) {
12853                         return;
12854                     }
12855                     mStrictModeBuffer.delete(0, mStrictModeBuffer.length());
12856                     mStrictModeBuffer.trimToSize();
12857                 }
12858                 dbox.addText(dropboxTag, errorReport);
12859             }
12860         }.start();
12861     }
12862
12863     /**
12864      * Used by {@link Log} via {@link com.android.internal.os.RuntimeInit} to report serious errors.
12865      * @param app object of the crashing app, null for the system server
12866      * @param tag reported by the caller
12867      * @param system whether this wtf is coming from the system
12868      * @param crashInfo describing the context of the error
12869      * @return true if the process should exit immediately (WTF is fatal)
12870      */
12871     public boolean handleApplicationWtf(final IBinder app, final String tag, boolean system,
12872             final ApplicationErrorReport.CrashInfo crashInfo) {
12873         final int callingUid = Binder.getCallingUid();
12874         final int callingPid = Binder.getCallingPid();
12875
12876         if (system) {
12877             // If this is coming from the system, we could very well have low-level
12878             // system locks held, so we want to do this all asynchronously.  And we
12879             // never want this to become fatal, so there is that too.
12880             mHandler.post(new Runnable() {
12881                 @Override public void run() {
12882                     handleApplicationWtfInner(callingUid, callingPid, app, tag, crashInfo);
12883                 }
12884             });
12885             return false;
12886         }
12887
12888         final ProcessRecord r = handleApplicationWtfInner(callingUid, callingPid, app, tag,
12889                 crashInfo);
12890
12891         if (r != null && r.pid != Process.myPid() &&
12892                 Settings.Global.getInt(mContext.getContentResolver(),
12893                         Settings.Global.WTF_IS_FATAL, 0) != 0) {
12894             crashApplication(r, crashInfo);
12895             return true;
12896         } else {
12897             return false;
12898         }
12899     }
12900
12901     ProcessRecord handleApplicationWtfInner(int callingUid, int callingPid, IBinder app, String tag,
12902             final ApplicationErrorReport.CrashInfo crashInfo) {
12903         final ProcessRecord r = findAppProcess(app, "WTF");
12904         final String processName = app == null ? "system_server"
12905                 : (r == null ? "unknown" : r.processName);
12906
12907         EventLog.writeEvent(EventLogTags.AM_WTF, UserHandle.getUserId(callingUid), callingPid,
12908                 processName, r == null ? -1 : r.info.flags, tag, crashInfo.exceptionMessage);
12909
12910         addErrorToDropBox("wtf", r, processName, null, null, tag, null, null, crashInfo);
12911
12912         return r;
12913     }
12914
12915     /**
12916      * @param app object of some object (as stored in {@link com.android.internal.os.RuntimeInit})
12917      * @return the corresponding {@link ProcessRecord} object, or null if none could be found
12918      */
12919     private ProcessRecord findAppProcess(IBinder app, String reason) {
12920         if (app == null) {
12921             return null;
12922         }
12923
12924         synchronized (this) {
12925             final int NP = mProcessNames.getMap().size();
12926             for (int ip=0; ip<NP; ip++) {
12927                 SparseArray<ProcessRecord> apps = mProcessNames.getMap().valueAt(ip);
12928                 final int NA = apps.size();
12929                 for (int ia=0; ia<NA; ia++) {
12930                     ProcessRecord p = apps.valueAt(ia);
12931                     if (p.thread != null && p.thread.asBinder() == app) {
12932                         return p;
12933                     }
12934                 }
12935             }
12936
12937             Slog.w(TAG, "Can't find mystery application for " + reason
12938                     + " from pid=" + Binder.getCallingPid()
12939                     + " uid=" + Binder.getCallingUid() + ": " + app);
12940             return null;
12941         }
12942     }
12943
12944     /**
12945      * Utility function for addErrorToDropBox and handleStrictModeViolation's logging
12946      * to append various headers to the dropbox log text.
12947      */
12948     private void appendDropBoxProcessHeaders(ProcessRecord process, String processName,
12949             StringBuilder sb) {
12950         // Watchdog thread ends up invoking this function (with
12951         // a null ProcessRecord) to add the stack file to dropbox.
12952         // Do not acquire a lock on this (am) in such cases, as it
12953         // could cause a potential deadlock, if and when watchdog
12954         // is invoked due to unavailability of lock on am and it
12955         // would prevent watchdog from killing system_server.
12956         if (process == null) {
12957             sb.append("Process: ").append(processName).append("\n");
12958             return;
12959         }
12960         // Note: ProcessRecord 'process' is guarded by the service
12961         // instance.  (notably process.pkgList, which could otherwise change
12962         // concurrently during execution of this method)
12963         synchronized (this) {
12964             sb.append("Process: ").append(processName).append("\n");
12965             int flags = process.info.flags;
12966             IPackageManager pm = AppGlobals.getPackageManager();
12967             sb.append("Flags: 0x").append(Integer.toString(flags, 16)).append("\n");
12968             for (int ip=0; ip<process.pkgList.size(); ip++) {
12969                 String pkg = process.pkgList.keyAt(ip);
12970                 sb.append("Package: ").append(pkg);
12971                 try {
12972                     PackageInfo pi = pm.getPackageInfo(pkg, 0, UserHandle.getCallingUserId());
12973                     if (pi != null) {
12974                         sb.append(" v").append(pi.versionCode);
12975                         if (pi.versionName != null) {
12976                             sb.append(" (").append(pi.versionName).append(")");
12977                         }
12978                     }
12979                 } catch (RemoteException e) {
12980                     Slog.e(TAG, "Error getting package info: " + pkg, e);
12981                 }
12982                 sb.append("\n");
12983             }
12984         }
12985     }
12986
12987     private static String processClass(ProcessRecord process) {
12988         if (process == null || process.pid == MY_PID) {
12989             return "system_server";
12990         } else if ((process.info.flags & ApplicationInfo.FLAG_SYSTEM) != 0) {
12991             return "system_app";
12992         } else {
12993             return "data_app";
12994         }
12995     }
12996
12997     /**
12998      * Write a description of an error (crash, WTF, ANR) to the drop box.
12999      * @param eventType to include in the drop box tag ("crash", "wtf", etc.)
13000      * @param process which caused the error, null means the system server
13001      * @param activity which triggered the error, null if unknown
13002      * @param parent activity related to the error, null if unknown
13003      * @param subject line related to the error, null if absent
13004      * @param report in long form describing the error, null if absent
13005      * @param logFile to include in the report, null if none
13006      * @param crashInfo giving an application stack trace, null if absent
13007      */
13008     public void addErrorToDropBox(String eventType,
13009             ProcessRecord process, String processName, ActivityRecord activity,
13010             ActivityRecord parent, String subject,
13011             final String report, final File logFile,
13012             final ApplicationErrorReport.CrashInfo crashInfo) {
13013         // NOTE -- this must never acquire the ActivityManagerService lock,
13014         // otherwise the watchdog may be prevented from resetting the system.
13015
13016         final String dropboxTag = processClass(process) + "_" + eventType;
13017         final DropBoxManager dbox = (DropBoxManager)
13018                 mContext.getSystemService(Context.DROPBOX_SERVICE);
13019
13020         // Exit early if the dropbox isn't configured to accept this report type.
13021         if (dbox == null || !dbox.isTagEnabled(dropboxTag)) return;
13022
13023         final StringBuilder sb = new StringBuilder(1024);
13024         appendDropBoxProcessHeaders(process, processName, sb);
13025         if (activity != null) {
13026             sb.append("Activity: ").append(activity.shortComponentName).append("\n");
13027         }
13028         if (parent != null && parent.app != null && parent.app.pid != process.pid) {
13029             sb.append("Parent-Process: ").append(parent.app.processName).append("\n");
13030         }
13031         if (parent != null && parent != activity) {
13032             sb.append("Parent-Activity: ").append(parent.shortComponentName).append("\n");
13033         }
13034         if (subject != null) {
13035             sb.append("Subject: ").append(subject).append("\n");
13036         }
13037         sb.append("Build: ").append(Build.FINGERPRINT).append("\n");
13038         if (Debug.isDebuggerConnected()) {
13039             sb.append("Debugger: Connected\n");
13040         }
13041         sb.append("\n");
13042
13043         // Do the rest in a worker thread to avoid blocking the caller on I/O
13044         // (After this point, we shouldn't access AMS internal data structures.)
13045         Thread worker = new Thread("Error dump: " + dropboxTag) {
13046             @Override
13047             public void run() {
13048                 if (report != null) {
13049                     sb.append(report);
13050                 }
13051                 if (logFile != null) {
13052                     try {
13053                         sb.append(FileUtils.readTextFile(logFile, DROPBOX_MAX_SIZE,
13054                                     "\n\n[[TRUNCATED]]"));
13055                     } catch (IOException e) {
13056                         Slog.e(TAG, "Error reading " + logFile, e);
13057                     }
13058                 }
13059                 if (crashInfo != null && crashInfo.stackTrace != null) {
13060                     sb.append(crashInfo.stackTrace);
13061                 }
13062
13063                 String setting = Settings.Global.ERROR_LOGCAT_PREFIX + dropboxTag;
13064                 int lines = Settings.Global.getInt(mContext.getContentResolver(), setting, 0);
13065                 if (lines > 0) {
13066                     sb.append("\n");
13067
13068                     // Merge several logcat streams, and take the last N lines
13069                     InputStreamReader input = null;
13070                     try {
13071                         java.lang.Process logcat = new ProcessBuilder("/system/bin/logcat",
13072                                 "-v", "time", "-b", "events", "-b", "system", "-b", "main",
13073                                 "-b", "crash",
13074                                 "-t", String.valueOf(lines)).redirectErrorStream(true).start();
13075
13076                         try { logcat.getOutputStream().close(); } catch (IOException e) {}
13077                         try { logcat.getErrorStream().close(); } catch (IOException e) {}
13078                         input = new InputStreamReader(logcat.getInputStream());
13079
13080                         int num;
13081                         char[] buf = new char[8192];
13082                         while ((num = input.read(buf)) > 0) sb.append(buf, 0, num);
13083                     } catch (IOException e) {
13084                         Slog.e(TAG, "Error running logcat", e);
13085                     } finally {
13086                         if (input != null) try { input.close(); } catch (IOException e) {}
13087                     }
13088                 }
13089
13090                 dbox.addText(dropboxTag, sb.toString());
13091             }
13092         };
13093
13094         if (process == null) {
13095             // If process is null, we are being called from some internal code
13096             // and may be about to die -- run this synchronously.
13097             worker.run();
13098         } else {
13099             worker.start();
13100         }
13101     }
13102
13103     /**
13104      * Bring up the "unexpected error" dialog box for a crashing app.
13105      * Deal with edge cases (intercepts from instrumented applications,
13106      * ActivityController, error intent receivers, that sort of thing).
13107      * @param r the application crashing
13108      * @param crashInfo describing the failure
13109      */
13110     private void crashApplication(ProcessRecord r, ApplicationErrorReport.CrashInfo crashInfo) {
13111         long timeMillis = System.currentTimeMillis();
13112         String shortMsg = crashInfo.exceptionClassName;
13113         String longMsg = crashInfo.exceptionMessage;
13114         String stackTrace = crashInfo.stackTrace;
13115         if (shortMsg != null && longMsg != null) {
13116             longMsg = shortMsg + ": " + longMsg;
13117         } else if (shortMsg != null) {
13118             longMsg = shortMsg;
13119         }
13120
13121         AppErrorResult result = new AppErrorResult();
13122         synchronized (this) {
13123             if (mController != null) {
13124                 try {
13125                     String name = r != null ? r.processName : null;
13126                     int pid = r != null ? r.pid : Binder.getCallingPid();
13127                     int uid = r != null ? r.info.uid : Binder.getCallingUid();
13128                     if (!mController.appCrashed(name, pid,
13129                             shortMsg, longMsg, timeMillis, crashInfo.stackTrace)) {
13130                         if ("1".equals(SystemProperties.get(SYSTEM_DEBUGGABLE, "0"))
13131                                 && "Native crash".equals(crashInfo.exceptionClassName)) {
13132                             Slog.w(TAG, "Skip killing native crashed app " + name
13133                                     + "(" + pid + ") during testing");
13134                         } else {
13135                             Slog.w(TAG, "Force-killing crashed app " + name
13136                                     + " at watcher's request");
13137                             if (r != null) {
13138                                 r.kill("crash", true);
13139                             } else {
13140                                 // Huh.
13141                                 Process.killProcess(pid);
13142                                 killProcessGroup(uid, pid);
13143                             }
13144                         }
13145                         return;
13146                     }
13147                 } catch (RemoteException e) {
13148                     mController = null;
13149                     Watchdog.getInstance().setActivityController(null);
13150                 }
13151             }
13152
13153             final long origId = Binder.clearCallingIdentity();
13154
13155             // If this process is running instrumentation, finish it.
13156             if (r != null && r.instrumentationClass != null) {
13157                 Slog.w(TAG, "Error in app " + r.processName
13158                       + " running instrumentation " + r.instrumentationClass + ":");
13159                 if (shortMsg != null) Slog.w(TAG, "  " + shortMsg);
13160                 if (longMsg != null) Slog.w(TAG, "  " + longMsg);
13161                 Bundle info = new Bundle();
13162                 info.putString("shortMsg", shortMsg);
13163                 info.putString("longMsg", longMsg);
13164                 finishInstrumentationLocked(r, Activity.RESULT_CANCELED, info);
13165                 Binder.restoreCallingIdentity(origId);
13166                 return;
13167             }
13168
13169             // Log crash in battery stats.
13170             if (r != null) {
13171                 mBatteryStatsService.noteProcessCrash(r.processName, r.uid);
13172             }
13173
13174             // If we can't identify the process or it's already exceeded its crash quota,
13175             // quit right away without showing a crash dialog.
13176             if (r == null || !makeAppCrashingLocked(r, shortMsg, longMsg, stackTrace)) {
13177                 Binder.restoreCallingIdentity(origId);
13178                 return;
13179             }
13180
13181             Message msg = Message.obtain();
13182             msg.what = SHOW_ERROR_UI_MSG;
13183             HashMap data = new HashMap();
13184             data.put("result", result);
13185             data.put("app", r);
13186             msg.obj = data;
13187             mUiHandler.sendMessage(msg);
13188
13189             Binder.restoreCallingIdentity(origId);
13190         }
13191
13192         int res = result.get();
13193
13194         Intent appErrorIntent = null;
13195         synchronized (this) {
13196             if (r != null && !r.isolated) {
13197                 // XXX Can't keep track of crash time for isolated processes,
13198                 // since they don't have a persistent identity.
13199                 mProcessCrashTimes.put(r.info.processName, r.uid,
13200                         SystemClock.uptimeMillis());
13201             }
13202             if (res == AppErrorDialog.FORCE_QUIT_AND_REPORT) {
13203                 appErrorIntent = createAppErrorIntentLocked(r, timeMillis, crashInfo);
13204             }
13205         }
13206
13207         if (appErrorIntent != null) {
13208             try {
13209                 mContext.startActivityAsUser(appErrorIntent, new UserHandle(r.userId));
13210             } catch (ActivityNotFoundException e) {
13211                 Slog.w(TAG, "bug report receiver dissappeared", e);
13212             }
13213         }
13214     }
13215
13216     Intent createAppErrorIntentLocked(ProcessRecord r,
13217             long timeMillis, ApplicationErrorReport.CrashInfo crashInfo) {
13218         ApplicationErrorReport report = createAppErrorReportLocked(r, timeMillis, crashInfo);
13219         if (report == null) {
13220             return null;
13221         }
13222         Intent result = new Intent(Intent.ACTION_APP_ERROR);
13223         result.setComponent(r.errorReportReceiver);
13224         result.putExtra(Intent.EXTRA_BUG_REPORT, report);
13225         result.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
13226         return result;
13227     }
13228
13229     private ApplicationErrorReport createAppErrorReportLocked(ProcessRecord r,
13230             long timeMillis, ApplicationErrorReport.CrashInfo crashInfo) {
13231         if (r.errorReportReceiver == null) {
13232             return null;
13233         }
13234
13235         if (!r.crashing && !r.notResponding && !r.forceCrashReport) {
13236             return null;
13237         }
13238
13239         ApplicationErrorReport report = new ApplicationErrorReport();
13240         report.packageName = r.info.packageName;
13241         report.installerPackageName = r.errorReportReceiver.getPackageName();
13242         report.processName = r.processName;
13243         report.time = timeMillis;
13244         report.systemApp = (r.info.flags & ApplicationInfo.FLAG_SYSTEM) != 0;
13245
13246         if (r.crashing || r.forceCrashReport) {
13247             report.type = ApplicationErrorReport.TYPE_CRASH;
13248             report.crashInfo = crashInfo;
13249         } else if (r.notResponding) {
13250             report.type = ApplicationErrorReport.TYPE_ANR;
13251             report.anrInfo = new ApplicationErrorReport.AnrInfo();
13252
13253             report.anrInfo.activity = r.notRespondingReport.tag;
13254             report.anrInfo.cause = r.notRespondingReport.shortMsg;
13255             report.anrInfo.info = r.notRespondingReport.longMsg;
13256         }
13257
13258         return report;
13259     }
13260
13261     public List<ActivityManager.ProcessErrorStateInfo> getProcessesInErrorState() {
13262         enforceNotIsolatedCaller("getProcessesInErrorState");
13263         // assume our apps are happy - lazy create the list
13264         List<ActivityManager.ProcessErrorStateInfo> errList = null;
13265
13266         final boolean allUsers = ActivityManager.checkUidPermission(INTERACT_ACROSS_USERS_FULL,
13267                 Binder.getCallingUid()) == PackageManager.PERMISSION_GRANTED;
13268         int userId = UserHandle.getUserId(Binder.getCallingUid());
13269
13270         synchronized (this) {
13271
13272             // iterate across all processes
13273             for (int i=mLruProcesses.size()-1; i>=0; i--) {
13274                 ProcessRecord app = mLruProcesses.get(i);
13275                 if (!allUsers && app.userId != userId) {
13276                     continue;
13277                 }
13278                 if ((app.thread != null) && (app.crashing || app.notResponding)) {
13279                     // This one's in trouble, so we'll generate a report for it
13280                     // crashes are higher priority (in case there's a crash *and* an anr)
13281                     ActivityManager.ProcessErrorStateInfo report = null;
13282                     if (app.crashing) {
13283                         report = app.crashingReport;
13284                     } else if (app.notResponding) {
13285                         report = app.notRespondingReport;
13286                     }
13287
13288                     if (report != null) {
13289                         if (errList == null) {
13290                             errList = new ArrayList<ActivityManager.ProcessErrorStateInfo>(1);
13291                         }
13292                         errList.add(report);
13293                     } else {
13294                         Slog.w(TAG, "Missing app error report, app = " + app.processName +
13295                                 " crashing = " + app.crashing +
13296                                 " notResponding = " + app.notResponding);
13297                     }
13298                 }
13299             }
13300         }
13301
13302         return errList;
13303     }
13304
13305     static int procStateToImportance(int procState, int memAdj,
13306             ActivityManager.RunningAppProcessInfo currApp) {
13307         int imp = ActivityManager.RunningAppProcessInfo.procStateToImportance(procState);
13308         if (imp == ActivityManager.RunningAppProcessInfo.IMPORTANCE_BACKGROUND) {
13309             currApp.lru = memAdj;
13310         } else {
13311             currApp.lru = 0;
13312         }
13313         return imp;
13314     }
13315
13316     private void fillInProcMemInfo(ProcessRecord app,
13317             ActivityManager.RunningAppProcessInfo outInfo) {
13318         outInfo.pid = app.pid;
13319         outInfo.uid = app.info.uid;
13320         if (mHeavyWeightProcess == app) {
13321             outInfo.flags |= ActivityManager.RunningAppProcessInfo.FLAG_CANT_SAVE_STATE;
13322         }
13323         if (app.persistent) {
13324             outInfo.flags |= ActivityManager.RunningAppProcessInfo.FLAG_PERSISTENT;
13325         }
13326         if (app.activities.size() > 0) {
13327             outInfo.flags |= ActivityManager.RunningAppProcessInfo.FLAG_HAS_ACTIVITIES;
13328         }
13329         outInfo.lastTrimLevel = app.trimMemoryLevel;
13330         int adj = app.curAdj;
13331         int procState = app.curProcState;
13332         outInfo.importance = procStateToImportance(procState, adj, outInfo);
13333         outInfo.importanceReasonCode = app.adjTypeCode;
13334         outInfo.processState = app.curProcState;
13335     }
13336
13337     public List<ActivityManager.RunningAppProcessInfo> getRunningAppProcesses() {
13338         enforceNotIsolatedCaller("getRunningAppProcesses");
13339
13340         final int callingUid = Binder.getCallingUid();
13341
13342         // Lazy instantiation of list
13343         List<ActivityManager.RunningAppProcessInfo> runList = null;
13344         final boolean allUsers = ActivityManager.checkUidPermission(INTERACT_ACROSS_USERS_FULL,
13345                 callingUid) == PackageManager.PERMISSION_GRANTED;
13346         final int userId = UserHandle.getUserId(callingUid);
13347         final boolean allUids = isGetTasksAllowed(
13348                 "getRunningAppProcesses", Binder.getCallingPid(), callingUid);
13349
13350         synchronized (this) {
13351             // Iterate across all processes
13352             for (int i = mLruProcesses.size() - 1; i >= 0; i--) {
13353                 ProcessRecord app = mLruProcesses.get(i);
13354                 if ((!allUsers && app.userId != userId)
13355                         || (!allUids && app.uid != callingUid)) {
13356                     continue;
13357                 }
13358                 if ((app.thread != null) && (!app.crashing && !app.notResponding)) {
13359                     // Generate process state info for running application
13360                     ActivityManager.RunningAppProcessInfo currApp =
13361                         new ActivityManager.RunningAppProcessInfo(app.processName,
13362                                 app.pid, app.getPackageList());
13363                     fillInProcMemInfo(app, currApp);
13364                     if (app.adjSource instanceof ProcessRecord) {
13365                         currApp.importanceReasonPid = ((ProcessRecord)app.adjSource).pid;
13366                         currApp.importanceReasonImportance =
13367                                 ActivityManager.RunningAppProcessInfo.procStateToImportance(
13368                                         app.adjSourceProcState);
13369                     } else if (app.adjSource instanceof ActivityRecord) {
13370                         ActivityRecord r = (ActivityRecord)app.adjSource;
13371                         if (r.app != null) currApp.importanceReasonPid = r.app.pid;
13372                     }
13373                     if (app.adjTarget instanceof ComponentName) {
13374                         currApp.importanceReasonComponent = (ComponentName)app.adjTarget;
13375                     }
13376                     //Slog.v(TAG, "Proc " + app.processName + ": imp=" + currApp.importance
13377                     //        + " lru=" + currApp.lru);
13378                     if (runList == null) {
13379                         runList = new ArrayList<>();
13380                     }
13381                     runList.add(currApp);
13382                 }
13383             }
13384         }
13385         return runList;
13386     }
13387
13388     public List<ApplicationInfo> getRunningExternalApplications() {
13389         enforceNotIsolatedCaller("getRunningExternalApplications");
13390         List<ActivityManager.RunningAppProcessInfo> runningApps = getRunningAppProcesses();
13391         List<ApplicationInfo> retList = new ArrayList<ApplicationInfo>();
13392         if (runningApps != null && runningApps.size() > 0) {
13393             Set<String> extList = new HashSet<String>();
13394             for (ActivityManager.RunningAppProcessInfo app : runningApps) {
13395                 if (app.pkgList != null) {
13396                     for (String pkg : app.pkgList) {
13397                         extList.add(pkg);
13398                     }
13399                 }
13400             }
13401             IPackageManager pm = AppGlobals.getPackageManager();
13402             for (String pkg : extList) {
13403                 try {
13404                     ApplicationInfo info = pm.getApplicationInfo(pkg, 0, UserHandle.getCallingUserId());
13405                     if ((info.flags & ApplicationInfo.FLAG_EXTERNAL_STORAGE) != 0) {
13406                         retList.add(info);
13407                     }
13408                 } catch (RemoteException e) {
13409                 }
13410             }
13411         }
13412         return retList;
13413     }
13414
13415     @Override
13416     public void getMyMemoryState(ActivityManager.RunningAppProcessInfo outInfo) {
13417         enforceNotIsolatedCaller("getMyMemoryState");
13418         synchronized (this) {
13419             ProcessRecord proc;
13420             synchronized (mPidsSelfLocked) {
13421                 proc = mPidsSelfLocked.get(Binder.getCallingPid());
13422             }
13423             fillInProcMemInfo(proc, outInfo);
13424         }
13425     }
13426
13427     @Override
13428     public void onShellCommand(FileDescriptor in, FileDescriptor out,
13429             FileDescriptor err, String[] args, ResultReceiver resultReceiver) {
13430         (new ActivityManagerShellCommand(this, false)).exec(
13431                 this, in, out, err, args, resultReceiver);
13432     }
13433
13434     @Override
13435     protected void dump(FileDescriptor fd, PrintWriter pw, String[] args) {
13436         if (checkCallingPermission(android.Manifest.permission.DUMP)
13437                 != PackageManager.PERMISSION_GRANTED) {
13438             pw.println("Permission Denial: can't dump ActivityManager from from pid="
13439                     + Binder.getCallingPid()
13440                     + ", uid=" + Binder.getCallingUid()
13441                     + " without permission "
13442                     + android.Manifest.permission.DUMP);
13443             return;
13444         }
13445
13446         boolean dumpAll = false;
13447         boolean dumpClient = false;
13448         String dumpPackage = null;
13449
13450         int opti = 0;
13451         while (opti < args.length) {
13452             String opt = args[opti];
13453             if (opt == null || opt.length() <= 0 || opt.charAt(0) != '-') {
13454                 break;
13455             }
13456             opti++;
13457             if ("-a".equals(opt)) {
13458                 dumpAll = true;
13459             } else if ("-c".equals(opt)) {
13460                 dumpClient = true;
13461             } else if ("-p".equals(opt)) {
13462                 if (opti < args.length) {
13463                     dumpPackage = args[opti];
13464                     opti++;
13465                 } else {
13466                     pw.println("Error: -p option requires package argument");
13467                     return;
13468                 }
13469                 dumpClient = true;
13470             } else if ("-h".equals(opt)) {
13471                 ActivityManagerShellCommand.dumpHelp(pw, true);
13472                 return;
13473             } else {
13474                 pw.println("Unknown argument: " + opt + "; use -h for help");
13475             }
13476         }
13477
13478         long origId = Binder.clearCallingIdentity();
13479         boolean more = false;
13480         // Is the caller requesting to dump a particular piece of data?
13481         if (opti < args.length) {
13482             String cmd = args[opti];
13483             opti++;
13484             if ("activities".equals(cmd) || "a".equals(cmd)) {
13485                 synchronized (this) {
13486                     dumpActivitiesLocked(fd, pw, args, opti, true, dumpClient, dumpPackage);
13487                 }
13488             } else if ("recents".equals(cmd) || "r".equals(cmd)) {
13489                 synchronized (this) {
13490                     dumpRecentsLocked(fd, pw, args, opti, true, dumpPackage);
13491                 }
13492             } else if ("broadcasts".equals(cmd) || "b".equals(cmd)) {
13493                 String[] newArgs;
13494                 String name;
13495                 if (opti >= args.length) {
13496                     name = null;
13497                     newArgs = EMPTY_STRING_ARRAY;
13498                 } else {
13499                     dumpPackage = args[opti];
13500                     opti++;
13501                     newArgs = new String[args.length - opti];
13502                     if (args.length > 2) System.arraycopy(args, opti, newArgs, 0,
13503                             args.length - opti);
13504                 }
13505                 synchronized (this) {
13506                     dumpBroadcastsLocked(fd, pw, args, opti, true, dumpPackage);
13507                 }
13508             } else if ("intents".equals(cmd) || "i".equals(cmd)) {
13509                 String[] newArgs;
13510                 String name;
13511                 if (opti >= args.length) {
13512                     name = null;
13513                     newArgs = EMPTY_STRING_ARRAY;
13514                 } else {
13515                     dumpPackage = args[opti];
13516                     opti++;
13517                     newArgs = new String[args.length - opti];
13518                     if (args.length > 2) System.arraycopy(args, opti, newArgs, 0,
13519                             args.length - opti);
13520                 }
13521                 synchronized (this) {
13522                     dumpPendingIntentsLocked(fd, pw, args, opti, true, dumpPackage);
13523                 }
13524             } else if ("processes".equals(cmd) || "p".equals(cmd)) {
13525                 String[] newArgs;
13526                 String name;
13527                 if (opti >= args.length) {
13528                     name = null;
13529                     newArgs = EMPTY_STRING_ARRAY;
13530                 } else {
13531                     dumpPackage = args[opti];
13532                     opti++;
13533                     newArgs = new String[args.length - opti];
13534                     if (args.length > 2) System.arraycopy(args, opti, newArgs, 0,
13535                             args.length - opti);
13536                 }
13537                 synchronized (this) {
13538                     dumpProcessesLocked(fd, pw, args, opti, true, dumpPackage);
13539                 }
13540             } else if ("oom".equals(cmd) || "o".equals(cmd)) {
13541                 synchronized (this) {
13542                     dumpOomLocked(fd, pw, args, opti, true);
13543                 }
13544             } else if ("permissions".equals(cmd) || "perm".equals(cmd)) {
13545                 synchronized (this) {
13546                     dumpPermissionsLocked(fd, pw, args, opti, true, null);
13547                 }
13548             } else if ("provider".equals(cmd)) {
13549                 String[] newArgs;
13550                 String name;
13551                 if (opti >= args.length) {
13552                     name = null;
13553                     newArgs = EMPTY_STRING_ARRAY;
13554                 } else {
13555                     name = args[opti];
13556                     opti++;
13557                     newArgs = new String[args.length - opti];
13558                     if (args.length > 2) System.arraycopy(args, opti, newArgs, 0, args.length - opti);
13559                 }
13560                 if (!dumpProvider(fd, pw, name, newArgs, 0, dumpAll)) {
13561                     pw.println("No providers match: " + name);
13562                     pw.println("Use -h for help.");
13563                 }
13564             } else if ("providers".equals(cmd) || "prov".equals(cmd)) {
13565                 synchronized (this) {
13566                     dumpProvidersLocked(fd, pw, args, opti, true, null);
13567                 }
13568             } else if ("service".equals(cmd)) {
13569                 String[] newArgs;
13570                 String name;
13571                 if (opti >= args.length) {
13572                     name = null;
13573                     newArgs = EMPTY_STRING_ARRAY;
13574                 } else {
13575                     name = args[opti];
13576                     opti++;
13577                     newArgs = new String[args.length - opti];
13578                     if (args.length > 2) System.arraycopy(args, opti, newArgs, 0,
13579                             args.length - opti);
13580                 }
13581                 if (!mServices.dumpService(fd, pw, name, newArgs, 0, dumpAll)) {
13582                     pw.println("No services match: " + name);
13583                     pw.println("Use -h for help.");
13584                 }
13585             } else if ("package".equals(cmd)) {
13586                 String[] newArgs;
13587                 if (opti >= args.length) {
13588                     pw.println("package: no package name specified");
13589                     pw.println("Use -h for help.");
13590                 } else {
13591                     dumpPackage = args[opti];
13592                     opti++;
13593                     newArgs = new String[args.length - opti];
13594                     if (args.length > 2) System.arraycopy(args, opti, newArgs, 0,
13595                             args.length - opti);
13596                     args = newArgs;
13597                     opti = 0;
13598                     more = true;
13599                 }
13600             } else if ("associations".equals(cmd) || "as".equals(cmd)) {
13601                 synchronized (this) {
13602                     dumpAssociationsLocked(fd, pw, args, opti, true, dumpClient, dumpPackage);
13603                 }
13604             } else if ("services".equals(cmd) || "s".equals(cmd)) {
13605                 synchronized (this) {
13606                     mServices.dumpServicesLocked(fd, pw, args, opti, true, dumpClient, dumpPackage);
13607                 }
13608             } else {
13609                 // Dumping a single activity?
13610                 if (!dumpActivity(fd, pw, cmd, args, opti, dumpAll)) {
13611                     ActivityManagerShellCommand shell = new ActivityManagerShellCommand(this, true);
13612                     int res = shell.exec(this, null, fd, null, args, new ResultReceiver(null));
13613                     if (res < 0) {
13614                         pw.println("Bad activity command, or no activities match: " + cmd);
13615                         pw.println("Use -h for help.");
13616                     }
13617                 }
13618             }
13619             if (!more) {
13620                 Binder.restoreCallingIdentity(origId);
13621                 return;
13622             }
13623         }
13624
13625         // No piece of data specified, dump everything.
13626         synchronized (this) {
13627             dumpPendingIntentsLocked(fd, pw, args, opti, dumpAll, dumpPackage);
13628             pw.println();
13629             if (dumpAll) {
13630                 pw.println("-------------------------------------------------------------------------------");
13631             }
13632             dumpBroadcastsLocked(fd, pw, args, opti, dumpAll, dumpPackage);
13633             pw.println();
13634             if (dumpAll) {
13635                 pw.println("-------------------------------------------------------------------------------");
13636             }
13637             dumpProvidersLocked(fd, pw, args, opti, dumpAll, dumpPackage);
13638             pw.println();
13639             if (dumpAll) {
13640                 pw.println("-------------------------------------------------------------------------------");
13641             }
13642             dumpPermissionsLocked(fd, pw, args, opti, dumpAll, dumpPackage);
13643             pw.println();
13644             if (dumpAll) {
13645                 pw.println("-------------------------------------------------------------------------------");
13646             }
13647             mServices.dumpServicesLocked(fd, pw, args, opti, dumpAll, dumpClient, dumpPackage);
13648             pw.println();
13649             if (dumpAll) {
13650                 pw.println("-------------------------------------------------------------------------------");
13651             }
13652             dumpRecentsLocked(fd, pw, args, opti, dumpAll, dumpPackage);
13653             pw.println();
13654             if (dumpAll) {
13655                 pw.println("-------------------------------------------------------------------------------");
13656             }
13657             dumpActivitiesLocked(fd, pw, args, opti, dumpAll, dumpClient, dumpPackage);
13658             if (mAssociations.size() > 0) {
13659                 pw.println();
13660                 if (dumpAll) {
13661                     pw.println("-------------------------------------------------------------------------------");
13662                 }
13663                 dumpAssociationsLocked(fd, pw, args, opti, dumpAll, dumpClient, dumpPackage);
13664             }
13665             pw.println();
13666             if (dumpAll) {
13667                 pw.println("-------------------------------------------------------------------------------");
13668             }
13669             dumpProcessesLocked(fd, pw, args, opti, dumpAll, dumpPackage);
13670         }
13671         Binder.restoreCallingIdentity(origId);
13672     }
13673
13674     void dumpActivitiesLocked(FileDescriptor fd, PrintWriter pw, String[] args,
13675             int opti, boolean dumpAll, boolean dumpClient, String dumpPackage) {
13676         pw.println("ACTIVITY MANAGER ACTIVITIES (dumpsys activity activities)");
13677
13678         boolean printedAnything = mStackSupervisor.dumpActivitiesLocked(fd, pw, dumpAll, dumpClient,
13679                 dumpPackage);
13680         boolean needSep = printedAnything;
13681
13682         boolean printed = ActivityStackSupervisor.printThisActivity(pw, mFocusedActivity,
13683                 dumpPackage, needSep, "  mFocusedActivity: ");
13684         if (printed) {
13685             printedAnything = true;
13686             needSep = false;
13687         }
13688
13689         if (dumpPackage == null) {
13690             if (needSep) {
13691                 pw.println();
13692             }
13693             needSep = true;
13694             printedAnything = true;
13695             mStackSupervisor.dump(pw, "  ");
13696         }
13697
13698         if (!printedAnything) {
13699             pw.println("  (nothing)");
13700         }
13701     }
13702
13703     void dumpRecentsLocked(FileDescriptor fd, PrintWriter pw, String[] args,
13704             int opti, boolean dumpAll, String dumpPackage) {
13705         pw.println("ACTIVITY MANAGER RECENT TASKS (dumpsys activity recents)");
13706
13707         boolean printedAnything = false;
13708
13709         if (mRecentTasks != null && mRecentTasks.size() > 0) {
13710             boolean printedHeader = false;
13711
13712             final int N = mRecentTasks.size();
13713             for (int i=0; i<N; i++) {
13714                 TaskRecord tr = mRecentTasks.get(i);
13715                 if (dumpPackage != null) {
13716                     if (tr.realActivity == null ||
13717                             !dumpPackage.equals(tr.realActivity)) {
13718                         continue;
13719                     }
13720                 }
13721                 if (!printedHeader) {
13722                     pw.println("  Recent tasks:");
13723                     printedHeader = true;
13724                     printedAnything = true;
13725                 }
13726                 pw.print("  * Recent #"); pw.print(i); pw.print(": ");
13727                         pw.println(tr);
13728                 if (dumpAll) {
13729                     mRecentTasks.get(i).dump(pw, "    ");
13730                 }
13731             }
13732         }
13733
13734         if (!printedAnything) {
13735             pw.println("  (nothing)");
13736         }
13737     }
13738
13739     void dumpAssociationsLocked(FileDescriptor fd, PrintWriter pw, String[] args,
13740             int opti, boolean dumpAll, boolean dumpClient, String dumpPackage) {
13741         pw.println("ACTIVITY MANAGER ASSOCIATIONS (dumpsys activity associations)");
13742
13743         int dumpUid = 0;
13744         if (dumpPackage != null) {
13745             IPackageManager pm = AppGlobals.getPackageManager();
13746             try {
13747                 dumpUid = pm.getPackageUid(dumpPackage, 0);
13748             } catch (RemoteException e) {
13749             }
13750         }
13751
13752         boolean printedAnything = false;
13753
13754         final long now = SystemClock.uptimeMillis();
13755
13756         for (int i1=0, N1=mAssociations.size(); i1<N1; i1++) {
13757             ArrayMap<ComponentName, SparseArray<ArrayMap<String, Association>>> targetComponents
13758                     = mAssociations.valueAt(i1);
13759             for (int i2=0, N2=targetComponents.size(); i2<N2; i2++) {
13760                 SparseArray<ArrayMap<String, Association>> sourceUids
13761                         = targetComponents.valueAt(i2);
13762                 for (int i3=0, N3=sourceUids.size(); i3<N3; i3++) {
13763                     ArrayMap<String, Association> sourceProcesses = sourceUids.valueAt(i3);
13764                     for (int i4=0, N4=sourceProcesses.size(); i4<N4; i4++) {
13765                         Association ass = sourceProcesses.valueAt(i4);
13766                         if (dumpPackage != null) {
13767                             if (!ass.mTargetComponent.getPackageName().equals(dumpPackage)
13768                                     && UserHandle.getAppId(ass.mSourceUid) != dumpUid) {
13769                                 continue;
13770                             }
13771                         }
13772                         printedAnything = true;
13773                         pw.print("  ");
13774                         pw.print(ass.mTargetProcess);
13775                         pw.print("/");
13776                         UserHandle.formatUid(pw, ass.mTargetUid);
13777                         pw.print(" <- ");
13778                         pw.print(ass.mSourceProcess);
13779                         pw.print("/");
13780                         UserHandle.formatUid(pw, ass.mSourceUid);
13781                         pw.println();
13782                         pw.print("    via ");
13783                         pw.print(ass.mTargetComponent.flattenToShortString());
13784                         pw.println();
13785                         pw.print("    ");
13786                         long dur = ass.mTime;
13787                         if (ass.mNesting > 0) {
13788                             dur += now - ass.mStartTime;
13789                         }
13790                         TimeUtils.formatDuration(dur, pw);
13791                         pw.print(" (");
13792                         pw.print(ass.mCount);
13793                         pw.println(" times)");
13794                         if (ass.mNesting > 0) {
13795                             pw.print("    ");
13796                             pw.print(" Currently active: ");
13797                             TimeUtils.formatDuration(now - ass.mStartTime, pw);
13798                             pw.println();
13799                         }
13800                     }
13801                 }
13802             }
13803
13804         }
13805
13806         if (!printedAnything) {
13807             pw.println("  (nothing)");
13808         }
13809     }
13810
13811     boolean dumpUids(PrintWriter pw, String dumpPackage, SparseArray<UidRecord> uids,
13812             String header, boolean needSep) {
13813         boolean printed = false;
13814         int whichAppId = -1;
13815         if (dumpPackage != null) {
13816             try {
13817                 ApplicationInfo info = mContext.getPackageManager().getApplicationInfo(
13818                         dumpPackage, 0);
13819                 whichAppId = UserHandle.getAppId(info.uid);
13820             } catch (NameNotFoundException e) {
13821                 e.printStackTrace();
13822             }
13823         }
13824         for (int i=0; i<uids.size(); i++) {
13825             UidRecord uidRec = uids.valueAt(i);
13826             if (dumpPackage != null && UserHandle.getAppId(uidRec.uid) != whichAppId) {
13827                 continue;
13828             }
13829             if (!printed) {
13830                 printed = true;
13831                 if (needSep) {
13832                     pw.println();
13833                 }
13834                 pw.print("  ");
13835                 pw.println(header);
13836                 needSep = true;
13837             }
13838             pw.print("    UID "); UserHandle.formatUid(pw, uidRec.uid);
13839             pw.print(": "); pw.println(uidRec);
13840         }
13841         return printed;
13842     }
13843
13844     void dumpProcessesLocked(FileDescriptor fd, PrintWriter pw, String[] args,
13845             int opti, boolean dumpAll, String dumpPackage) {
13846         boolean needSep = false;
13847         boolean printedAnything = false;
13848         int numPers = 0;
13849
13850         pw.println("ACTIVITY MANAGER RUNNING PROCESSES (dumpsys activity processes)");
13851
13852         if (dumpAll) {
13853             final int NP = mProcessNames.getMap().size();
13854             for (int ip=0; ip<NP; ip++) {
13855                 SparseArray<ProcessRecord> procs = mProcessNames.getMap().valueAt(ip);
13856                 final int NA = procs.size();
13857                 for (int ia=0; ia<NA; ia++) {
13858                     ProcessRecord r = procs.valueAt(ia);
13859                     if (dumpPackage != null && !r.pkgList.containsKey(dumpPackage)) {
13860                         continue;
13861                     }
13862                     if (!needSep) {
13863                         pw.println("  All known processes:");
13864                         needSep = true;
13865                         printedAnything = true;
13866                     }
13867                     pw.print(r.persistent ? "  *PERS*" : "  *APP*");
13868                         pw.print(" UID "); pw.print(procs.keyAt(ia));
13869                         pw.print(" "); pw.println(r);
13870                     r.dump(pw, "    ");
13871                     if (r.persistent) {
13872                         numPers++;
13873                     }
13874                 }
13875             }
13876         }
13877
13878         if (mIsolatedProcesses.size() > 0) {
13879             boolean printed = false;
13880             for (int i=0; i<mIsolatedProcesses.size(); i++) {
13881                 ProcessRecord r = mIsolatedProcesses.valueAt(i);
13882                 if (dumpPackage != null && !r.pkgList.containsKey(dumpPackage)) {
13883                     continue;
13884                 }
13885                 if (!printed) {
13886                     if (needSep) {
13887                         pw.println();
13888                     }
13889                     pw.println("  Isolated process list (sorted by uid):");
13890                     printedAnything = true;
13891                     printed = true;
13892                     needSep = true;
13893                 }
13894                 pw.println(String.format("%sIsolated #%2d: %s",
13895                         "    ", i, r.toString()));
13896             }
13897         }
13898
13899         if (mActiveUids.size() > 0) {
13900             if (dumpUids(pw, dumpPackage, mActiveUids, "UID states:", needSep)) {
13901                 printedAnything = needSep = true;
13902             }
13903         }
13904         if (mValidateUids.size() > 0) {
13905             if (dumpUids(pw, dumpPackage, mValidateUids, "UID validation:", needSep)) {
13906                 printedAnything = needSep = true;
13907             }
13908         }
13909
13910         if (mLruProcesses.size() > 0) {
13911             if (needSep) {
13912                 pw.println();
13913             }
13914             pw.print("  Process LRU list (sorted by oom_adj, "); pw.print(mLruProcesses.size());
13915                     pw.print(" total, non-act at ");
13916                     pw.print(mLruProcesses.size()-mLruProcessActivityStart);
13917                     pw.print(", non-svc at ");
13918                     pw.print(mLruProcesses.size()-mLruProcessServiceStart);
13919                     pw.println("):");
13920             dumpProcessOomList(pw, this, mLruProcesses, "    ", "Proc", "PERS", false, dumpPackage);
13921             needSep = true;
13922             printedAnything = true;
13923         }
13924
13925         if (dumpAll || dumpPackage != null) {
13926             synchronized (mPidsSelfLocked) {
13927                 boolean printed = false;
13928                 for (int i=0; i<mPidsSelfLocked.size(); i++) {
13929                     ProcessRecord r = mPidsSelfLocked.valueAt(i);
13930                     if (dumpPackage != null && !r.pkgList.containsKey(dumpPackage)) {
13931                         continue;
13932                     }
13933                     if (!printed) {
13934                         if (needSep) pw.println();
13935                         needSep = true;
13936                         pw.println("  PID mappings:");
13937                         printed = true;
13938                         printedAnything = true;
13939                     }
13940                     pw.print("    PID #"); pw.print(mPidsSelfLocked.keyAt(i));
13941                         pw.print(": "); pw.println(mPidsSelfLocked.valueAt(i));
13942                 }
13943             }
13944         }
13945
13946         if (mForegroundProcesses.size() > 0) {
13947             synchronized (mPidsSelfLocked) {
13948                 boolean printed = false;
13949                 for (int i=0; i<mForegroundProcesses.size(); i++) {
13950                     ProcessRecord r = mPidsSelfLocked.get(
13951                             mForegroundProcesses.valueAt(i).pid);
13952                     if (dumpPackage != null && (r == null
13953                             || !r.pkgList.containsKey(dumpPackage))) {
13954                         continue;
13955                     }
13956                     if (!printed) {
13957                         if (needSep) pw.println();
13958                         needSep = true;
13959                         pw.println("  Foreground Processes:");
13960                         printed = true;
13961                         printedAnything = true;
13962                     }
13963                     pw.print("    PID #"); pw.print(mForegroundProcesses.keyAt(i));
13964                             pw.print(": "); pw.println(mForegroundProcesses.valueAt(i));
13965                 }
13966             }
13967         }
13968
13969         if (mPersistentStartingProcesses.size() > 0) {
13970             if (needSep) pw.println();
13971             needSep = true;
13972             printedAnything = true;
13973             pw.println("  Persisent processes that are starting:");
13974             dumpProcessList(pw, this, mPersistentStartingProcesses, "    ",
13975                     "Starting Norm", "Restarting PERS", dumpPackage);
13976         }
13977
13978         if (mRemovedProcesses.size() > 0) {
13979             if (needSep) pw.println();
13980             needSep = true;
13981             printedAnything = true;
13982             pw.println("  Processes that are being removed:");
13983             dumpProcessList(pw, this, mRemovedProcesses, "    ",
13984                     "Removed Norm", "Removed PERS", dumpPackage);
13985         }
13986
13987         if (mProcessesOnHold.size() > 0) {
13988             if (needSep) pw.println();
13989             needSep = true;
13990             printedAnything = true;
13991             pw.println("  Processes that are on old until the system is ready:");
13992             dumpProcessList(pw, this, mProcessesOnHold, "    ",
13993                     "OnHold Norm", "OnHold PERS", dumpPackage);
13994         }
13995
13996         needSep = dumpProcessesToGc(fd, pw, args, opti, needSep, dumpAll, dumpPackage);
13997
13998         if (mProcessCrashTimes.getMap().size() > 0) {
13999             boolean printed = false;
14000             long now = SystemClock.uptimeMillis();
14001             final ArrayMap<String, SparseArray<Long>> pmap = mProcessCrashTimes.getMap();
14002             final int NP = pmap.size();
14003             for (int ip=0; ip<NP; ip++) {
14004                 String pname = pmap.keyAt(ip);
14005                 SparseArray<Long> uids = pmap.valueAt(ip);
14006                 final int N = uids.size();
14007                 for (int i=0; i<N; i++) {
14008                     int puid = uids.keyAt(i);
14009                     ProcessRecord r = mProcessNames.get(pname, puid);
14010                     if (dumpPackage != null && (r == null
14011                             || !r.pkgList.containsKey(dumpPackage))) {
14012                         continue;
14013                     }
14014                     if (!printed) {
14015                         if (needSep) pw.println();
14016                         needSep = true;
14017                         pw.println("  Time since processes crashed:");
14018                         printed = true;
14019                         printedAnything = true;
14020                     }
14021                     pw.print("    Process "); pw.print(pname);
14022                             pw.print(" uid "); pw.print(puid);
14023                             pw.print(": last crashed ");
14024                             TimeUtils.formatDuration(now-uids.valueAt(i), pw);
14025                             pw.println(" ago");
14026                 }
14027             }
14028         }
14029
14030         if (mBadProcesses.getMap().size() > 0) {
14031             boolean printed = false;
14032             final ArrayMap<String, SparseArray<BadProcessInfo>> pmap = mBadProcesses.getMap();
14033             final int NP = pmap.size();
14034             for (int ip=0; ip<NP; ip++) {
14035                 String pname = pmap.keyAt(ip);
14036                 SparseArray<BadProcessInfo> uids = pmap.valueAt(ip);
14037                 final int N = uids.size();
14038                 for (int i=0; i<N; i++) {
14039                     int puid = uids.keyAt(i);
14040                     ProcessRecord r = mProcessNames.get(pname, puid);
14041                     if (dumpPackage != null && (r == null
14042                             || !r.pkgList.containsKey(dumpPackage))) {
14043                         continue;
14044                     }
14045                     if (!printed) {
14046                         if (needSep) pw.println();
14047                         needSep = true;
14048                         pw.println("  Bad processes:");
14049                         printedAnything = true;
14050                     }
14051                     BadProcessInfo info = uids.valueAt(i);
14052                     pw.print("    Bad process "); pw.print(pname);
14053                             pw.print(" uid "); pw.print(puid);
14054                             pw.print(": crashed at time "); pw.println(info.time);
14055                     if (info.shortMsg != null) {
14056                         pw.print("      Short msg: "); pw.println(info.shortMsg);
14057                     }
14058                     if (info.longMsg != null) {
14059                         pw.print("      Long msg: "); pw.println(info.longMsg);
14060                     }
14061                     if (info.stack != null) {
14062                         pw.println("      Stack:");
14063                         int lastPos = 0;
14064                         for (int pos=0; pos<info.stack.length(); pos++) {
14065                             if (info.stack.charAt(pos) == '\n') {
14066                                 pw.print("        ");
14067                                 pw.write(info.stack, lastPos, pos-lastPos);
14068                                 pw.println();
14069                                 lastPos = pos+1;
14070                             }
14071                         }
14072                         if (lastPos < info.stack.length()) {
14073                             pw.print("        ");
14074                             pw.write(info.stack, lastPos, info.stack.length()-lastPos);
14075                             pw.println();
14076                         }
14077                     }
14078                 }
14079             }
14080         }
14081
14082         if (dumpPackage == null) {
14083             pw.println();
14084             needSep = false;
14085             mUserController.dump(pw, dumpAll);
14086         }
14087         if (mHomeProcess != null && (dumpPackage == null
14088                 || mHomeProcess.pkgList.containsKey(dumpPackage))) {
14089             if (needSep) {
14090                 pw.println();
14091                 needSep = false;
14092             }
14093             pw.println("  mHomeProcess: " + mHomeProcess);
14094         }
14095         if (mPreviousProcess != null && (dumpPackage == null
14096                 || mPreviousProcess.pkgList.containsKey(dumpPackage))) {
14097             if (needSep) {
14098                 pw.println();
14099                 needSep = false;
14100             }
14101             pw.println("  mPreviousProcess: " + mPreviousProcess);
14102         }
14103         if (dumpAll) {
14104             StringBuilder sb = new StringBuilder(128);
14105             sb.append("  mPreviousProcessVisibleTime: ");
14106             TimeUtils.formatDuration(mPreviousProcessVisibleTime, sb);
14107             pw.println(sb);
14108         }
14109         if (mHeavyWeightProcess != null && (dumpPackage == null
14110                 || mHeavyWeightProcess.pkgList.containsKey(dumpPackage))) {
14111             if (needSep) {
14112                 pw.println();
14113                 needSep = false;
14114             }
14115             pw.println("  mHeavyWeightProcess: " + mHeavyWeightProcess);
14116         }
14117         if (dumpPackage == null) {
14118             pw.println("  mConfiguration: " + mConfiguration);
14119         }
14120         if (dumpAll) {
14121             pw.println("  mConfigWillChange: " + getFocusedStack().mConfigWillChange);
14122             if (mCompatModePackages.getPackages().size() > 0) {
14123                 boolean printed = false;
14124                 for (Map.Entry<String, Integer> entry
14125                         : mCompatModePackages.getPackages().entrySet()) {
14126                     String pkg = entry.getKey();
14127                     int mode = entry.getValue();
14128                     if (dumpPackage != null && !dumpPackage.equals(pkg)) {
14129                         continue;
14130                     }
14131                     if (!printed) {
14132                         pw.println("  mScreenCompatPackages:");
14133                         printed = true;
14134                     }
14135                     pw.print("    "); pw.print(pkg); pw.print(": ");
14136                             pw.print(mode); pw.println();
14137                 }
14138             }
14139         }
14140         if (dumpPackage == null) {
14141             pw.println("  mWakefulness="
14142                     + PowerManagerInternal.wakefulnessToString(mWakefulness));
14143             pw.println("  mSleepTokens=" + mSleepTokens);
14144             pw.println("  mSleeping=" + mSleeping + " mLockScreenShown="
14145                     + lockScreenShownToString());
14146             pw.println("  mShuttingDown=" + mShuttingDown + " mTestPssMode=" + mTestPssMode);
14147             if (mRunningVoice != null) {
14148                 pw.println("  mRunningVoice=" + mRunningVoice);
14149                 pw.println("  mVoiceWakeLock" + mVoiceWakeLock);
14150             }
14151         }
14152         if (mDebugApp != null || mOrigDebugApp != null || mDebugTransient
14153                 || mOrigWaitForDebugger) {
14154             if (dumpPackage == null || dumpPackage.equals(mDebugApp)
14155                     || dumpPackage.equals(mOrigDebugApp)) {
14156                 if (needSep) {
14157                     pw.println();
14158                     needSep = false;
14159                 }
14160                 pw.println("  mDebugApp=" + mDebugApp + "/orig=" + mOrigDebugApp
14161                         + " mDebugTransient=" + mDebugTransient
14162                         + " mOrigWaitForDebugger=" + mOrigWaitForDebugger);
14163             }
14164         }
14165         if (mCurAppTimeTracker != null) {
14166             mCurAppTimeTracker.dumpWithHeader(pw, "  ", true);
14167         }
14168         if (mMemWatchProcesses.getMap().size() > 0) {
14169             pw.println("  Mem watch processes:");
14170             final ArrayMap<String, SparseArray<Pair<Long, String>>> procs
14171                     = mMemWatchProcesses.getMap();
14172             for (int i=0; i<procs.size(); i++) {
14173                 final String proc = procs.keyAt(i);
14174                 final SparseArray<Pair<Long, String>> uids = procs.valueAt(i);
14175                 for (int j=0; j<uids.size(); j++) {
14176                     if (needSep) {
14177                         pw.println();
14178                         needSep = false;
14179                     }
14180                     StringBuilder sb = new StringBuilder();
14181                     sb.append("    ").append(proc).append('/');
14182                     UserHandle.formatUid(sb, uids.keyAt(j));
14183                     Pair<Long, String> val = uids.valueAt(j);
14184                     sb.append(": "); DebugUtils.sizeValueToString(val.first, sb);
14185                     if (val.second != null) {
14186                         sb.append(", report to ").append(val.second);
14187                     }
14188                     pw.println(sb.toString());
14189                 }
14190             }
14191             pw.print("  mMemWatchDumpProcName="); pw.println(mMemWatchDumpProcName);
14192             pw.print("  mMemWatchDumpFile="); pw.println(mMemWatchDumpFile);
14193             pw.print("  mMemWatchDumpPid="); pw.print(mMemWatchDumpPid);
14194                     pw.print(" mMemWatchDumpUid="); pw.println(mMemWatchDumpUid);
14195         }
14196         if (mTrackAllocationApp != null) {
14197             if (dumpPackage == null || dumpPackage.equals(mTrackAllocationApp)) {
14198                 if (needSep) {
14199                     pw.println();
14200                     needSep = false;
14201                 }
14202                 pw.println("  mTrackAllocationApp=" + mTrackAllocationApp);
14203             }
14204         }
14205         if (mProfileApp != null || mProfileProc != null || mProfileFile != null
14206                 || mProfileFd != null) {
14207             if (dumpPackage == null || dumpPackage.equals(mProfileApp)) {
14208                 if (needSep) {
14209                     pw.println();
14210                     needSep = false;
14211                 }
14212                 pw.println("  mProfileApp=" + mProfileApp + " mProfileProc=" + mProfileProc);
14213                 pw.println("  mProfileFile=" + mProfileFile + " mProfileFd=" + mProfileFd);
14214                 pw.println("  mSamplingInterval=" + mSamplingInterval + " mAutoStopProfiler="
14215                         + mAutoStopProfiler);
14216                 pw.println("  mProfileType=" + mProfileType);
14217             }
14218         }
14219         if (dumpPackage == null) {
14220             if (mAlwaysFinishActivities || mController != null) {
14221                 pw.println("  mAlwaysFinishActivities=" + mAlwaysFinishActivities
14222                         + " mController=" + mController);
14223             }
14224             if (dumpAll) {
14225                 pw.println("  Total persistent processes: " + numPers);
14226                 pw.println("  mProcessesReady=" + mProcessesReady
14227                         + " mSystemReady=" + mSystemReady
14228                         + " mBooted=" + mBooted
14229                         + " mFactoryTest=" + mFactoryTest);
14230                 pw.println("  mBooting=" + mBooting
14231                         + " mCallFinishBooting=" + mCallFinishBooting
14232                         + " mBootAnimationComplete=" + mBootAnimationComplete);
14233                 pw.print("  mLastPowerCheckRealtime=");
14234                         TimeUtils.formatDuration(mLastPowerCheckRealtime, pw);
14235                         pw.println("");
14236                 pw.print("  mLastPowerCheckUptime=");
14237                         TimeUtils.formatDuration(mLastPowerCheckUptime, pw);
14238                         pw.println("");
14239                 pw.println("  mGoingToSleep=" + mStackSupervisor.mGoingToSleep);
14240                 pw.println("  mLaunchingActivity=" + mStackSupervisor.mLaunchingActivity);
14241                 pw.println("  mAdjSeq=" + mAdjSeq + " mLruSeq=" + mLruSeq);
14242                 pw.println("  mNumNonCachedProcs=" + mNumNonCachedProcs
14243                         + " (" + mLruProcesses.size() + " total)"
14244                         + " mNumCachedHiddenProcs=" + mNumCachedHiddenProcs
14245                         + " mNumServiceProcs=" + mNumServiceProcs
14246                         + " mNewNumServiceProcs=" + mNewNumServiceProcs);
14247                 pw.println("  mAllowLowerMemLevel=" + mAllowLowerMemLevel
14248                         + " mLastMemoryLevel" + mLastMemoryLevel
14249                         + " mLastNumProcesses" + mLastNumProcesses);
14250                 long now = SystemClock.uptimeMillis();
14251                 pw.print("  mLastIdleTime=");
14252                         TimeUtils.formatDuration(now, mLastIdleTime, pw);
14253                         pw.print(" mLowRamSinceLastIdle=");
14254                         TimeUtils.formatDuration(getLowRamTimeSinceIdle(now), pw);
14255                         pw.println();
14256             }
14257         }
14258
14259         if (!printedAnything) {
14260             pw.println("  (nothing)");
14261         }
14262     }
14263
14264     boolean dumpProcessesToGc(FileDescriptor fd, PrintWriter pw, String[] args,
14265             int opti, boolean needSep, boolean dumpAll, String dumpPackage) {
14266         if (mProcessesToGc.size() > 0) {
14267             boolean printed = false;
14268             long now = SystemClock.uptimeMillis();
14269             for (int i=0; i<mProcessesToGc.size(); i++) {
14270                 ProcessRecord proc = mProcessesToGc.get(i);
14271                 if (dumpPackage != null && !dumpPackage.equals(proc.info.packageName)) {
14272                     continue;
14273                 }
14274                 if (!printed) {
14275                     if (needSep) pw.println();
14276                     needSep = true;
14277                     pw.println("  Processes that are waiting to GC:");
14278                     printed = true;
14279                 }
14280                 pw.print("    Process "); pw.println(proc);
14281                 pw.print("      lowMem="); pw.print(proc.reportLowMemory);
14282                         pw.print(", last gced=");
14283                         pw.print(now-proc.lastRequestedGc);
14284                         pw.print(" ms ago, last lowMem=");
14285                         pw.print(now-proc.lastLowMemory);
14286                         pw.println(" ms ago");
14287
14288             }
14289         }
14290         return needSep;
14291     }
14292
14293     void printOomLevel(PrintWriter pw, String name, int adj) {
14294         pw.print("    ");
14295         if (adj >= 0) {
14296             pw.print(' ');
14297             if (adj < 10) pw.print(' ');
14298         } else {
14299             if (adj > -10) pw.print(' ');
14300         }
14301         pw.print(adj);
14302         pw.print(": ");
14303         pw.print(name);
14304         pw.print(" (");
14305         pw.print(stringifySize(mProcessList.getMemLevel(adj), 1024));
14306         pw.println(")");
14307     }
14308
14309     boolean dumpOomLocked(FileDescriptor fd, PrintWriter pw, String[] args,
14310             int opti, boolean dumpAll) {
14311         boolean needSep = false;
14312
14313         if (mLruProcesses.size() > 0) {
14314             if (needSep) pw.println();
14315             needSep = true;
14316             pw.println("  OOM levels:");
14317             printOomLevel(pw, "SYSTEM_ADJ", ProcessList.SYSTEM_ADJ);
14318             printOomLevel(pw, "PERSISTENT_PROC_ADJ", ProcessList.PERSISTENT_PROC_ADJ);
14319             printOomLevel(pw, "PERSISTENT_SERVICE_ADJ", ProcessList.PERSISTENT_SERVICE_ADJ);
14320             printOomLevel(pw, "FOREGROUND_APP_ADJ", ProcessList.FOREGROUND_APP_ADJ);
14321             printOomLevel(pw, "VISIBLE_APP_ADJ", ProcessList.VISIBLE_APP_ADJ);
14322             printOomLevel(pw, "PERCEPTIBLE_APP_ADJ", ProcessList.PERCEPTIBLE_APP_ADJ);
14323             printOomLevel(pw, "BACKUP_APP_ADJ", ProcessList.BACKUP_APP_ADJ);
14324             printOomLevel(pw, "HEAVY_WEIGHT_APP_ADJ", ProcessList.HEAVY_WEIGHT_APP_ADJ);
14325             printOomLevel(pw, "SERVICE_ADJ", ProcessList.SERVICE_ADJ);
14326             printOomLevel(pw, "HOME_APP_ADJ", ProcessList.HOME_APP_ADJ);
14327             printOomLevel(pw, "PREVIOUS_APP_ADJ", ProcessList.PREVIOUS_APP_ADJ);
14328             printOomLevel(pw, "SERVICE_B_ADJ", ProcessList.SERVICE_B_ADJ);
14329             printOomLevel(pw, "CACHED_APP_MIN_ADJ", ProcessList.CACHED_APP_MIN_ADJ);
14330             printOomLevel(pw, "CACHED_APP_MAX_ADJ", ProcessList.CACHED_APP_MAX_ADJ);
14331
14332             if (needSep) pw.println();
14333             pw.print("  Process OOM control ("); pw.print(mLruProcesses.size());
14334                     pw.print(" total, non-act at ");
14335                     pw.print(mLruProcesses.size()-mLruProcessActivityStart);
14336                     pw.print(", non-svc at ");
14337                     pw.print(mLruProcesses.size()-mLruProcessServiceStart);
14338                     pw.println("):");
14339             dumpProcessOomList(pw, this, mLruProcesses, "    ", "Proc", "PERS", true, null);
14340             needSep = true;
14341         }
14342
14343         dumpProcessesToGc(fd, pw, args, opti, needSep, dumpAll, null);
14344
14345         pw.println();
14346         pw.println("  mHomeProcess: " + mHomeProcess);
14347         pw.println("  mPreviousProcess: " + mPreviousProcess);
14348         if (mHeavyWeightProcess != null) {
14349             pw.println("  mHeavyWeightProcess: " + mHeavyWeightProcess);
14350         }
14351
14352         return true;
14353     }
14354
14355     /**
14356      * There are three ways to call this:
14357      *  - no provider specified: dump all the providers
14358      *  - a flattened component name that matched an existing provider was specified as the
14359      *    first arg: dump that one provider
14360      *  - the first arg isn't the flattened component name of an existing provider:
14361      *    dump all providers whose component contains the first arg as a substring
14362      */
14363     protected boolean dumpProvider(FileDescriptor fd, PrintWriter pw, String name, String[] args,
14364             int opti, boolean dumpAll) {
14365         return mProviderMap.dumpProvider(fd, pw, name, args, opti, dumpAll);
14366     }
14367
14368     static class ItemMatcher {
14369         ArrayList<ComponentName> components;
14370         ArrayList<String> strings;
14371         ArrayList<Integer> objects;
14372         boolean all;
14373
14374         ItemMatcher() {
14375             all = true;
14376         }
14377
14378         void build(String name) {
14379             ComponentName componentName = ComponentName.unflattenFromString(name);
14380             if (componentName != null) {
14381                 if (components == null) {
14382                     components = new ArrayList<ComponentName>();
14383                 }
14384                 components.add(componentName);
14385                 all = false;
14386             } else {
14387                 int objectId = 0;
14388                 // Not a '/' separated full component name; maybe an object ID?
14389                 try {
14390                     objectId = Integer.parseInt(name, 16);
14391                     if (objects == null) {
14392                         objects = new ArrayList<Integer>();
14393                     }
14394                     objects.add(objectId);
14395                     all = false;
14396                 } catch (RuntimeException e) {
14397                     // Not an integer; just do string match.
14398                     if (strings == null) {
14399                         strings = new ArrayList<String>();
14400                     }
14401                     strings.add(name);
14402                     all = false;
14403                 }
14404             }
14405         }
14406
14407         int build(String[] args, int opti) {
14408             for (; opti<args.length; opti++) {
14409                 String name = args[opti];
14410                 if ("--".equals(name)) {
14411                     return opti+1;
14412                 }
14413                 build(name);
14414             }
14415             return opti;
14416         }
14417
14418         boolean match(Object object, ComponentName comp) {
14419             if (all) {
14420                 return true;
14421             }
14422             if (components != null) {
14423                 for (int i=0; i<components.size(); i++) {
14424                     if (components.get(i).equals(comp)) {
14425                         return true;
14426                     }
14427                 }
14428             }
14429             if (objects != null) {
14430                 for (int i=0; i<objects.size(); i++) {
14431                     if (System.identityHashCode(object) == objects.get(i)) {
14432                         return true;
14433                     }
14434                 }
14435             }
14436             if (strings != null) {
14437                 String flat = comp.flattenToString();
14438                 for (int i=0; i<strings.size(); i++) {
14439                     if (flat.contains(strings.get(i))) {
14440                         return true;
14441                     }
14442                 }
14443             }
14444             return false;
14445         }
14446     }
14447
14448     /**
14449      * There are three things that cmd can be:
14450      *  - a flattened component name that matches an existing activity
14451      *  - the cmd arg isn't the flattened component name of an existing activity:
14452      *    dump all activity whose component contains the cmd as a substring
14453      *  - A hex number of the ActivityRecord object instance.
14454      */
14455     protected boolean dumpActivity(FileDescriptor fd, PrintWriter pw, String name, String[] args,
14456             int opti, boolean dumpAll) {
14457         ArrayList<ActivityRecord> activities;
14458
14459         synchronized (this) {
14460             activities = mStackSupervisor.getDumpActivitiesLocked(name);
14461         }
14462
14463         if (activities.size() <= 0) {
14464             return false;
14465         }
14466
14467         String[] newArgs = new String[args.length - opti];
14468         System.arraycopy(args, opti, newArgs, 0, args.length - opti);
14469
14470         TaskRecord lastTask = null;
14471         boolean needSep = false;
14472         for (int i=activities.size()-1; i>=0; i--) {
14473             ActivityRecord r = activities.get(i);
14474             if (needSep) {
14475                 pw.println();
14476             }
14477             needSep = true;
14478             synchronized (this) {
14479                 if (lastTask != r.task) {
14480                     lastTask = r.task;
14481                     pw.print("TASK "); pw.print(lastTask.affinity);
14482                             pw.print(" id="); pw.println(lastTask.taskId);
14483                     if (dumpAll) {
14484                         lastTask.dump(pw, "  ");
14485                     }
14486                 }
14487             }
14488             dumpActivity("  ", fd, pw, activities.get(i), newArgs, dumpAll);
14489         }
14490         return true;
14491     }
14492
14493     /**
14494      * Invokes IApplicationThread.dumpActivity() on the thread of the specified activity if
14495      * there is a thread associated with the activity.
14496      */
14497     private void dumpActivity(String prefix, FileDescriptor fd, PrintWriter pw,
14498             final ActivityRecord r, String[] args, boolean dumpAll) {
14499         String innerPrefix = prefix + "  ";
14500         synchronized (this) {
14501             pw.print(prefix); pw.print("ACTIVITY "); pw.print(r.shortComponentName);
14502                     pw.print(" "); pw.print(Integer.toHexString(System.identityHashCode(r)));
14503                     pw.print(" pid=");
14504                     if (r.app != null) pw.println(r.app.pid);
14505                     else pw.println("(not running)");
14506             if (dumpAll) {
14507                 r.dump(pw, innerPrefix);
14508             }
14509         }
14510         if (r.app != null && r.app.thread != null) {
14511             // flush anything that is already in the PrintWriter since the thread is going
14512             // to write to the file descriptor directly
14513             pw.flush();
14514             try {
14515                 TransferPipe tp = new TransferPipe();
14516                 try {
14517                     r.app.thread.dumpActivity(tp.getWriteFd().getFileDescriptor(),
14518                             r.appToken, innerPrefix, args);
14519                     tp.go(fd);
14520                 } finally {
14521                     tp.kill();
14522                 }
14523             } catch (IOException e) {
14524                 pw.println(innerPrefix + "Failure while dumping the activity: " + e);
14525             } catch (RemoteException e) {
14526                 pw.println(innerPrefix + "Got a RemoteException while dumping the activity");
14527             }
14528         }
14529     }
14530
14531     void dumpBroadcastsLocked(FileDescriptor fd, PrintWriter pw, String[] args,
14532             int opti, boolean dumpAll, String dumpPackage) {
14533         boolean needSep = false;
14534         boolean onlyHistory = false;
14535         boolean printedAnything = false;
14536
14537         if ("history".equals(dumpPackage)) {
14538             if (opti < args.length && "-s".equals(args[opti])) {
14539                 dumpAll = false;
14540             }
14541             onlyHistory = true;
14542             dumpPackage = null;
14543         }
14544
14545         pw.println("ACTIVITY MANAGER BROADCAST STATE (dumpsys activity broadcasts)");
14546         if (!onlyHistory && dumpAll) {
14547             if (mRegisteredReceivers.size() > 0) {
14548                 boolean printed = false;
14549                 Iterator it = mRegisteredReceivers.values().iterator();
14550                 while (it.hasNext()) {
14551                     ReceiverList r = (ReceiverList)it.next();
14552                     if (dumpPackage != null && (r.app == null ||
14553                             !dumpPackage.equals(r.app.info.packageName))) {
14554                         continue;
14555                     }
14556                     if (!printed) {
14557                         pw.println("  Registered Receivers:");
14558                         needSep = true;
14559                         printed = true;
14560                         printedAnything = true;
14561                     }
14562                     pw.print("  * "); pw.println(r);
14563                     r.dump(pw, "    ");
14564                 }
14565             }
14566
14567             if (mReceiverResolver.dump(pw, needSep ?
14568                     "\n  Receiver Resolver Table:" : "  Receiver Resolver Table:",
14569                     "    ", dumpPackage, false, false)) {
14570                 needSep = true;
14571                 printedAnything = true;
14572             }
14573         }
14574
14575         for (BroadcastQueue q : mBroadcastQueues) {
14576             needSep = q.dumpLocked(fd, pw, args, opti, dumpAll, dumpPackage, needSep);
14577             printedAnything |= needSep;
14578         }
14579
14580         needSep = true;
14581
14582         if (!onlyHistory && mStickyBroadcasts != null && dumpPackage == null) {
14583             for (int user=0; user<mStickyBroadcasts.size(); user++) {
14584                 if (needSep) {
14585                     pw.println();
14586                 }
14587                 needSep = true;
14588                 printedAnything = true;
14589                 pw.print("  Sticky broadcasts for user ");
14590                         pw.print(mStickyBroadcasts.keyAt(user)); pw.println(":");
14591                 StringBuilder sb = new StringBuilder(128);
14592                 for (Map.Entry<String, ArrayList<Intent>> ent
14593                         : mStickyBroadcasts.valueAt(user).entrySet()) {
14594                     pw.print("  * Sticky action "); pw.print(ent.getKey());
14595                     if (dumpAll) {
14596                         pw.println(":");
14597                         ArrayList<Intent> intents = ent.getValue();
14598                         final int N = intents.size();
14599                         for (int i=0; i<N; i++) {
14600                             sb.setLength(0);
14601                             sb.append("    Intent: ");
14602                             intents.get(i).toShortString(sb, false, true, false, false);
14603                             pw.println(sb.toString());
14604                             Bundle bundle = intents.get(i).getExtras();
14605                             if (bundle != null) {
14606                                 pw.print("      ");
14607                                 pw.println(bundle.toString());
14608                             }
14609                         }
14610                     } else {
14611                         pw.println("");
14612                     }
14613                 }
14614             }
14615         }
14616
14617         if (!onlyHistory && dumpAll) {
14618             pw.println();
14619             for (BroadcastQueue queue : mBroadcastQueues) {
14620                 pw.println("  mBroadcastsScheduled [" + queue.mQueueName + "]="
14621                         + queue.mBroadcastsScheduled);
14622             }
14623             pw.println("  mHandler:");
14624             mHandler.dump(new PrintWriterPrinter(pw), "    ");
14625             needSep = true;
14626             printedAnything = true;
14627         }
14628
14629         if (!printedAnything) {
14630             pw.println("  (nothing)");
14631         }
14632     }
14633
14634     void dumpProvidersLocked(FileDescriptor fd, PrintWriter pw, String[] args,
14635             int opti, boolean dumpAll, String dumpPackage) {
14636         boolean needSep;
14637         boolean printedAnything = false;
14638
14639         ItemMatcher matcher = new ItemMatcher();
14640         matcher.build(args, opti);
14641
14642         pw.println("ACTIVITY MANAGER CONTENT PROVIDERS (dumpsys activity providers)");
14643
14644         needSep = mProviderMap.dumpProvidersLocked(pw, dumpAll, dumpPackage);
14645         printedAnything |= needSep;
14646
14647         if (mLaunchingProviders.size() > 0) {
14648             boolean printed = false;
14649             for (int i=mLaunchingProviders.size()-1; i>=0; i--) {
14650                 ContentProviderRecord r = mLaunchingProviders.get(i);
14651                 if (dumpPackage != null && !dumpPackage.equals(r.name.getPackageName())) {
14652                     continue;
14653                 }
14654                 if (!printed) {
14655                     if (needSep) pw.println();
14656                     needSep = true;
14657                     pw.println("  Launching content providers:");
14658                     printed = true;
14659                     printedAnything = true;
14660                 }
14661                 pw.print("  Launching #"); pw.print(i); pw.print(": ");
14662                         pw.println(r);
14663             }
14664         }
14665
14666         if (!printedAnything) {
14667             pw.println("  (nothing)");
14668         }
14669     }
14670
14671     void dumpPermissionsLocked(FileDescriptor fd, PrintWriter pw, String[] args,
14672             int opti, boolean dumpAll, String dumpPackage) {
14673         boolean needSep = false;
14674         boolean printedAnything = false;
14675
14676         pw.println("ACTIVITY MANAGER URI PERMISSIONS (dumpsys activity permissions)");
14677
14678         if (mGrantedUriPermissions.size() > 0) {
14679             boolean printed = false;
14680             int dumpUid = -2;
14681             if (dumpPackage != null) {
14682                 try {
14683                     dumpUid = mContext.getPackageManager().getPackageUid(dumpPackage, 0);
14684                 } catch (NameNotFoundException e) {
14685                     dumpUid = -1;
14686                 }
14687             }
14688             for (int i=0; i<mGrantedUriPermissions.size(); i++) {
14689                 int uid = mGrantedUriPermissions.keyAt(i);
14690                 if (dumpUid >= -1 && UserHandle.getAppId(uid) != dumpUid) {
14691                     continue;
14692                 }
14693                 final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.valueAt(i);
14694                 if (!printed) {
14695                     if (needSep) pw.println();
14696                     needSep = true;
14697                     pw.println("  Granted Uri Permissions:");
14698                     printed = true;
14699                     printedAnything = true;
14700                 }
14701                 pw.print("  * UID "); pw.print(uid); pw.println(" holds:");
14702                 for (UriPermission perm : perms.values()) {
14703                     pw.print("    "); pw.println(perm);
14704                     if (dumpAll) {
14705                         perm.dump(pw, "      ");
14706                     }
14707                 }
14708             }
14709         }
14710
14711         if (!printedAnything) {
14712             pw.println("  (nothing)");
14713         }
14714     }
14715
14716     void dumpPendingIntentsLocked(FileDescriptor fd, PrintWriter pw, String[] args,
14717             int opti, boolean dumpAll, String dumpPackage) {
14718         boolean printed = false;
14719
14720         pw.println("ACTIVITY MANAGER PENDING INTENTS (dumpsys activity intents)");
14721
14722         if (mIntentSenderRecords.size() > 0) {
14723             Iterator<WeakReference<PendingIntentRecord>> it
14724                     = mIntentSenderRecords.values().iterator();
14725             while (it.hasNext()) {
14726                 WeakReference<PendingIntentRecord> ref = it.next();
14727                 PendingIntentRecord rec = ref != null ? ref.get(): null;
14728                 if (dumpPackage != null && (rec == null
14729                         || !dumpPackage.equals(rec.key.packageName))) {
14730                     continue;
14731                 }
14732                 printed = true;
14733                 if (rec != null) {
14734                     pw.print("  * "); pw.println(rec);
14735                     if (dumpAll) {
14736                         rec.dump(pw, "    ");
14737                     }
14738                 } else {
14739                     pw.print("  * "); pw.println(ref);
14740                 }
14741             }
14742         }
14743
14744         if (!printed) {
14745             pw.println("  (nothing)");
14746         }
14747     }
14748
14749     private static final int dumpProcessList(PrintWriter pw,
14750             ActivityManagerService service, List list,
14751             String prefix, String normalLabel, String persistentLabel,
14752             String dumpPackage) {
14753         int numPers = 0;
14754         final int N = list.size()-1;
14755         for (int i=N; i>=0; i--) {
14756             ProcessRecord r = (ProcessRecord)list.get(i);
14757             if (dumpPackage != null && !dumpPackage.equals(r.info.packageName)) {
14758                 continue;
14759             }
14760             pw.println(String.format("%s%s #%2d: %s",
14761                     prefix, (r.persistent ? persistentLabel : normalLabel),
14762                     i, r.toString()));
14763             if (r.persistent) {
14764                 numPers++;
14765             }
14766         }
14767         return numPers;
14768     }
14769
14770     private static final boolean dumpProcessOomList(PrintWriter pw,
14771             ActivityManagerService service, List<ProcessRecord> origList,
14772             String prefix, String normalLabel, String persistentLabel,
14773             boolean inclDetails, String dumpPackage) {
14774
14775         ArrayList<Pair<ProcessRecord, Integer>> list
14776                 = new ArrayList<Pair<ProcessRecord, Integer>>(origList.size());
14777         for (int i=0; i<origList.size(); i++) {
14778             ProcessRecord r = origList.get(i);
14779             if (dumpPackage != null && !r.pkgList.containsKey(dumpPackage)) {
14780                 continue;
14781             }
14782             list.add(new Pair<ProcessRecord, Integer>(origList.get(i), i));
14783         }
14784
14785         if (list.size() <= 0) {
14786             return false;
14787         }
14788
14789         Comparator<Pair<ProcessRecord, Integer>> comparator
14790                 = new Comparator<Pair<ProcessRecord, Integer>>() {
14791             @Override
14792             public int compare(Pair<ProcessRecord, Integer> object1,
14793                     Pair<ProcessRecord, Integer> object2) {
14794                 if (object1.first.setAdj != object2.first.setAdj) {
14795                     return object1.first.setAdj > object2.first.setAdj ? -1 : 1;
14796                 }
14797                 if (object1.first.setProcState != object2.first.setProcState) {
14798                     return object1.first.setProcState > object2.first.setProcState ? -1 : 1;
14799                 }
14800                 if (object1.second.intValue() != object2.second.intValue()) {
14801                     return object1.second.intValue() > object2.second.intValue() ? -1 : 1;
14802                 }
14803                 return 0;
14804             }
14805         };
14806
14807         Collections.sort(list, comparator);
14808
14809         final long curRealtime = SystemClock.elapsedRealtime();
14810         final long realtimeSince = curRealtime - service.mLastPowerCheckRealtime;
14811         final long curUptime = SystemClock.uptimeMillis();
14812         final long uptimeSince = curUptime - service.mLastPowerCheckUptime;
14813
14814         for (int i=list.size()-1; i>=0; i--) {
14815             ProcessRecord r = list.get(i).first;
14816             String oomAdj = ProcessList.makeOomAdjString(r.setAdj);
14817             char schedGroup;
14818             switch (r.setSchedGroup) {
14819                 case Process.THREAD_GROUP_BG_NONINTERACTIVE:
14820                     schedGroup = 'B';
14821                     break;
14822                 case Process.THREAD_GROUP_DEFAULT:
14823                     schedGroup = 'F';
14824                     break;
14825                 default:
14826                     schedGroup = '?';
14827                     break;
14828             }
14829             char foreground;
14830             if (r.foregroundActivities) {
14831                 foreground = 'A';
14832             } else if (r.foregroundServices) {
14833                 foreground = 'S';
14834             } else {
14835                 foreground = ' ';
14836             }
14837             String procState = ProcessList.makeProcStateString(r.curProcState);
14838             pw.print(prefix);
14839             pw.print(r.persistent ? persistentLabel : normalLabel);
14840             pw.print(" #");
14841             int num = (origList.size()-1)-list.get(i).second;
14842             if (num < 10) pw.print(' ');
14843             pw.print(num);
14844             pw.print(": ");
14845             pw.print(oomAdj);
14846             pw.print(' ');
14847             pw.print(schedGroup);
14848             pw.print('/');
14849             pw.print(foreground);
14850             pw.print('/');
14851             pw.print(procState);
14852             pw.print(" trm:");
14853             if (r.trimMemoryLevel < 10) pw.print(' ');
14854             pw.print(r.trimMemoryLevel);
14855             pw.print(' ');
14856             pw.print(r.toShortString());
14857             pw.print(" (");
14858             pw.print(r.adjType);
14859             pw.println(')');
14860             if (r.adjSource != null || r.adjTarget != null) {
14861                 pw.print(prefix);
14862                 pw.print("    ");
14863                 if (r.adjTarget instanceof ComponentName) {
14864                     pw.print(((ComponentName)r.adjTarget).flattenToShortString());
14865                 } else if (r.adjTarget != null) {
14866                     pw.print(r.adjTarget.toString());
14867                 } else {
14868                     pw.print("{null}");
14869                 }
14870                 pw.print("<=");
14871                 if (r.adjSource instanceof ProcessRecord) {
14872                     pw.print("Proc{");
14873                     pw.print(((ProcessRecord)r.adjSource).toShortString());
14874                     pw.println("}");
14875                 } else if (r.adjSource != null) {
14876                     pw.println(r.adjSource.toString());
14877                 } else {
14878                     pw.println("{null}");
14879                 }
14880             }
14881             if (inclDetails) {
14882                 pw.print(prefix);
14883                 pw.print("    ");
14884                 pw.print("oom: max="); pw.print(r.maxAdj);
14885                 pw.print(" curRaw="); pw.print(r.curRawAdj);
14886                 pw.print(" setRaw="); pw.print(r.setRawAdj);
14887                 pw.print(" cur="); pw.print(r.curAdj);
14888                 pw.print(" set="); pw.println(r.setAdj);
14889                 pw.print(prefix);
14890                 pw.print("    ");
14891                 pw.print("state: cur="); pw.print(ProcessList.makeProcStateString(r.curProcState));
14892                 pw.print(" set="); pw.print(ProcessList.makeProcStateString(r.setProcState));
14893                 pw.print(" lastPss="); DebugUtils.printSizeValue(pw, r.lastPss*1024);
14894                 pw.print(" lastCachedPss="); DebugUtils.printSizeValue(pw, r.lastCachedPss*1024);
14895                 pw.println();
14896                 pw.print(prefix);
14897                 pw.print("    ");
14898                 pw.print("cached="); pw.print(r.cached);
14899                 pw.print(" empty="); pw.print(r.empty);
14900                 pw.print(" hasAboveClient="); pw.println(r.hasAboveClient);
14901
14902                 if (r.setProcState >= ActivityManager.PROCESS_STATE_SERVICE) {
14903                     if (r.lastWakeTime != 0) {
14904                         long wtime;
14905                         BatteryStatsImpl stats = service.mBatteryStatsService.getActiveStatistics();
14906                         synchronized (stats) {
14907                             wtime = stats.getProcessWakeTime(r.info.uid,
14908                                     r.pid, curRealtime);
14909                         }
14910                         long timeUsed = wtime - r.lastWakeTime;
14911                         pw.print(prefix);
14912                         pw.print("    ");
14913                         pw.print("keep awake over ");
14914                         TimeUtils.formatDuration(realtimeSince, pw);
14915                         pw.print(" used ");
14916                         TimeUtils.formatDuration(timeUsed, pw);
14917                         pw.print(" (");
14918                         pw.print((timeUsed*100)/realtimeSince);
14919                         pw.println("%)");
14920                     }
14921                     if (r.lastCpuTime != 0) {
14922                         long timeUsed = r.curCpuTime - r.lastCpuTime;
14923                         pw.print(prefix);
14924                         pw.print("    ");
14925                         pw.print("run cpu over ");
14926                         TimeUtils.formatDuration(uptimeSince, pw);
14927                         pw.print(" used ");
14928                         TimeUtils.formatDuration(timeUsed, pw);
14929                         pw.print(" (");
14930                         pw.print((timeUsed*100)/uptimeSince);
14931                         pw.println("%)");
14932                     }
14933                 }
14934             }
14935         }
14936         return true;
14937     }
14938
14939     ArrayList<ProcessRecord> collectProcesses(PrintWriter pw, int start, boolean allPkgs,
14940             String[] args) {
14941         ArrayList<ProcessRecord> procs;
14942         synchronized (this) {
14943             if (args != null && args.length > start
14944                     && args[start].charAt(0) != '-') {
14945                 procs = new ArrayList<ProcessRecord>();
14946                 int pid = -1;
14947                 try {
14948                     pid = Integer.parseInt(args[start]);
14949                 } catch (NumberFormatException e) {
14950                 }
14951                 for (int i=mLruProcesses.size()-1; i>=0; i--) {
14952                     ProcessRecord proc = mLruProcesses.get(i);
14953                     if (proc.pid == pid) {
14954                         procs.add(proc);
14955                     } else if (allPkgs && proc.pkgList != null
14956                             && proc.pkgList.containsKey(args[start])) {
14957                         procs.add(proc);
14958                     } else if (proc.processName.equals(args[start])) {
14959                         procs.add(proc);
14960                     }
14961                 }
14962                 if (procs.size() <= 0) {
14963                     return null;
14964                 }
14965             } else {
14966                 procs = new ArrayList<ProcessRecord>(mLruProcesses);
14967             }
14968         }
14969         return procs;
14970     }
14971
14972     final void dumpGraphicsHardwareUsage(FileDescriptor fd,
14973             PrintWriter pw, String[] args) {
14974         ArrayList<ProcessRecord> procs = collectProcesses(pw, 0, false, args);
14975         if (procs == null) {
14976             pw.println("No process found for: " + args[0]);
14977             return;
14978         }
14979
14980         long uptime = SystemClock.uptimeMillis();
14981         long realtime = SystemClock.elapsedRealtime();
14982         pw.println("Applications Graphics Acceleration Info:");
14983         pw.println("Uptime: " + uptime + " Realtime: " + realtime);
14984
14985         for (int i = procs.size() - 1 ; i >= 0 ; i--) {
14986             ProcessRecord r = procs.get(i);
14987             if (r.thread != null) {
14988                 pw.println("\n** Graphics info for pid " + r.pid + " [" + r.processName + "] **");
14989                 pw.flush();
14990                 try {
14991                     TransferPipe tp = new TransferPipe();
14992                     try {
14993                         r.thread.dumpGfxInfo(tp.getWriteFd().getFileDescriptor(), args);
14994                         tp.go(fd);
14995                     } finally {
14996                         tp.kill();
14997                     }
14998                 } catch (IOException e) {
14999                     pw.println("Failure while dumping the app: " + r);
15000                     pw.flush();
15001                 } catch (RemoteException e) {
15002                     pw.println("Got a RemoteException while dumping the app " + r);
15003                     pw.flush();
15004                 }
15005             }
15006         }
15007     }
15008
15009     final void dumpDbInfo(FileDescriptor fd, PrintWriter pw, String[] args) {
15010         ArrayList<ProcessRecord> procs = collectProcesses(pw, 0, false, args);
15011         if (procs == null) {
15012             pw.println("No process found for: " + args[0]);
15013             return;
15014         }
15015
15016         pw.println("Applications Database Info:");
15017
15018         for (int i = procs.size() - 1 ; i >= 0 ; i--) {
15019             ProcessRecord r = procs.get(i);
15020             if (r.thread != null) {
15021                 pw.println("\n** Database info for pid " + r.pid + " [" + r.processName + "] **");
15022                 pw.flush();
15023                 try {
15024                     TransferPipe tp = new TransferPipe();
15025                     try {
15026                         r.thread.dumpDbInfo(tp.getWriteFd().getFileDescriptor(), args);
15027                         tp.go(fd);
15028                     } finally {
15029                         tp.kill();
15030                     }
15031                 } catch (IOException e) {
15032                     pw.println("Failure while dumping the app: " + r);
15033                     pw.flush();
15034                 } catch (RemoteException e) {
15035                     pw.println("Got a RemoteException while dumping the app " + r);
15036                     pw.flush();
15037                 }
15038             }
15039         }
15040     }
15041
15042     final static class MemItem {
15043         final boolean isProc;
15044         final String label;
15045         final String shortLabel;
15046         final long pss;
15047         final int id;
15048         final boolean hasActivities;
15049         ArrayList<MemItem> subitems;
15050
15051         public MemItem(String _label, String _shortLabel, long _pss, int _id,
15052                 boolean _hasActivities) {
15053             isProc = true;
15054             label = _label;
15055             shortLabel = _shortLabel;
15056             pss = _pss;
15057             id = _id;
15058             hasActivities = _hasActivities;
15059         }
15060
15061         public MemItem(String _label, String _shortLabel, long _pss, int _id) {
15062             isProc = false;
15063             label = _label;
15064             shortLabel = _shortLabel;
15065             pss = _pss;
15066             id = _id;
15067             hasActivities = false;
15068         }
15069     }
15070
15071     static final void dumpMemItems(PrintWriter pw, String prefix, String tag,
15072             ArrayList<MemItem> items, boolean sort, boolean isCompact) {
15073         if (sort && !isCompact) {
15074             Collections.sort(items, new Comparator<MemItem>() {
15075                 @Override
15076                 public int compare(MemItem lhs, MemItem rhs) {
15077                     if (lhs.pss < rhs.pss) {
15078                         return 1;
15079                     } else if (lhs.pss > rhs.pss) {
15080                         return -1;
15081                     }
15082                     return 0;
15083                 }
15084             });
15085         }
15086
15087         for (int i=0; i<items.size(); i++) {
15088             MemItem mi = items.get(i);
15089             if (!isCompact) {
15090                 pw.printf("%s%s: %s\n", prefix, stringifyKBSize(mi.pss), mi.label);
15091             } else if (mi.isProc) {
15092                 pw.print("proc,"); pw.print(tag); pw.print(","); pw.print(mi.shortLabel);
15093                 pw.print(","); pw.print(mi.id); pw.print(","); pw.print(mi.pss);
15094                 pw.println(mi.hasActivities ? ",a" : ",e");
15095             } else {
15096                 pw.print(tag); pw.print(","); pw.print(mi.shortLabel); pw.print(",");
15097                 pw.println(mi.pss);
15098             }
15099             if (mi.subitems != null) {
15100                 dumpMemItems(pw, prefix + "           ", mi.shortLabel, mi.subitems,
15101                         true, isCompact);
15102             }
15103         }
15104     }
15105
15106     // These are in KB.
15107     static final long[] DUMP_MEM_BUCKETS = new long[] {
15108         5*1024, 7*1024, 10*1024, 15*1024, 20*1024, 30*1024, 40*1024, 80*1024,
15109         120*1024, 160*1024, 200*1024,
15110         250*1024, 300*1024, 350*1024, 400*1024, 500*1024, 600*1024, 800*1024,
15111         1*1024*1024, 2*1024*1024, 5*1024*1024, 10*1024*1024, 20*1024*1024
15112     };
15113
15114     static final void appendMemBucket(StringBuilder out, long memKB, String label,
15115             boolean stackLike) {
15116         int start = label.lastIndexOf('.');
15117         if (start >= 0) start++;
15118         else start = 0;
15119         int end = label.length();
15120         for (int i=0; i<DUMP_MEM_BUCKETS.length; i++) {
15121             if (DUMP_MEM_BUCKETS[i] >= memKB) {
15122                 long bucket = DUMP_MEM_BUCKETS[i]/1024;
15123                 out.append(bucket);
15124                 out.append(stackLike ? "MB." : "MB ");
15125                 out.append(label, start, end);
15126                 return;
15127             }
15128         }
15129         out.append(memKB/1024);
15130         out.append(stackLike ? "MB." : "MB ");
15131         out.append(label, start, end);
15132     }
15133
15134     static final int[] DUMP_MEM_OOM_ADJ = new int[] {
15135             ProcessList.NATIVE_ADJ,
15136             ProcessList.SYSTEM_ADJ, ProcessList.PERSISTENT_PROC_ADJ,
15137             ProcessList.PERSISTENT_SERVICE_ADJ, ProcessList.FOREGROUND_APP_ADJ,
15138             ProcessList.VISIBLE_APP_ADJ, ProcessList.PERCEPTIBLE_APP_ADJ,
15139             ProcessList.BACKUP_APP_ADJ, ProcessList.HEAVY_WEIGHT_APP_ADJ,
15140             ProcessList.SERVICE_ADJ, ProcessList.HOME_APP_ADJ,
15141             ProcessList.PREVIOUS_APP_ADJ, ProcessList.SERVICE_B_ADJ, ProcessList.CACHED_APP_MAX_ADJ
15142     };
15143     static final String[] DUMP_MEM_OOM_LABEL = new String[] {
15144             "Native",
15145             "System", "Persistent", "Persistent Service", "Foreground",
15146             "Visible", "Perceptible",
15147             "Heavy Weight", "Backup",
15148             "A Services", "Home",
15149             "Previous", "B Services", "Cached"
15150     };
15151     static final String[] DUMP_MEM_OOM_COMPACT_LABEL = new String[] {
15152             "native",
15153             "sys", "pers", "persvc", "fore",
15154             "vis", "percept",
15155             "heavy", "backup",
15156             "servicea", "home",
15157             "prev", "serviceb", "cached"
15158     };
15159
15160     private final void dumpApplicationMemoryUsageHeader(PrintWriter pw, long uptime,
15161             long realtime, boolean isCheckinRequest, boolean isCompact) {
15162         if (isCheckinRequest || isCompact) {
15163             // short checkin version
15164             pw.print("time,"); pw.print(uptime); pw.print(","); pw.println(realtime);
15165         } else {
15166             pw.println("Applications Memory Usage (in Kilobytes):");
15167             pw.println("Uptime: " + uptime + " Realtime: " + realtime);
15168         }
15169     }
15170
15171     private static final int KSM_SHARED = 0;
15172     private static final int KSM_SHARING = 1;
15173     private static final int KSM_UNSHARED = 2;
15174     private static final int KSM_VOLATILE = 3;
15175
15176     private final long[] getKsmInfo() {
15177         long[] longOut = new long[4];
15178         final int[] SINGLE_LONG_FORMAT = new int[] {
15179             Process.PROC_SPACE_TERM|Process.PROC_OUT_LONG
15180         };
15181         long[] longTmp = new long[1];
15182         Process.readProcFile("/sys/kernel/mm/ksm/pages_shared",
15183                 SINGLE_LONG_FORMAT, null, longTmp, null);
15184         longOut[KSM_SHARED] = longTmp[0] * ProcessList.PAGE_SIZE / 1024;
15185         longTmp[0] = 0;
15186         Process.readProcFile("/sys/kernel/mm/ksm/pages_sharing",
15187                 SINGLE_LONG_FORMAT, null, longTmp, null);
15188         longOut[KSM_SHARING] = longTmp[0] * ProcessList.PAGE_SIZE / 1024;
15189         longTmp[0] = 0;
15190         Process.readProcFile("/sys/kernel/mm/ksm/pages_unshared",
15191                 SINGLE_LONG_FORMAT, null, longTmp, null);
15192         longOut[KSM_UNSHARED] = longTmp[0] * ProcessList.PAGE_SIZE / 1024;
15193         longTmp[0] = 0;
15194         Process.readProcFile("/sys/kernel/mm/ksm/pages_volatile",
15195                 SINGLE_LONG_FORMAT, null, longTmp, null);
15196         longOut[KSM_VOLATILE] = longTmp[0] * ProcessList.PAGE_SIZE / 1024;
15197         return longOut;
15198     }
15199
15200     private static String stringifySize(long size, int order) {
15201         Locale locale = Locale.US;
15202         switch (order) {
15203             case 1:
15204                 return String.format(locale, "%,13d", size);
15205             case 1024:
15206                 return String.format(locale, "%,9dK", size / 1024);
15207             case 1024 * 1024:
15208                 return String.format(locale, "%,5dM", size / 1024 / 1024);
15209             case 1024 * 1024 * 1024:
15210                 return String.format(locale, "%,1dG", size / 1024 / 1024 / 1024);
15211             default:
15212                 throw new IllegalArgumentException("Invalid size order");
15213         }
15214     }
15215
15216     private static String stringifyKBSize(long size) {
15217         return stringifySize(size * 1024, 1024);
15218     }
15219
15220     final void dumpApplicationMemoryUsage(FileDescriptor fd,
15221             PrintWriter pw, String prefix, String[] args, boolean brief, PrintWriter categoryPw) {
15222         boolean dumpDetails = false;
15223         boolean dumpFullDetails = false;
15224         boolean dumpDalvik = false;
15225         boolean dumpSummaryOnly = false;
15226         boolean oomOnly = false;
15227         boolean isCompact = false;
15228         boolean localOnly = false;
15229         boolean packages = false;
15230
15231         int opti = 0;
15232         while (opti < args.length) {
15233             String opt = args[opti];
15234             if (opt == null || opt.length() <= 0 || opt.charAt(0) != '-') {
15235                 break;
15236             }
15237             opti++;
15238             if ("-a".equals(opt)) {
15239                 dumpDetails = true;
15240                 dumpFullDetails = true;
15241                 dumpDalvik = true;
15242             } else if ("-d".equals(opt)) {
15243                 dumpDalvik = true;
15244             } else if ("-c".equals(opt)) {
15245                 isCompact = true;
15246             } else if ("-s".equals(opt)) {
15247                 dumpDetails = true;
15248                 dumpSummaryOnly = true;
15249             } else if ("--oom".equals(opt)) {
15250                 oomOnly = true;
15251             } else if ("--local".equals(opt)) {
15252                 localOnly = true;
15253             } else if ("--package".equals(opt)) {
15254                 packages = true;
15255             } else if ("-h".equals(opt)) {
15256                 pw.println("meminfo dump options: [-a] [-d] [-c] [-s] [--oom] [process]");
15257                 pw.println("  -a: include all available information for each process.");
15258                 pw.println("  -d: include dalvik details.");
15259                 pw.println("  -c: dump in a compact machine-parseable representation.");
15260                 pw.println("  -s: dump only summary of application memory usage.");
15261                 pw.println("  --oom: only show processes organized by oom adj.");
15262                 pw.println("  --local: only collect details locally, don't call process.");
15263                 pw.println("  --package: interpret process arg as package, dumping all");
15264                 pw.println("             processes that have loaded that package.");
15265                 pw.println("If [process] is specified it can be the name or ");
15266                 pw.println("pid of a specific process to dump.");
15267                 return;
15268             } else {
15269                 pw.println("Unknown argument: " + opt + "; use -h for help");
15270             }
15271         }
15272
15273         final boolean isCheckinRequest = scanArgs(args, "--checkin");
15274         long uptime = SystemClock.uptimeMillis();
15275         long realtime = SystemClock.elapsedRealtime();
15276         final long[] tmpLong = new long[1];
15277
15278         ArrayList<ProcessRecord> procs = collectProcesses(pw, opti, packages, args);
15279         if (procs == null) {
15280             // No Java processes.  Maybe they want to print a native process.
15281             if (args != null && args.length > opti
15282                     && args[opti].charAt(0) != '-') {
15283                 ArrayList<ProcessCpuTracker.Stats> nativeProcs
15284                         = new ArrayList<ProcessCpuTracker.Stats>();
15285                 updateCpuStatsNow();
15286                 int findPid = -1;
15287                 try {
15288                     findPid = Integer.parseInt(args[opti]);
15289                 } catch (NumberFormatException e) {
15290                 }
15291                 synchronized (mProcessCpuTracker) {
15292                     final int N = mProcessCpuTracker.countStats();
15293                     for (int i=0; i<N; i++) {
15294                         ProcessCpuTracker.Stats st = mProcessCpuTracker.getStats(i);
15295                         if (st.pid == findPid || (st.baseName != null
15296                                 && st.baseName.equals(args[opti]))) {
15297                             nativeProcs.add(st);
15298                         }
15299                     }
15300                 }
15301                 if (nativeProcs.size() > 0) {
15302                     dumpApplicationMemoryUsageHeader(pw, uptime, realtime, isCheckinRequest,
15303                             isCompact);
15304                     Debug.MemoryInfo mi = null;
15305                     for (int i = nativeProcs.size() - 1 ; i >= 0 ; i--) {
15306                         final ProcessCpuTracker.Stats r = nativeProcs.get(i);
15307                         final int pid = r.pid;
15308                         if (!isCheckinRequest && dumpDetails) {
15309                             pw.println("\n** MEMINFO in pid " + pid + " [" + r.baseName + "] **");
15310                         }
15311                         if (mi == null) {
15312                             mi = new Debug.MemoryInfo();
15313                         }
15314                         if (dumpDetails || (!brief && !oomOnly)) {
15315                             Debug.getMemoryInfo(pid, mi);
15316                         } else {
15317                             mi.dalvikPss = (int)Debug.getPss(pid, tmpLong, null);
15318                             mi.dalvikPrivateDirty = (int)tmpLong[0];
15319                         }
15320                         ActivityThread.dumpMemInfoTable(pw, mi, isCheckinRequest, dumpFullDetails,
15321                                 dumpDalvik, dumpSummaryOnly, pid, r.baseName, 0, 0, 0, 0, 0, 0);
15322                         if (isCheckinRequest) {
15323                             pw.println();
15324                         }
15325                     }
15326                     return;
15327                 }
15328             }
15329             pw.println("No process found for: " + args[opti]);
15330             return;
15331         }
15332
15333         if (!brief && !oomOnly && (procs.size() == 1 || isCheckinRequest || packages)) {
15334             dumpDetails = true;
15335         }
15336
15337         dumpApplicationMemoryUsageHeader(pw, uptime, realtime, isCheckinRequest, isCompact);
15338
15339         String[] innerArgs = new String[args.length-opti];
15340         System.arraycopy(args, opti, innerArgs, 0, args.length-opti);
15341
15342         ArrayList<MemItem> procMems = new ArrayList<MemItem>();
15343         final SparseArray<MemItem> procMemsMap = new SparseArray<MemItem>();
15344         long nativePss = 0;
15345         long dalvikPss = 0;
15346         long[] dalvikSubitemPss = dumpDalvik ? new long[Debug.MemoryInfo.NUM_DVK_STATS] :
15347                 EmptyArray.LONG;
15348         long otherPss = 0;
15349         long[] miscPss = new long[Debug.MemoryInfo.NUM_OTHER_STATS];
15350
15351         long oomPss[] = new long[DUMP_MEM_OOM_LABEL.length];
15352         ArrayList<MemItem>[] oomProcs = (ArrayList<MemItem>[])
15353                 new ArrayList[DUMP_MEM_OOM_LABEL.length];
15354
15355         long totalPss = 0;
15356         long cachedPss = 0;
15357
15358         Debug.MemoryInfo mi = null;
15359         for (int i = procs.size() - 1 ; i >= 0 ; i--) {
15360             final ProcessRecord r = procs.get(i);
15361             final IApplicationThread thread;
15362             final int pid;
15363             final int oomAdj;
15364             final boolean hasActivities;
15365             synchronized (this) {
15366                 thread = r.thread;
15367                 pid = r.pid;
15368                 oomAdj = r.getSetAdjWithServices();
15369                 hasActivities = r.activities.size() > 0;
15370             }
15371             if (thread != null) {
15372                 if (!isCheckinRequest && dumpDetails) {
15373                     pw.println("\n** MEMINFO in pid " + pid + " [" + r.processName + "] **");
15374                 }
15375                 if (mi == null) {
15376                     mi = new Debug.MemoryInfo();
15377                 }
15378                 if (dumpDetails || (!brief && !oomOnly)) {
15379                     Debug.getMemoryInfo(pid, mi);
15380                 } else {
15381                     mi.dalvikPss = (int)Debug.getPss(pid, tmpLong, null);
15382                     mi.dalvikPrivateDirty = (int)tmpLong[0];
15383                 }
15384                 if (dumpDetails) {
15385                     if (localOnly) {
15386                         ActivityThread.dumpMemInfoTable(pw, mi, isCheckinRequest, dumpFullDetails,
15387                                 dumpDalvik, dumpSummaryOnly, pid, r.processName, 0, 0, 0, 0, 0, 0);
15388                         if (isCheckinRequest) {
15389                             pw.println();
15390                         }
15391                     } else {
15392                         try {
15393                             pw.flush();
15394                             thread.dumpMemInfo(fd, mi, isCheckinRequest, dumpFullDetails,
15395                                     dumpDalvik, dumpSummaryOnly, innerArgs);
15396                         } catch (RemoteException e) {
15397                             if (!isCheckinRequest) {
15398                                 pw.println("Got RemoteException!");
15399                                 pw.flush();
15400                             }
15401                         }
15402                     }
15403                 }
15404
15405                 final long myTotalPss = mi.getTotalPss();
15406                 final long myTotalUss = mi.getTotalUss();
15407
15408                 synchronized (this) {
15409                     if (r.thread != null && oomAdj == r.getSetAdjWithServices()) {
15410                         // Record this for posterity if the process has been stable.
15411                         r.baseProcessTracker.addPss(myTotalPss, myTotalUss, true, r.pkgList);
15412                     }
15413                 }
15414
15415                 if (!isCheckinRequest && mi != null) {
15416                     totalPss += myTotalPss;
15417                     MemItem pssItem = new MemItem(r.processName + " (pid " + pid +
15418                             (hasActivities ? " / activities)" : ")"),
15419                             r.processName, myTotalPss, pid, hasActivities);
15420                     procMems.add(pssItem);
15421                     procMemsMap.put(pid, pssItem);
15422
15423                     nativePss += mi.nativePss;
15424                     dalvikPss += mi.dalvikPss;
15425                     for (int j=0; j<dalvikSubitemPss.length; j++) {
15426                         dalvikSubitemPss[j] += mi.getOtherPss(Debug.MemoryInfo.NUM_OTHER_STATS + j);
15427                     }
15428                     otherPss += mi.otherPss;
15429                     for (int j=0; j<Debug.MemoryInfo.NUM_OTHER_STATS; j++) {
15430                         long mem = mi.getOtherPss(j);
15431                         miscPss[j] += mem;
15432                         otherPss -= mem;
15433                     }
15434
15435                     if (oomAdj >= ProcessList.CACHED_APP_MIN_ADJ) {
15436                         cachedPss += myTotalPss;
15437                     }
15438
15439                     for (int oomIndex=0; oomIndex<oomPss.length; oomIndex++) {
15440                         if (oomAdj <= DUMP_MEM_OOM_ADJ[oomIndex]
15441                                 || oomIndex == (oomPss.length-1)) {
15442                             oomPss[oomIndex] += myTotalPss;
15443                             if (oomProcs[oomIndex] == null) {
15444                                 oomProcs[oomIndex] = new ArrayList<MemItem>();
15445                             }
15446                             oomProcs[oomIndex].add(pssItem);
15447                             break;
15448                         }
15449                     }
15450                 }
15451             }
15452         }
15453
15454         long nativeProcTotalPss = 0;
15455
15456         if (!isCheckinRequest && procs.size() > 1 && !packages) {
15457             // If we are showing aggregations, also look for native processes to
15458             // include so that our aggregations are more accurate.
15459             updateCpuStatsNow();
15460             mi = null;
15461             synchronized (mProcessCpuTracker) {
15462                 final int N = mProcessCpuTracker.countStats();
15463                 for (int i=0; i<N; i++) {
15464                     ProcessCpuTracker.Stats st = mProcessCpuTracker.getStats(i);
15465                     if (st.vsize > 0 && procMemsMap.indexOfKey(st.pid) < 0) {
15466                         if (mi == null) {
15467                             mi = new Debug.MemoryInfo();
15468                         }
15469                         if (!brief && !oomOnly) {
15470                             Debug.getMemoryInfo(st.pid, mi);
15471                         } else {
15472                             mi.nativePss = (int)Debug.getPss(st.pid, tmpLong, null);
15473                             mi.nativePrivateDirty = (int)tmpLong[0];
15474                         }
15475
15476                         final long myTotalPss = mi.getTotalPss();
15477                         totalPss += myTotalPss;
15478                         nativeProcTotalPss += myTotalPss;
15479
15480                         MemItem pssItem = new MemItem(st.name + " (pid " + st.pid + ")",
15481                                 st.name, myTotalPss, st.pid, false);
15482                         procMems.add(pssItem);
15483
15484                         nativePss += mi.nativePss;
15485                         dalvikPss += mi.dalvikPss;
15486                         for (int j=0; j<dalvikSubitemPss.length; j++) {
15487                             dalvikSubitemPss[j] += mi.getOtherPss(
15488                                     Debug.MemoryInfo.NUM_OTHER_STATS + j);
15489                         }
15490                         otherPss += mi.otherPss;
15491                         for (int j=0; j<Debug.MemoryInfo.NUM_OTHER_STATS; j++) {
15492                             long mem = mi.getOtherPss(j);
15493                             miscPss[j] += mem;
15494                             otherPss -= mem;
15495                         }
15496                         oomPss[0] += myTotalPss;
15497                         if (oomProcs[0] == null) {
15498                             oomProcs[0] = new ArrayList<MemItem>();
15499                         }
15500                         oomProcs[0].add(pssItem);
15501                     }
15502                 }
15503             }
15504
15505             ArrayList<MemItem> catMems = new ArrayList<MemItem>();
15506
15507             catMems.add(new MemItem("Native", "Native", nativePss, -1));
15508             final MemItem dalvikItem = new MemItem("Dalvik", "Dalvik", dalvikPss, -2);
15509             if (dalvikSubitemPss.length > 0) {
15510                 dalvikItem.subitems = new ArrayList<MemItem>();
15511                 for (int j=0; j<dalvikSubitemPss.length; j++) {
15512                     final String name = Debug.MemoryInfo.getOtherLabel(
15513                             Debug.MemoryInfo.NUM_OTHER_STATS + j);
15514                     dalvikItem.subitems.add(new MemItem(name, name, dalvikSubitemPss[j], j));
15515                 }
15516             }
15517             catMems.add(dalvikItem);
15518             catMems.add(new MemItem("Unknown", "Unknown", otherPss, -3));
15519             for (int j=0; j<Debug.MemoryInfo.NUM_OTHER_STATS; j++) {
15520                 String label = Debug.MemoryInfo.getOtherLabel(j);
15521                 catMems.add(new MemItem(label, label, miscPss[j], j));
15522             }
15523
15524             ArrayList<MemItem> oomMems = new ArrayList<MemItem>();
15525             for (int j=0; j<oomPss.length; j++) {
15526                 if (oomPss[j] != 0) {
15527                     String label = isCompact ? DUMP_MEM_OOM_COMPACT_LABEL[j]
15528                             : DUMP_MEM_OOM_LABEL[j];
15529                     MemItem item = new MemItem(label, label, oomPss[j],
15530                             DUMP_MEM_OOM_ADJ[j]);
15531                     item.subitems = oomProcs[j];
15532                     oomMems.add(item);
15533                 }
15534             }
15535
15536             if (!brief && !oomOnly && !isCompact) {
15537                 pw.println();
15538                 pw.println("Total PSS by process:");
15539                 dumpMemItems(pw, "  ", "proc", procMems, true, isCompact);
15540                 pw.println();
15541             }
15542             if (!isCompact) {
15543                 pw.println("Total PSS by OOM adjustment:");
15544             }
15545             dumpMemItems(pw, "  ", "oom", oomMems, false, isCompact);
15546             if (!brief && !oomOnly) {
15547                 PrintWriter out = categoryPw != null ? categoryPw : pw;
15548                 if (!isCompact) {
15549                     out.println();
15550                     out.println("Total PSS by category:");
15551                 }
15552                 dumpMemItems(out, "  ", "cat", catMems, true, isCompact);
15553             }
15554             if (!isCompact) {
15555                 pw.println();
15556             }
15557             MemInfoReader memInfo = new MemInfoReader();
15558             memInfo.readMemInfo();
15559             if (nativeProcTotalPss > 0) {
15560                 synchronized (this) {
15561                     final long cachedKb = memInfo.getCachedSizeKb();
15562                     final long freeKb = memInfo.getFreeSizeKb();
15563                     final long zramKb = memInfo.getZramTotalSizeKb();
15564                     final long kernelKb = memInfo.getKernelUsedSizeKb();
15565                     EventLogTags.writeAmMeminfo(cachedKb*1024, freeKb*1024, zramKb*1024,
15566                             kernelKb*1024, nativeProcTotalPss*1024);
15567                     mProcessStats.addSysMemUsageLocked(cachedKb, freeKb, zramKb, kernelKb,
15568                             nativeProcTotalPss);
15569                 }
15570             }
15571             if (!brief) {
15572                 if (!isCompact) {
15573                     pw.print("Total RAM: "); pw.print(stringifyKBSize(memInfo.getTotalSizeKb()));
15574                     pw.print(" (status ");
15575                     switch (mLastMemoryLevel) {
15576                         case ProcessStats.ADJ_MEM_FACTOR_NORMAL:
15577                             pw.println("normal)");
15578                             break;
15579                         case ProcessStats.ADJ_MEM_FACTOR_MODERATE:
15580                             pw.println("moderate)");
15581                             break;
15582                         case ProcessStats.ADJ_MEM_FACTOR_LOW:
15583                             pw.println("low)");
15584                             break;
15585                         case ProcessStats.ADJ_MEM_FACTOR_CRITICAL:
15586                             pw.println("critical)");
15587                             break;
15588                         default:
15589                             pw.print(mLastMemoryLevel);
15590                             pw.println(")");
15591                             break;
15592                     }
15593                     pw.print(" Free RAM: ");
15594                     pw.print(stringifyKBSize(cachedPss + memInfo.getCachedSizeKb()
15595                             + memInfo.getFreeSizeKb()));
15596                     pw.print(" (");
15597                     pw.print(stringifyKBSize(cachedPss));
15598                     pw.print(" cached pss + ");
15599                     pw.print(stringifyKBSize(memInfo.getCachedSizeKb()));
15600                     pw.print(" cached kernel + ");
15601                     pw.print(stringifyKBSize(memInfo.getFreeSizeKb()));
15602                     pw.println(" free)");
15603                 } else {
15604                     pw.print("ram,"); pw.print(memInfo.getTotalSizeKb()); pw.print(",");
15605                     pw.print(cachedPss + memInfo.getCachedSizeKb()
15606                             + memInfo.getFreeSizeKb()); pw.print(",");
15607                     pw.println(totalPss - cachedPss);
15608                 }
15609             }
15610             if (!isCompact) {
15611                 pw.print(" Used RAM: "); pw.print(stringifyKBSize(totalPss - cachedPss
15612                         + memInfo.getKernelUsedSizeKb())); pw.print(" (");
15613                 pw.print(stringifyKBSize(totalPss - cachedPss)); pw.print(" used pss + ");
15614                 pw.print(stringifyKBSize(memInfo.getKernelUsedSizeKb())); pw.print(" kernel)\n");
15615                 pw.print(" Lost RAM: "); pw.println(stringifyKBSize(memInfo.getTotalSizeKb()
15616                         - totalPss - memInfo.getFreeSizeKb() - memInfo.getCachedSizeKb()
15617                         - memInfo.getKernelUsedSizeKb()));
15618             } else {
15619                 pw.print("lostram,"); pw.println(memInfo.getTotalSizeKb()
15620                         - totalPss - memInfo.getFreeSizeKb() - memInfo.getCachedSizeKb()
15621                         - memInfo.getKernelUsedSizeKb());
15622             }
15623             if (!brief) {
15624                 if (memInfo.getZramTotalSizeKb() != 0) {
15625                     if (!isCompact) {
15626                         pw.print("     ZRAM: ");
15627                         pw.print(stringifyKBSize(memInfo.getZramTotalSizeKb()));
15628                                 pw.print(" physical used for ");
15629                                 pw.print(stringifyKBSize(memInfo.getSwapTotalSizeKb()
15630                                         - memInfo.getSwapFreeSizeKb()));
15631                                 pw.print(" in swap (");
15632                                 pw.print(stringifyKBSize(memInfo.getSwapTotalSizeKb()));
15633                                 pw.println(" total swap)");
15634                     } else {
15635                         pw.print("zram,"); pw.print(memInfo.getZramTotalSizeKb()); pw.print(",");
15636                                 pw.print(memInfo.getSwapTotalSizeKb()); pw.print(",");
15637                                 pw.println(memInfo.getSwapFreeSizeKb());
15638                     }
15639                 }
15640                 final long[] ksm = getKsmInfo();
15641                 if (!isCompact) {
15642                     if (ksm[KSM_SHARING] != 0 || ksm[KSM_SHARED] != 0 || ksm[KSM_UNSHARED] != 0
15643                             || ksm[KSM_VOLATILE] != 0) {
15644                         pw.print("      KSM: "); pw.print(stringifyKBSize(ksm[KSM_SHARING]));
15645                                 pw.print(" saved from shared ");
15646                                 pw.print(stringifyKBSize(ksm[KSM_SHARED]));
15647                         pw.print("           "); pw.print(stringifyKBSize(ksm[KSM_UNSHARED]));
15648                                 pw.print(" unshared; ");
15649                                 pw.print(stringifyKBSize(
15650                                              ksm[KSM_VOLATILE])); pw.println(" volatile");
15651                     }
15652                     pw.print("   Tuning: ");
15653                     pw.print(ActivityManager.staticGetMemoryClass());
15654                     pw.print(" (large ");
15655                     pw.print(ActivityManager.staticGetLargeMemoryClass());
15656                     pw.print("), oom ");
15657                     pw.print(stringifySize(
15658                                 mProcessList.getMemLevel(ProcessList.CACHED_APP_MAX_ADJ), 1024));
15659                     pw.print(", restore limit ");
15660                     pw.print(stringifyKBSize(mProcessList.getCachedRestoreThresholdKb()));
15661                     if (ActivityManager.isLowRamDeviceStatic()) {
15662                         pw.print(" (low-ram)");
15663                     }
15664                     if (ActivityManager.isHighEndGfx()) {
15665                         pw.print(" (high-end-gfx)");
15666                     }
15667                     pw.println();
15668                 } else {
15669                     pw.print("ksm,"); pw.print(ksm[KSM_SHARING]); pw.print(",");
15670                     pw.print(ksm[KSM_SHARED]); pw.print(","); pw.print(ksm[KSM_UNSHARED]);
15671                     pw.print(","); pw.println(ksm[KSM_VOLATILE]);
15672                     pw.print("tuning,");
15673                     pw.print(ActivityManager.staticGetMemoryClass());
15674                     pw.print(',');
15675                     pw.print(ActivityManager.staticGetLargeMemoryClass());
15676                     pw.print(',');
15677                     pw.print(mProcessList.getMemLevel(ProcessList.CACHED_APP_MAX_ADJ)/1024);
15678                     if (ActivityManager.isLowRamDeviceStatic()) {
15679                         pw.print(",low-ram");
15680                     }
15681                     if (ActivityManager.isHighEndGfx()) {
15682                         pw.print(",high-end-gfx");
15683                     }
15684                     pw.println();
15685                 }
15686             }
15687         }
15688     }
15689
15690     private void appendBasicMemEntry(StringBuilder sb, int oomAdj, int procState, long pss,
15691             long memtrack, String name) {
15692         sb.append("  ");
15693         sb.append(ProcessList.makeOomAdjString(oomAdj));
15694         sb.append(' ');
15695         sb.append(ProcessList.makeProcStateString(procState));
15696         sb.append(' ');
15697         ProcessList.appendRamKb(sb, pss);
15698         sb.append(": ");
15699         sb.append(name);
15700         if (memtrack > 0) {
15701             sb.append(" (");
15702             sb.append(stringifyKBSize(memtrack));
15703             sb.append(" memtrack)");
15704         }
15705     }
15706
15707     private void appendMemInfo(StringBuilder sb, ProcessMemInfo mi) {
15708         appendBasicMemEntry(sb, mi.oomAdj, mi.procState, mi.pss, mi.memtrack, mi.name);
15709         sb.append(" (pid ");
15710         sb.append(mi.pid);
15711         sb.append(") ");
15712         sb.append(mi.adjType);
15713         sb.append('\n');
15714         if (mi.adjReason != null) {
15715             sb.append("                      ");
15716             sb.append(mi.adjReason);
15717             sb.append('\n');
15718         }
15719     }
15720
15721     void reportMemUsage(ArrayList<ProcessMemInfo> memInfos) {
15722         final SparseArray<ProcessMemInfo> infoMap = new SparseArray<>(memInfos.size());
15723         for (int i=0, N=memInfos.size(); i<N; i++) {
15724             ProcessMemInfo mi = memInfos.get(i);
15725             infoMap.put(mi.pid, mi);
15726         }
15727         updateCpuStatsNow();
15728         long[] memtrackTmp = new long[1];
15729         synchronized (mProcessCpuTracker) {
15730             final int N = mProcessCpuTracker.countStats();
15731             for (int i=0; i<N; i++) {
15732                 ProcessCpuTracker.Stats st = mProcessCpuTracker.getStats(i);
15733                 if (st.vsize > 0) {
15734                     long pss = Debug.getPss(st.pid, null, memtrackTmp);
15735                     if (pss > 0) {
15736                         if (infoMap.indexOfKey(st.pid) < 0) {
15737                             ProcessMemInfo mi = new ProcessMemInfo(st.name, st.pid,
15738                                     ProcessList.NATIVE_ADJ, -1, "native", null);
15739                             mi.pss = pss;
15740                             mi.memtrack = memtrackTmp[0];
15741                             memInfos.add(mi);
15742                         }
15743                     }
15744                 }
15745             }
15746         }
15747
15748         long totalPss = 0;
15749         long totalMemtrack = 0;
15750         for (int i=0, N=memInfos.size(); i<N; i++) {
15751             ProcessMemInfo mi = memInfos.get(i);
15752             if (mi.pss == 0) {
15753                 mi.pss = Debug.getPss(mi.pid, null, memtrackTmp);
15754                 mi.memtrack = memtrackTmp[0];
15755             }
15756             totalPss += mi.pss;
15757             totalMemtrack += mi.memtrack;
15758         }
15759         Collections.sort(memInfos, new Comparator<ProcessMemInfo>() {
15760             @Override public int compare(ProcessMemInfo lhs, ProcessMemInfo rhs) {
15761                 if (lhs.oomAdj != rhs.oomAdj) {
15762                     return lhs.oomAdj < rhs.oomAdj ? -1 : 1;
15763                 }
15764                 if (lhs.pss != rhs.pss) {
15765                     return lhs.pss < rhs.pss ? 1 : -1;
15766                 }
15767                 return 0;
15768             }
15769         });
15770
15771         StringBuilder tag = new StringBuilder(128);
15772         StringBuilder stack = new StringBuilder(128);
15773         tag.append("Low on memory -- ");
15774         appendMemBucket(tag, totalPss, "total", false);
15775         appendMemBucket(stack, totalPss, "total", true);
15776
15777         StringBuilder fullNativeBuilder = new StringBuilder(1024);
15778         StringBuilder shortNativeBuilder = new StringBuilder(1024);
15779         StringBuilder fullJavaBuilder = new StringBuilder(1024);
15780
15781         boolean firstLine = true;
15782         int lastOomAdj = Integer.MIN_VALUE;
15783         long extraNativeRam = 0;
15784         long extraNativeMemtrack = 0;
15785         long cachedPss = 0;
15786         for (int i=0, N=memInfos.size(); i<N; i++) {
15787             ProcessMemInfo mi = memInfos.get(i);
15788
15789             if (mi.oomAdj >= ProcessList.CACHED_APP_MIN_ADJ) {
15790                 cachedPss += mi.pss;
15791             }
15792
15793             if (mi.oomAdj != ProcessList.NATIVE_ADJ
15794                     && (mi.oomAdj < ProcessList.SERVICE_ADJ
15795                             || mi.oomAdj == ProcessList.HOME_APP_ADJ
15796                             || mi.oomAdj == ProcessList.PREVIOUS_APP_ADJ)) {
15797                 if (lastOomAdj != mi.oomAdj) {
15798                     lastOomAdj = mi.oomAdj;
15799                     if (mi.oomAdj <= ProcessList.FOREGROUND_APP_ADJ) {
15800                         tag.append(" / ");
15801                     }
15802                     if (mi.oomAdj >= ProcessList.FOREGROUND_APP_ADJ) {
15803                         if (firstLine) {
15804                             stack.append(":");
15805                             firstLine = false;
15806                         }
15807                         stack.append("\n\t at ");
15808                     } else {
15809                         stack.append("$");
15810                     }
15811                 } else {
15812                     tag.append(" ");
15813                     stack.append("$");
15814                 }
15815                 if (mi.oomAdj <= ProcessList.FOREGROUND_APP_ADJ) {
15816                     appendMemBucket(tag, mi.pss, mi.name, false);
15817                 }
15818                 appendMemBucket(stack, mi.pss, mi.name, true);
15819                 if (mi.oomAdj >= ProcessList.FOREGROUND_APP_ADJ
15820                         && ((i+1) >= N || memInfos.get(i+1).oomAdj != lastOomAdj)) {
15821                     stack.append("(");
15822                     for (int k=0; k<DUMP_MEM_OOM_ADJ.length; k++) {
15823                         if (DUMP_MEM_OOM_ADJ[k] == mi.oomAdj) {
15824                             stack.append(DUMP_MEM_OOM_LABEL[k]);
15825                             stack.append(":");
15826                             stack.append(DUMP_MEM_OOM_ADJ[k]);
15827                         }
15828                     }
15829                     stack.append(")");
15830                 }
15831             }
15832
15833             appendMemInfo(fullNativeBuilder, mi);
15834             if (mi.oomAdj == ProcessList.NATIVE_ADJ) {
15835                 // The short form only has native processes that are >= 512K.
15836                 if (mi.pss >= 512) {
15837                     appendMemInfo(shortNativeBuilder, mi);
15838                 } else {
15839                     extraNativeRam += mi.pss;
15840                     extraNativeMemtrack += mi.memtrack;
15841                 }
15842             } else {
15843                 // Short form has all other details, but if we have collected RAM
15844                 // from smaller native processes let's dump a summary of that.
15845                 if (extraNativeRam > 0) {
15846                     appendBasicMemEntry(shortNativeBuilder, ProcessList.NATIVE_ADJ,
15847                             -1, extraNativeRam, extraNativeMemtrack, "(Other native)");
15848                     shortNativeBuilder.append('\n');
15849                     extraNativeRam = 0;
15850                 }
15851                 appendMemInfo(fullJavaBuilder, mi);
15852             }
15853         }
15854
15855         fullJavaBuilder.append("           ");
15856         ProcessList.appendRamKb(fullJavaBuilder, totalPss);
15857         fullJavaBuilder.append(": TOTAL");
15858         if (totalMemtrack > 0) {
15859             fullJavaBuilder.append(" (");
15860             fullJavaBuilder.append(stringifyKBSize(totalMemtrack));
15861             fullJavaBuilder.append(" memtrack)");
15862         } else {
15863         }
15864         fullJavaBuilder.append("\n");
15865
15866         MemInfoReader memInfo = new MemInfoReader();
15867         memInfo.readMemInfo();
15868         final long[] infos = memInfo.getRawInfo();
15869
15870         StringBuilder memInfoBuilder = new StringBuilder(1024);
15871         Debug.getMemInfo(infos);
15872         memInfoBuilder.append("  MemInfo: ");
15873         memInfoBuilder.append(stringifyKBSize(infos[Debug.MEMINFO_SLAB])).append(" slab, ");
15874         memInfoBuilder.append(stringifyKBSize(infos[Debug.MEMINFO_SHMEM])).append(" shmem, ");
15875         memInfoBuilder.append(stringifyKBSize(
15876                                   infos[Debug.MEMINFO_VM_ALLOC_USED])).append(" vm alloc, ");
15877         memInfoBuilder.append(stringifyKBSize(
15878                                   infos[Debug.MEMINFO_PAGE_TABLES])).append(" page tables ");
15879         memInfoBuilder.append(stringifyKBSize(
15880                                   infos[Debug.MEMINFO_KERNEL_STACK])).append(" kernel stack\n");
15881         memInfoBuilder.append("           ");
15882         memInfoBuilder.append(stringifyKBSize(infos[Debug.MEMINFO_BUFFERS])).append(" buffers, ");
15883         memInfoBuilder.append(stringifyKBSize(infos[Debug.MEMINFO_CACHED])).append(" cached, ");
15884         memInfoBuilder.append(stringifyKBSize(infos[Debug.MEMINFO_MAPPED])).append(" mapped, ");
15885         memInfoBuilder.append(stringifyKBSize(infos[Debug.MEMINFO_FREE])).append(" free\n");
15886         if (infos[Debug.MEMINFO_ZRAM_TOTAL] != 0) {
15887             memInfoBuilder.append("  ZRAM: ");
15888             memInfoBuilder.append(stringifyKBSize(infos[Debug.MEMINFO_ZRAM_TOTAL]));
15889             memInfoBuilder.append(" RAM, ");
15890             memInfoBuilder.append(stringifyKBSize(infos[Debug.MEMINFO_SWAP_TOTAL]));
15891             memInfoBuilder.append(" swap total, ");
15892             memInfoBuilder.append(stringifyKBSize(infos[Debug.MEMINFO_SWAP_FREE]));
15893             memInfoBuilder.append(" swap free\n");
15894         }
15895         final long[] ksm = getKsmInfo();
15896         if (ksm[KSM_SHARING] != 0 || ksm[KSM_SHARED] != 0 || ksm[KSM_UNSHARED] != 0
15897                 || ksm[KSM_VOLATILE] != 0) {
15898             memInfoBuilder.append("  KSM: ");
15899             memInfoBuilder.append(stringifyKBSize(ksm[KSM_SHARING]));
15900             memInfoBuilder.append(" saved from shared ");
15901             memInfoBuilder.append(stringifyKBSize(ksm[KSM_SHARED]));
15902             memInfoBuilder.append("\n       ");
15903             memInfoBuilder.append(stringifyKBSize(ksm[KSM_UNSHARED]));
15904             memInfoBuilder.append(" unshared; ");
15905             memInfoBuilder.append(stringifyKBSize(ksm[KSM_VOLATILE]));
15906             memInfoBuilder.append(" volatile\n");
15907         }
15908         memInfoBuilder.append("  Free RAM: ");
15909         memInfoBuilder.append(stringifyKBSize(cachedPss + memInfo.getCachedSizeKb()
15910                 + memInfo.getFreeSizeKb()));
15911         memInfoBuilder.append("\n");
15912         memInfoBuilder.append("  Used RAM: ");
15913         memInfoBuilder.append(stringifyKBSize(
15914                                   totalPss - cachedPss + memInfo.getKernelUsedSizeKb()));
15915         memInfoBuilder.append("\n");
15916         memInfoBuilder.append("  Lost RAM: ");
15917         memInfoBuilder.append(stringifyKBSize(memInfo.getTotalSizeKb()
15918                 - totalPss - memInfo.getFreeSizeKb() - memInfo.getCachedSizeKb()
15919                 - memInfo.getKernelUsedSizeKb()));
15920         memInfoBuilder.append("\n");
15921         Slog.i(TAG, "Low on memory:");
15922         Slog.i(TAG, shortNativeBuilder.toString());
15923         Slog.i(TAG, fullJavaBuilder.toString());
15924         Slog.i(TAG, memInfoBuilder.toString());
15925
15926         StringBuilder dropBuilder = new StringBuilder(1024);
15927         /*
15928         StringWriter oomSw = new StringWriter();
15929         PrintWriter oomPw = new FastPrintWriter(oomSw, false, 256);
15930         StringWriter catSw = new StringWriter();
15931         PrintWriter catPw = new FastPrintWriter(catSw, false, 256);
15932         String[] emptyArgs = new String[] { };
15933         dumpApplicationMemoryUsage(null, oomPw, "  ", emptyArgs, true, catPw);
15934         oomPw.flush();
15935         String oomString = oomSw.toString();
15936         */
15937         dropBuilder.append("Low on memory:");
15938         dropBuilder.append(stack);
15939         dropBuilder.append('\n');
15940         dropBuilder.append(fullNativeBuilder);
15941         dropBuilder.append(fullJavaBuilder);
15942         dropBuilder.append('\n');
15943         dropBuilder.append(memInfoBuilder);
15944         dropBuilder.append('\n');
15945         /*
15946         dropBuilder.append(oomString);
15947         dropBuilder.append('\n');
15948         */
15949         StringWriter catSw = new StringWriter();
15950         synchronized (ActivityManagerService.this) {
15951             PrintWriter catPw = new FastPrintWriter(catSw, false, 256);
15952             String[] emptyArgs = new String[] { };
15953             catPw.println();
15954             dumpProcessesLocked(null, catPw, emptyArgs, 0, false, null);
15955             catPw.println();
15956             mServices.dumpServicesLocked(null, catPw, emptyArgs, 0,
15957                     false, false, null);
15958             catPw.println();
15959             dumpActivitiesLocked(null, catPw, emptyArgs, 0, false, false, null);
15960             catPw.flush();
15961         }
15962         dropBuilder.append(catSw.toString());
15963         addErrorToDropBox("lowmem", null, "system_server", null,
15964                 null, tag.toString(), dropBuilder.toString(), null, null);
15965         //Slog.i(TAG, "Sent to dropbox:");
15966         //Slog.i(TAG, dropBuilder.toString());
15967         synchronized (ActivityManagerService.this) {
15968             long now = SystemClock.uptimeMillis();
15969             if (mLastMemUsageReportTime < now) {
15970                 mLastMemUsageReportTime = now;
15971             }
15972         }
15973     }
15974
15975     /**
15976      * Searches array of arguments for the specified string
15977      * @param args array of argument strings
15978      * @param value value to search for
15979      * @return true if the value is contained in the array
15980      */
15981     private static boolean scanArgs(String[] args, String value) {
15982         if (args != null) {
15983             for (String arg : args) {
15984                 if (value.equals(arg)) {
15985                     return true;
15986                 }
15987             }
15988         }
15989         return false;
15990     }
15991
15992     private final boolean removeDyingProviderLocked(ProcessRecord proc,
15993             ContentProviderRecord cpr, boolean always) {
15994         final boolean inLaunching = mLaunchingProviders.contains(cpr);
15995
15996         if (!inLaunching || always) {
15997             synchronized (cpr) {
15998                 cpr.launchingApp = null;
15999                 cpr.notifyAll();
16000             }
16001             mProviderMap.removeProviderByClass(cpr.name, UserHandle.getUserId(cpr.uid));
16002             String names[] = cpr.info.authority.split(";");
16003             for (int j = 0; j < names.length; j++) {
16004                 mProviderMap.removeProviderByName(names[j], UserHandle.getUserId(cpr.uid));
16005             }
16006         }
16007
16008         for (int i = cpr.connections.size() - 1; i >= 0; i--) {
16009             ContentProviderConnection conn = cpr.connections.get(i);
16010             if (conn.waiting) {
16011                 // If this connection is waiting for the provider, then we don't
16012                 // need to mess with its process unless we are always removing
16013                 // or for some reason the provider is not currently launching.
16014                 if (inLaunching && !always) {
16015                     continue;
16016                 }
16017             }
16018             ProcessRecord capp = conn.client;
16019             conn.dead = true;
16020             if (conn.stableCount > 0) {
16021                 if (!capp.persistent && capp.thread != null
16022                         && capp.pid != 0
16023                         && capp.pid != MY_PID) {
16024                     capp.kill("depends on provider "
16025                             + cpr.name.flattenToShortString()
16026                             + " in dying proc " + (proc != null ? proc.processName : "??"), true);
16027                 }
16028             } else if (capp.thread != null && conn.provider.provider != null) {
16029                 try {
16030                     capp.thread.unstableProviderDied(conn.provider.provider.asBinder());
16031                 } catch (RemoteException e) {
16032                 }
16033                 // In the protocol here, we don't expect the client to correctly
16034                 // clean up this connection, we'll just remove it.
16035                 cpr.connections.remove(i);
16036                 if (conn.client.conProviders.remove(conn)) {
16037                     stopAssociationLocked(capp.uid, capp.processName, cpr.uid, cpr.name);
16038                 }
16039             }
16040         }
16041
16042         if (inLaunching && always) {
16043             mLaunchingProviders.remove(cpr);
16044         }
16045         return inLaunching;
16046     }
16047
16048     /**
16049      * Main code for cleaning up a process when it has gone away.  This is
16050      * called both as a result of the process dying, or directly when stopping
16051      * a process when running in single process mode.
16052      *
16053      * @return Returns true if the given process has been restarted, so the
16054      * app that was passed in must remain on the process lists.
16055      */
16056     private final boolean cleanUpApplicationRecordLocked(ProcessRecord app,
16057             boolean restarting, boolean allowRestart, int index) {
16058         if (index >= 0) {
16059             removeLruProcessLocked(app);
16060             ProcessList.remove(app.pid);
16061         }
16062
16063         mProcessesToGc.remove(app);
16064         mPendingPssProcesses.remove(app);
16065
16066         // Dismiss any open dialogs.
16067         if (app.crashDialog != null && !app.forceCrashReport) {
16068             app.crashDialog.dismiss();
16069             app.crashDialog = null;
16070         }
16071         if (app.anrDialog != null) {
16072             app.anrDialog.dismiss();
16073             app.anrDialog = null;
16074         }
16075         if (app.waitDialog != null) {
16076             app.waitDialog.dismiss();
16077             app.waitDialog = null;
16078         }
16079
16080         app.crashing = false;
16081         app.notResponding = false;
16082
16083         app.resetPackageList(mProcessStats);
16084         app.unlinkDeathRecipient();
16085         app.makeInactive(mProcessStats);
16086         app.waitingToKill = null;
16087         app.forcingToForeground = null;
16088         updateProcessForegroundLocked(app, false, false);
16089         app.foregroundActivities = false;
16090         app.hasShownUi = false;
16091         app.treatLikeActivity = false;
16092         app.hasAboveClient = false;
16093         app.hasClientActivities = false;
16094
16095         mServices.killServicesLocked(app, allowRestart);
16096
16097         boolean restart = false;
16098
16099         // Remove published content providers.
16100         for (int i = app.pubProviders.size() - 1; i >= 0; i--) {
16101             ContentProviderRecord cpr = app.pubProviders.valueAt(i);
16102             final boolean always = app.bad || !allowRestart;
16103             boolean inLaunching = removeDyingProviderLocked(app, cpr, always);
16104             if ((inLaunching || always) && cpr.hasConnectionOrHandle()) {
16105                 // We left the provider in the launching list, need to
16106                 // restart it.
16107                 restart = true;
16108             }
16109
16110             cpr.provider = null;
16111             cpr.proc = null;
16112         }
16113         app.pubProviders.clear();
16114
16115         // Take care of any launching providers waiting for this process.
16116         if (cleanupAppInLaunchingProvidersLocked(app, false)) {
16117             restart = true;
16118         }
16119
16120         // Unregister from connected content providers.
16121         if (!app.conProviders.isEmpty()) {
16122             for (int i = app.conProviders.size() - 1; i >= 0; i--) {
16123                 ContentProviderConnection conn = app.conProviders.get(i);
16124                 conn.provider.connections.remove(conn);
16125                 stopAssociationLocked(app.uid, app.processName, conn.provider.uid,
16126                         conn.provider.name);
16127             }
16128             app.conProviders.clear();
16129         }
16130
16131         // At this point there may be remaining entries in mLaunchingProviders
16132         // where we were the only one waiting, so they are no longer of use.
16133         // Look for these and clean up if found.
16134         // XXX Commented out for now.  Trying to figure out a way to reproduce
16135         // the actual situation to identify what is actually going on.
16136         if (false) {
16137             for (int i = mLaunchingProviders.size() - 1; i >= 0; i--) {
16138                 ContentProviderRecord cpr = mLaunchingProviders.get(i);
16139                 if (cpr.connections.size() <= 0 && !cpr.hasExternalProcessHandles()) {
16140                     synchronized (cpr) {
16141                         cpr.launchingApp = null;
16142                         cpr.notifyAll();
16143                     }
16144                 }
16145             }
16146         }
16147
16148         skipCurrentReceiverLocked(app);
16149
16150         // Unregister any receivers.
16151         for (int i = app.receivers.size() - 1; i >= 0; i--) {
16152             removeReceiverLocked(app.receivers.valueAt(i));
16153         }
16154         app.receivers.clear();
16155
16156         // If the app is undergoing backup, tell the backup manager about it
16157         if (mBackupTarget != null && app.pid == mBackupTarget.app.pid) {
16158             if (DEBUG_BACKUP || DEBUG_CLEANUP) Slog.d(TAG_CLEANUP, "App "
16159                     + mBackupTarget.appInfo + " died during backup");
16160             try {
16161                 IBackupManager bm = IBackupManager.Stub.asInterface(
16162                         ServiceManager.getService(Context.BACKUP_SERVICE));
16163                 bm.agentDisconnected(app.info.packageName);
16164             } catch (RemoteException e) {
16165                 // can't happen; backup manager is local
16166             }
16167         }
16168
16169         for (int i = mPendingProcessChanges.size() - 1; i >= 0; i--) {
16170             ProcessChangeItem item = mPendingProcessChanges.get(i);
16171             if (item.pid == app.pid) {
16172                 mPendingProcessChanges.remove(i);
16173                 mAvailProcessChanges.add(item);
16174             }
16175         }
16176         mUiHandler.obtainMessage(DISPATCH_PROCESS_DIED_UI_MSG, app.pid, app.info.uid,
16177                 null).sendToTarget();
16178
16179         // If the caller is restarting this app, then leave it in its
16180         // current lists and let the caller take care of it.
16181         if (restarting) {
16182             return false;
16183         }
16184
16185         if (!app.persistent || app.isolated) {
16186             if (DEBUG_PROCESSES || DEBUG_CLEANUP) Slog.v(TAG_CLEANUP,
16187                     "Removing non-persistent process during cleanup: " + app);
16188             removeProcessNameLocked(app.processName, app.uid);
16189             if (mHeavyWeightProcess == app) {
16190                 mHandler.sendMessage(mHandler.obtainMessage(CANCEL_HEAVY_NOTIFICATION_MSG,
16191                         mHeavyWeightProcess.userId, 0));
16192                 mHeavyWeightProcess = null;
16193             }
16194         } else if (!app.removed) {
16195             // This app is persistent, so we need to keep its record around.
16196             // If it is not already on the pending app list, add it there
16197             // and start a new process for it.
16198             if (mPersistentStartingProcesses.indexOf(app) < 0) {
16199                 mPersistentStartingProcesses.add(app);
16200                 restart = true;
16201             }
16202         }
16203         if ((DEBUG_PROCESSES || DEBUG_CLEANUP) && mProcessesOnHold.contains(app)) Slog.v(
16204                 TAG_CLEANUP, "Clean-up removing on hold: " + app);
16205         mProcessesOnHold.remove(app);
16206
16207         if (app == mHomeProcess) {
16208             mHomeProcess = null;
16209         }
16210         if (app == mPreviousProcess) {
16211             mPreviousProcess = null;
16212         }
16213
16214         if (restart && !app.isolated) {
16215             // We have components that still need to be running in the
16216             // process, so re-launch it.
16217             if (index < 0) {
16218                 ProcessList.remove(app.pid);
16219             }
16220             addProcessNameLocked(app);
16221             startProcessLocked(app, "restart", app.processName);
16222             return true;
16223         } else if (app.pid > 0 && app.pid != MY_PID) {
16224             // Goodbye!
16225             boolean removed;
16226             synchronized (mPidsSelfLocked) {
16227                 mPidsSelfLocked.remove(app.pid);
16228                 mHandler.removeMessages(PROC_START_TIMEOUT_MSG, app);
16229             }
16230             mBatteryStatsService.noteProcessFinish(app.processName, app.info.uid);
16231             if (app.isolated) {
16232                 mBatteryStatsService.removeIsolatedUid(app.uid, app.info.uid);
16233             }
16234             app.setPid(0);
16235         }
16236         return false;
16237     }
16238
16239     boolean checkAppInLaunchingProvidersLocked(ProcessRecord app) {
16240         for (int i = mLaunchingProviders.size() - 1; i >= 0; i--) {
16241             ContentProviderRecord cpr = mLaunchingProviders.get(i);
16242             if (cpr.launchingApp == app) {
16243                 return true;
16244             }
16245         }
16246         return false;
16247     }
16248
16249     boolean cleanupAppInLaunchingProvidersLocked(ProcessRecord app, boolean alwaysBad) {
16250         // Look through the content providers we are waiting to have launched,
16251         // and if any run in this process then either schedule a restart of
16252         // the process or kill the client waiting for it if this process has
16253         // gone bad.
16254         boolean restart = false;
16255         for (int i = mLaunchingProviders.size() - 1; i >= 0; i--) {
16256             ContentProviderRecord cpr = mLaunchingProviders.get(i);
16257             if (cpr.launchingApp == app) {
16258                 if (!alwaysBad && !app.bad && cpr.hasConnectionOrHandle()) {
16259                     restart = true;
16260                 } else {
16261                     removeDyingProviderLocked(app, cpr, true);
16262                 }
16263             }
16264         }
16265         return restart;
16266     }
16267
16268     // =========================================================
16269     // SERVICES
16270     // =========================================================
16271
16272     @Override
16273     public List<ActivityManager.RunningServiceInfo> getServices(int maxNum,
16274             int flags) {
16275         enforceNotIsolatedCaller("getServices");
16276         synchronized (this) {
16277             return mServices.getRunningServiceInfoLocked(maxNum, flags);
16278         }
16279     }
16280
16281     @Override
16282     public PendingIntent getRunningServiceControlPanel(ComponentName name) {
16283         enforceNotIsolatedCaller("getRunningServiceControlPanel");
16284         synchronized (this) {
16285             return mServices.getRunningServiceControlPanelLocked(name);
16286         }
16287     }
16288
16289     @Override
16290     public ComponentName startService(IApplicationThread caller, Intent service,
16291             String resolvedType, String callingPackage, int userId)
16292             throws TransactionTooLargeException {
16293         enforceNotIsolatedCaller("startService");
16294         // Refuse possible leaked file descriptors
16295         if (service != null && service.hasFileDescriptors() == true) {
16296             throw new IllegalArgumentException("File descriptors passed in Intent");
16297         }
16298
16299         if (callingPackage == null) {
16300             throw new IllegalArgumentException("callingPackage cannot be null");
16301         }
16302
16303         if (DEBUG_SERVICE) Slog.v(TAG_SERVICE,
16304                 "startService: " + service + " type=" + resolvedType);
16305         synchronized(this) {
16306             final int callingPid = Binder.getCallingPid();
16307             final int callingUid = Binder.getCallingUid();
16308             final long origId = Binder.clearCallingIdentity();
16309             ComponentName res = mServices.startServiceLocked(caller, service,
16310                     resolvedType, callingPid, callingUid, callingPackage, userId);
16311             Binder.restoreCallingIdentity(origId);
16312             return res;
16313         }
16314     }
16315
16316     ComponentName startServiceInPackage(int uid, Intent service, String resolvedType,
16317             String callingPackage, int userId)
16318             throws TransactionTooLargeException {
16319         synchronized(this) {
16320             if (DEBUG_SERVICE) Slog.v(TAG_SERVICE,
16321                     "startServiceInPackage: " + service + " type=" + resolvedType);
16322             final long origId = Binder.clearCallingIdentity();
16323             ComponentName res = mServices.startServiceLocked(null, service,
16324                     resolvedType, -1, uid, callingPackage, userId);
16325             Binder.restoreCallingIdentity(origId);
16326             return res;
16327         }
16328     }
16329
16330     @Override
16331     public int stopService(IApplicationThread caller, Intent service,
16332             String resolvedType, int userId) {
16333         enforceNotIsolatedCaller("stopService");
16334         // Refuse possible leaked file descriptors
16335         if (service != null && service.hasFileDescriptors() == true) {
16336             throw new IllegalArgumentException("File descriptors passed in Intent");
16337         }
16338
16339         synchronized(this) {
16340             return mServices.stopServiceLocked(caller, service, resolvedType, userId);
16341         }
16342     }
16343
16344     @Override
16345     public IBinder peekService(Intent service, String resolvedType, String callingPackage) {
16346         enforceNotIsolatedCaller("peekService");
16347         // Refuse possible leaked file descriptors
16348         if (service != null && service.hasFileDescriptors() == true) {
16349             throw new IllegalArgumentException("File descriptors passed in Intent");
16350         }
16351
16352         if (callingPackage == null) {
16353             throw new IllegalArgumentException("callingPackage cannot be null");
16354         }
16355
16356         synchronized(this) {
16357             return mServices.peekServiceLocked(service, resolvedType, callingPackage);
16358         }
16359     }
16360
16361     @Override
16362     public boolean stopServiceToken(ComponentName className, IBinder token,
16363             int startId) {
16364         synchronized(this) {
16365             return mServices.stopServiceTokenLocked(className, token, startId);
16366         }
16367     }
16368
16369     @Override
16370     public void setServiceForeground(ComponentName className, IBinder token,
16371             int id, Notification notification, boolean removeNotification) {
16372         synchronized(this) {
16373             mServices.setServiceForegroundLocked(className, token, id, notification,
16374                     removeNotification);
16375         }
16376     }
16377
16378     @Override
16379     public int handleIncomingUser(int callingPid, int callingUid, int userId, boolean allowAll,
16380             boolean requireFull, String name, String callerPackage) {
16381         return mUserController.handleIncomingUser(callingPid, callingUid, userId, allowAll,
16382                 requireFull ? ALLOW_FULL_ONLY : ALLOW_NON_FULL, name, callerPackage);
16383     }
16384
16385     boolean isSingleton(String componentProcessName, ApplicationInfo aInfo,
16386             String className, int flags) {
16387         boolean result = false;
16388         // For apps that don't have pre-defined UIDs, check for permission
16389         if (UserHandle.getAppId(aInfo.uid) >= Process.FIRST_APPLICATION_UID) {
16390             if ((flags & ServiceInfo.FLAG_SINGLE_USER) != 0) {
16391                 if (ActivityManager.checkUidPermission(
16392                         INTERACT_ACROSS_USERS,
16393                         aInfo.uid) != PackageManager.PERMISSION_GRANTED) {
16394                     ComponentName comp = new ComponentName(aInfo.packageName, className);
16395                     String msg = "Permission Denial: Component " + comp.flattenToShortString()
16396                             + " requests FLAG_SINGLE_USER, but app does not hold "
16397                             + INTERACT_ACROSS_USERS;
16398                     Slog.w(TAG, msg);
16399                     throw new SecurityException(msg);
16400                 }
16401                 // Permission passed
16402                 result = true;
16403             }
16404         } else if ("system".equals(componentProcessName)) {
16405             result = true;
16406         } else if ((flags & ServiceInfo.FLAG_SINGLE_USER) != 0) {
16407             // Phone app and persistent apps are allowed to export singleuser providers.
16408             result = UserHandle.isSameApp(aInfo.uid, Process.PHONE_UID)
16409                     || (aInfo.flags & ApplicationInfo.FLAG_PERSISTENT) != 0;
16410         }
16411         if (DEBUG_MU) Slog.v(TAG_MU,
16412                 "isSingleton(" + componentProcessName + ", " + aInfo + ", " + className + ", 0x"
16413                 + Integer.toHexString(flags) + ") = " + result);
16414         return result;
16415     }
16416
16417     /**
16418      * Checks to see if the caller is in the same app as the singleton
16419      * component, or the component is in a special app. It allows special apps
16420      * to export singleton components but prevents exporting singleton
16421      * components for regular apps.
16422      */
16423     boolean isValidSingletonCall(int callingUid, int componentUid) {
16424         int componentAppId = UserHandle.getAppId(componentUid);
16425         return UserHandle.isSameApp(callingUid, componentUid)
16426                 || componentAppId == Process.SYSTEM_UID
16427                 || componentAppId == Process.PHONE_UID
16428                 || ActivityManager.checkUidPermission(INTERACT_ACROSS_USERS_FULL, componentUid)
16429                         == PackageManager.PERMISSION_GRANTED;
16430     }
16431
16432     public int bindService(IApplicationThread caller, IBinder token, Intent service,
16433             String resolvedType, IServiceConnection connection, int flags, String callingPackage,
16434             int userId) throws TransactionTooLargeException {
16435         enforceNotIsolatedCaller("bindService");
16436
16437         // Refuse possible leaked file descriptors
16438         if (service != null && service.hasFileDescriptors() == true) {
16439             throw new IllegalArgumentException("File descriptors passed in Intent");
16440         }
16441
16442         if (callingPackage == null) {
16443             throw new IllegalArgumentException("callingPackage cannot be null");
16444         }
16445
16446         synchronized(this) {
16447             return mServices.bindServiceLocked(caller, token, service,
16448                     resolvedType, connection, flags, callingPackage, userId);
16449         }
16450     }
16451
16452     public boolean unbindService(IServiceConnection connection) {
16453         synchronized (this) {
16454             return mServices.unbindServiceLocked(connection);
16455         }
16456     }
16457
16458     public void publishService(IBinder token, Intent intent, IBinder service) {
16459         // Refuse possible leaked file descriptors
16460         if (intent != null && intent.hasFileDescriptors() == true) {
16461             throw new IllegalArgumentException("File descriptors passed in Intent");
16462         }
16463
16464         synchronized(this) {
16465             if (!(token instanceof ServiceRecord)) {
16466                 throw new IllegalArgumentException("Invalid service token");
16467             }
16468             mServices.publishServiceLocked((ServiceRecord)token, intent, service);
16469         }
16470     }
16471
16472     public void unbindFinished(IBinder token, Intent intent, boolean doRebind) {
16473         // Refuse possible leaked file descriptors
16474         if (intent != null && intent.hasFileDescriptors() == true) {
16475             throw new IllegalArgumentException("File descriptors passed in Intent");
16476         }
16477
16478         synchronized(this) {
16479             mServices.unbindFinishedLocked((ServiceRecord)token, intent, doRebind);
16480         }
16481     }
16482
16483     public void serviceDoneExecuting(IBinder token, int type, int startId, int res) {
16484         synchronized(this) {
16485             if (!(token instanceof ServiceRecord)) {
16486                 Slog.e(TAG, "serviceDoneExecuting: Invalid service token=" + token);
16487                 throw new IllegalArgumentException("Invalid service token");
16488             }
16489             mServices.serviceDoneExecutingLocked((ServiceRecord)token, type, startId, res);
16490         }
16491     }
16492
16493     // =========================================================
16494     // BACKUP AND RESTORE
16495     // =========================================================
16496
16497     // Cause the target app to be launched if necessary and its backup agent
16498     // instantiated.  The backup agent will invoke backupAgentCreated() on the
16499     // activity manager to announce its creation.
16500     public boolean bindBackupAgent(ApplicationInfo app, int backupMode) {
16501         if (DEBUG_BACKUP) Slog.v(TAG_BACKUP,
16502                 "bindBackupAgent: app=" + app + " mode=" + backupMode);
16503         enforceCallingPermission("android.permission.CONFIRM_FULL_BACKUP", "bindBackupAgent");
16504
16505         synchronized(this) {
16506             // !!! TODO: currently no check here that we're already bound
16507             BatteryStatsImpl.Uid.Pkg.Serv ss = null;
16508             BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
16509             synchronized (stats) {
16510                 ss = stats.getServiceStatsLocked(app.uid, app.packageName, app.name);
16511             }
16512
16513             // Backup agent is now in use, its package can't be stopped.
16514             try {
16515                 AppGlobals.getPackageManager().setPackageStoppedState(
16516                         app.packageName, false, UserHandle.getUserId(app.uid));
16517             } catch (RemoteException e) {
16518             } catch (IllegalArgumentException e) {
16519                 Slog.w(TAG, "Failed trying to unstop package "
16520                         + app.packageName + ": " + e);
16521             }
16522
16523             BackupRecord r = new BackupRecord(ss, app, backupMode);
16524             ComponentName hostingName = (backupMode == IApplicationThread.BACKUP_MODE_INCREMENTAL)
16525                     ? new ComponentName(app.packageName, app.backupAgentName)
16526                     : new ComponentName("android", "FullBackupAgent");
16527             // startProcessLocked() returns existing proc's record if it's already running
16528             ProcessRecord proc = startProcessLocked(app.processName, app,
16529                     false, 0, "backup", hostingName, false, false, false);
16530             if (proc == null) {
16531                 Slog.e(TAG, "Unable to start backup agent process " + r);
16532                 return false;
16533             }
16534
16535             r.app = proc;
16536             mBackupTarget = r;
16537             mBackupAppName = app.packageName;
16538
16539             // Try not to kill the process during backup
16540             updateOomAdjLocked(proc);
16541
16542             // If the process is already attached, schedule the creation of the backup agent now.
16543             // If it is not yet live, this will be done when it attaches to the framework.
16544             if (proc.thread != null) {
16545                 if (DEBUG_BACKUP) Slog.v(TAG_BACKUP, "Agent proc already running: " + proc);
16546                 try {
16547                     proc.thread.scheduleCreateBackupAgent(app,
16548                             compatibilityInfoForPackageLocked(app), backupMode);
16549                 } catch (RemoteException e) {
16550                     // Will time out on the backup manager side
16551                 }
16552             } else {
16553                 if (DEBUG_BACKUP) Slog.v(TAG_BACKUP, "Agent proc not running, waiting for attach");
16554             }
16555             // Invariants: at this point, the target app process exists and the application
16556             // is either already running or in the process of coming up.  mBackupTarget and
16557             // mBackupAppName describe the app, so that when it binds back to the AM we
16558             // know that it's scheduled for a backup-agent operation.
16559         }
16560
16561         return true;
16562     }
16563
16564     @Override
16565     public void clearPendingBackup() {
16566         if (DEBUG_BACKUP) Slog.v(TAG_BACKUP, "clearPendingBackup");
16567         enforceCallingPermission("android.permission.BACKUP", "clearPendingBackup");
16568
16569         synchronized (this) {
16570             mBackupTarget = null;
16571             mBackupAppName = null;
16572         }
16573     }
16574
16575     // A backup agent has just come up
16576     public void backupAgentCreated(String agentPackageName, IBinder agent) {
16577         if (DEBUG_BACKUP) Slog.v(TAG_BACKUP, "backupAgentCreated: " + agentPackageName
16578                 + " = " + agent);
16579
16580         synchronized(this) {
16581             if (!agentPackageName.equals(mBackupAppName)) {
16582                 Slog.e(TAG, "Backup agent created for " + agentPackageName + " but not requested!");
16583                 return;
16584             }
16585         }
16586
16587         long oldIdent = Binder.clearCallingIdentity();
16588         try {
16589             IBackupManager bm = IBackupManager.Stub.asInterface(
16590                     ServiceManager.getService(Context.BACKUP_SERVICE));
16591             bm.agentConnected(agentPackageName, agent);
16592         } catch (RemoteException e) {
16593             // can't happen; the backup manager service is local
16594         } catch (Exception e) {
16595             Slog.w(TAG, "Exception trying to deliver BackupAgent binding: ");
16596             e.printStackTrace();
16597         } finally {
16598             Binder.restoreCallingIdentity(oldIdent);
16599         }
16600     }
16601
16602     // done with this agent
16603     public void unbindBackupAgent(ApplicationInfo appInfo) {
16604         if (DEBUG_BACKUP) Slog.v(TAG_BACKUP, "unbindBackupAgent: " + appInfo);
16605         if (appInfo == null) {
16606             Slog.w(TAG, "unbind backup agent for null app");
16607             return;
16608         }
16609
16610         synchronized(this) {
16611             try {
16612                 if (mBackupAppName == null) {
16613                     Slog.w(TAG, "Unbinding backup agent with no active backup");
16614                     return;
16615                 }
16616
16617                 if (!mBackupAppName.equals(appInfo.packageName)) {
16618                     Slog.e(TAG, "Unbind of " + appInfo + " but is not the current backup target");
16619                     return;
16620                 }
16621
16622                 // Not backing this app up any more; reset its OOM adjustment
16623                 final ProcessRecord proc = mBackupTarget.app;
16624                 updateOomAdjLocked(proc);
16625
16626                 // If the app crashed during backup, 'thread' will be null here
16627                 if (proc.thread != null) {
16628                     try {
16629                         proc.thread.scheduleDestroyBackupAgent(appInfo,
16630                                 compatibilityInfoForPackageLocked(appInfo));
16631                     } catch (Exception e) {
16632                         Slog.e(TAG, "Exception when unbinding backup agent:");
16633                         e.printStackTrace();
16634                     }
16635                 }
16636             } finally {
16637                 mBackupTarget = null;
16638                 mBackupAppName = null;
16639             }
16640         }
16641     }
16642     // =========================================================
16643     // BROADCASTS
16644     // =========================================================
16645
16646     boolean isPendingBroadcastProcessLocked(int pid) {
16647         return mFgBroadcastQueue.isPendingBroadcastProcessLocked(pid)
16648                 || mBgBroadcastQueue.isPendingBroadcastProcessLocked(pid);
16649     }
16650
16651     void skipPendingBroadcastLocked(int pid) {
16652             Slog.w(TAG, "Unattached app died before broadcast acknowledged, skipping");
16653             for (BroadcastQueue queue : mBroadcastQueues) {
16654                 queue.skipPendingBroadcastLocked(pid);
16655             }
16656     }
16657
16658     // The app just attached; send any pending broadcasts that it should receive
16659     boolean sendPendingBroadcastsLocked(ProcessRecord app) {
16660         boolean didSomething = false;
16661         for (BroadcastQueue queue : mBroadcastQueues) {
16662             didSomething |= queue.sendPendingBroadcastsLocked(app);
16663         }
16664         return didSomething;
16665     }
16666
16667     public Intent registerReceiver(IApplicationThread caller, String callerPackage,
16668             IIntentReceiver receiver, IntentFilter filter, String permission, int userId) {
16669         enforceNotIsolatedCaller("registerReceiver");
16670         ArrayList<Intent> stickyIntents = null;
16671         ProcessRecord callerApp = null;
16672         int callingUid;
16673         int callingPid;
16674         synchronized(this) {
16675             if (caller != null) {
16676                 callerApp = getRecordForAppLocked(caller);
16677                 if (callerApp == null) {
16678                     throw new SecurityException(
16679                             "Unable to find app for caller " + caller
16680                             + " (pid=" + Binder.getCallingPid()
16681                             + ") when registering receiver " + receiver);
16682                 }
16683                 if (callerApp.info.uid != Process.SYSTEM_UID &&
16684                         !callerApp.pkgList.containsKey(callerPackage) &&
16685                         !"android".equals(callerPackage)) {
16686                     throw new SecurityException("Given caller package " + callerPackage
16687                             + " is not running in process " + callerApp);
16688                 }
16689                 callingUid = callerApp.info.uid;
16690                 callingPid = callerApp.pid;
16691             } else {
16692                 callerPackage = null;
16693                 callingUid = Binder.getCallingUid();
16694                 callingPid = Binder.getCallingPid();
16695             }
16696
16697             userId = mUserController.handleIncomingUser(callingPid, callingUid, userId, true,
16698                     ALLOW_FULL_ONLY, "registerReceiver", callerPackage);
16699
16700             Iterator<String> actions = filter.actionsIterator();
16701             if (actions == null) {
16702                 ArrayList<String> noAction = new ArrayList<String>(1);
16703                 noAction.add(null);
16704                 actions = noAction.iterator();
16705             }
16706
16707             // Collect stickies of users
16708             int[] userIds = { UserHandle.USER_ALL, UserHandle.getUserId(callingUid) };
16709             while (actions.hasNext()) {
16710                 String action = actions.next();
16711                 for (int id : userIds) {
16712                     ArrayMap<String, ArrayList<Intent>> stickies = mStickyBroadcasts.get(id);
16713                     if (stickies != null) {
16714                         ArrayList<Intent> intents = stickies.get(action);
16715                         if (intents != null) {
16716                             if (stickyIntents == null) {
16717                                 stickyIntents = new ArrayList<Intent>();
16718                             }
16719                             stickyIntents.addAll(intents);
16720                         }
16721                     }
16722                 }
16723             }
16724         }
16725
16726         ArrayList<Intent> allSticky = null;
16727         if (stickyIntents != null) {
16728             final ContentResolver resolver = mContext.getContentResolver();
16729             // Look for any matching sticky broadcasts...
16730             for (int i = 0, N = stickyIntents.size(); i < N; i++) {
16731                 Intent intent = stickyIntents.get(i);
16732                 // If intent has scheme "content", it will need to acccess
16733                 // provider that needs to lock mProviderMap in ActivityThread
16734                 // and also it may need to wait application response, so we
16735                 // cannot lock ActivityManagerService here.
16736                 if (filter.match(resolver, intent, true, TAG) >= 0) {
16737                     if (allSticky == null) {
16738                         allSticky = new ArrayList<Intent>();
16739                     }
16740                     allSticky.add(intent);
16741                 }
16742             }
16743         }
16744
16745         // The first sticky in the list is returned directly back to the client.
16746         Intent sticky = allSticky != null ? allSticky.get(0) : null;
16747         if (DEBUG_BROADCAST) Slog.v(TAG_BROADCAST, "Register receiver " + filter + ": " + sticky);
16748         if (receiver == null) {
16749             return sticky;
16750         }
16751
16752         synchronized (this) {
16753             if (callerApp != null && (callerApp.thread == null
16754                     || callerApp.thread.asBinder() != caller.asBinder())) {
16755                 // Original caller already died
16756                 return null;
16757             }
16758             ReceiverList rl = mRegisteredReceivers.get(receiver.asBinder());
16759             if (rl == null) {
16760                 rl = new ReceiverList(this, callerApp, callingPid, callingUid,
16761                         userId, receiver);
16762                 if (rl.app != null) {
16763                     rl.app.receivers.add(rl);
16764                 } else {
16765                     try {
16766                         receiver.asBinder().linkToDeath(rl, 0);
16767                     } catch (RemoteException e) {
16768                         return sticky;
16769                     }
16770                     rl.linkedToDeath = true;
16771                 }
16772                 mRegisteredReceivers.put(receiver.asBinder(), rl);
16773             } else if (rl.uid != callingUid) {
16774                 throw new IllegalArgumentException(
16775                         "Receiver requested to register for uid " + callingUid
16776                         + " was previously registered for uid " + rl.uid);
16777             } else if (rl.pid != callingPid) {
16778                 throw new IllegalArgumentException(
16779                         "Receiver requested to register for pid " + callingPid
16780                         + " was previously registered for pid " + rl.pid);
16781             } else if (rl.userId != userId) {
16782                 throw new IllegalArgumentException(
16783                         "Receiver requested to register for user " + userId
16784                         + " was previously registered for user " + rl.userId);
16785             }
16786             BroadcastFilter bf = new BroadcastFilter(filter, rl, callerPackage,
16787                     permission, callingUid, userId);
16788             rl.add(bf);
16789             if (!bf.debugCheck()) {
16790                 Slog.w(TAG, "==> For Dynamic broadcast");
16791             }
16792             mReceiverResolver.addFilter(bf);
16793
16794             // Enqueue broadcasts for all existing stickies that match
16795             // this filter.
16796             if (allSticky != null) {
16797                 ArrayList receivers = new ArrayList();
16798                 receivers.add(bf);
16799
16800                 final int stickyCount = allSticky.size();
16801                 for (int i = 0; i < stickyCount; i++) {
16802                     Intent intent = allSticky.get(i);
16803                     BroadcastQueue queue = broadcastQueueForIntent(intent);
16804                     BroadcastRecord r = new BroadcastRecord(queue, intent, null,
16805                             null, -1, -1, null, null, AppOpsManager.OP_NONE, null, receivers,
16806                             null, 0, null, null, false, true, true, -1);
16807                     queue.enqueueParallelBroadcastLocked(r);
16808                     queue.scheduleBroadcastsLocked();
16809                 }
16810             }
16811
16812             return sticky;
16813         }
16814     }
16815
16816     public void unregisterReceiver(IIntentReceiver receiver) {
16817         if (DEBUG_BROADCAST) Slog.v(TAG_BROADCAST, "Unregister receiver: " + receiver);
16818
16819         final long origId = Binder.clearCallingIdentity();
16820         try {
16821             boolean doTrim = false;
16822
16823             synchronized(this) {
16824                 ReceiverList rl = mRegisteredReceivers.get(receiver.asBinder());
16825                 if (rl != null) {
16826                     final BroadcastRecord r = rl.curBroadcast;
16827                     if (r != null && r == r.queue.getMatchingOrderedReceiver(r)) {
16828                         final boolean doNext = r.queue.finishReceiverLocked(
16829                                 r, r.resultCode, r.resultData, r.resultExtras,
16830                                 r.resultAbort, false);
16831                         if (doNext) {
16832                             doTrim = true;
16833                             r.queue.processNextBroadcast(false);
16834                         }
16835                     }
16836
16837                     if (rl.app != null) {
16838                         rl.app.receivers.remove(rl);
16839                     }
16840                     removeReceiverLocked(rl);
16841                     if (rl.linkedToDeath) {
16842                         rl.linkedToDeath = false;
16843                         rl.receiver.asBinder().unlinkToDeath(rl, 0);
16844                     }
16845                 }
16846             }
16847
16848             // If we actually concluded any broadcasts, we might now be able
16849             // to trim the recipients' apps from our working set
16850             if (doTrim) {
16851                 trimApplications();
16852                 return;
16853             }
16854
16855         } finally {
16856             Binder.restoreCallingIdentity(origId);
16857         }
16858     }
16859
16860     void removeReceiverLocked(ReceiverList rl) {
16861         mRegisteredReceivers.remove(rl.receiver.asBinder());
16862         for (int i = rl.size() - 1; i >= 0; i--) {
16863             mReceiverResolver.removeFilter(rl.get(i));
16864         }
16865     }
16866
16867     private final void sendPackageBroadcastLocked(int cmd, String[] packages, int userId) {
16868         for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) {
16869             ProcessRecord r = mLruProcesses.get(i);
16870             if (r.thread != null && (userId == UserHandle.USER_ALL || r.userId == userId)) {
16871                 try {
16872                     r.thread.dispatchPackageBroadcast(cmd, packages);
16873                 } catch (RemoteException ex) {
16874                 }
16875             }
16876         }
16877     }
16878
16879     private List<ResolveInfo> collectReceiverComponents(Intent intent, String resolvedType,
16880             int callingUid, int[] users) {
16881         List<ResolveInfo> receivers = null;
16882         try {
16883             HashSet<ComponentName> singleUserReceivers = null;
16884             boolean scannedFirstReceivers = false;
16885             for (int user : users) {
16886                 // Skip users that have Shell restrictions
16887                 if (callingUid == Process.SHELL_UID
16888                         && mUserController.hasUserRestriction(
16889                         UserManager.DISALLOW_DEBUGGING_FEATURES, user)) {
16890                     continue;
16891                 }
16892                 List<ResolveInfo> newReceivers = AppGlobals.getPackageManager()
16893                         .queryIntentReceivers(intent, resolvedType, STOCK_PM_FLAGS, user);
16894                 if (user != UserHandle.USER_SYSTEM && newReceivers != null) {
16895                     // If this is not the system user, we need to check for
16896                     // any receivers that should be filtered out.
16897                     for (int i=0; i<newReceivers.size(); i++) {
16898                         ResolveInfo ri = newReceivers.get(i);
16899                         if ((ri.activityInfo.flags&ActivityInfo.FLAG_SYSTEM_USER_ONLY) != 0) {
16900                             newReceivers.remove(i);
16901                             i--;
16902                         }
16903                     }
16904                 }
16905                 if (newReceivers != null && newReceivers.size() == 0) {
16906                     newReceivers = null;
16907                 }
16908                 if (receivers == null) {
16909                     receivers = newReceivers;
16910                 } else if (newReceivers != null) {
16911                     // We need to concatenate the additional receivers
16912                     // found with what we have do far.  This would be easy,
16913                     // but we also need to de-dup any receivers that are
16914                     // singleUser.
16915                     if (!scannedFirstReceivers) {
16916                         // Collect any single user receivers we had already retrieved.
16917                         scannedFirstReceivers = true;
16918                         for (int i=0; i<receivers.size(); i++) {
16919                             ResolveInfo ri = receivers.get(i);
16920                             if ((ri.activityInfo.flags&ActivityInfo.FLAG_SINGLE_USER) != 0) {
16921                                 ComponentName cn = new ComponentName(
16922                                         ri.activityInfo.packageName, ri.activityInfo.name);
16923                                 if (singleUserReceivers == null) {
16924                                     singleUserReceivers = new HashSet<ComponentName>();
16925                                 }
16926                                 singleUserReceivers.add(cn);
16927                             }
16928                         }
16929                     }
16930                     // Add the new results to the existing results, tracking
16931                     // and de-dupping single user receivers.
16932                     for (int i=0; i<newReceivers.size(); i++) {
16933                         ResolveInfo ri = newReceivers.get(i);
16934                         if ((ri.activityInfo.flags&ActivityInfo.FLAG_SINGLE_USER) != 0) {
16935                             ComponentName cn = new ComponentName(
16936                                     ri.activityInfo.packageName, ri.activityInfo.name);
16937                             if (singleUserReceivers == null) {
16938                                 singleUserReceivers = new HashSet<ComponentName>();
16939                             }
16940                             if (!singleUserReceivers.contains(cn)) {
16941                                 singleUserReceivers.add(cn);
16942                                 receivers.add(ri);
16943                             }
16944                         } else {
16945                             receivers.add(ri);
16946                         }
16947                     }
16948                 }
16949             }
16950         } catch (RemoteException ex) {
16951             // pm is in same process, this will never happen.
16952         }
16953         return receivers;
16954     }
16955
16956     final int broadcastIntentLocked(ProcessRecord callerApp,
16957             String callerPackage, Intent intent, String resolvedType,
16958             IIntentReceiver resultTo, int resultCode, String resultData,
16959             Bundle resultExtras, String[] requiredPermissions, int appOp, Bundle bOptions,
16960             boolean ordered, boolean sticky, int callingPid, int callingUid, int userId) {
16961         intent = new Intent(intent);
16962
16963         // By default broadcasts do not go to stopped apps.
16964         intent.addFlags(Intent.FLAG_EXCLUDE_STOPPED_PACKAGES);
16965
16966         // If we have not finished booting, don't allow this to launch new processes.
16967         if (!mProcessesReady && (intent.getFlags()&Intent.FLAG_RECEIVER_BOOT_UPGRADE) == 0) {
16968             intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY);
16969         }
16970
16971         if (DEBUG_BROADCAST_LIGHT) Slog.v(TAG_BROADCAST,
16972                 (sticky ? "Broadcast sticky: ": "Broadcast: ") + intent
16973                 + " ordered=" + ordered + " userid=" + userId);
16974         if ((resultTo != null) && !ordered) {
16975             Slog.w(TAG, "Broadcast " + intent + " not ordered but result callback requested!");
16976         }
16977
16978         userId = mUserController.handleIncomingUser(callingPid, callingUid, userId, true,
16979                 ALLOW_NON_FULL, "broadcast", callerPackage);
16980
16981         // Make sure that the user who is receiving this broadcast is running.
16982         // If not, we will just skip it. Make an exception for shutdown broadcasts
16983         // and upgrade steps.
16984
16985         if (userId != UserHandle.USER_ALL && !mUserController.isUserRunningLocked(userId, 0)) {
16986             if ((callingUid != Process.SYSTEM_UID
16987                     || (intent.getFlags() & Intent.FLAG_RECEIVER_BOOT_UPGRADE) == 0)
16988                     && !Intent.ACTION_SHUTDOWN.equals(intent.getAction())) {
16989                 Slog.w(TAG, "Skipping broadcast of " + intent
16990                         + ": user " + userId + " is stopped");
16991                 return ActivityManager.BROADCAST_FAILED_USER_STOPPED;
16992             }
16993         }
16994
16995         BroadcastOptions brOptions = null;
16996         if (bOptions != null) {
16997             brOptions = new BroadcastOptions(bOptions);
16998             if (brOptions.getTemporaryAppWhitelistDuration() > 0) {
16999                 // See if the caller is allowed to do this.  Note we are checking against
17000                 // the actual real caller (not whoever provided the operation as say a
17001                 // PendingIntent), because that who is actually supplied the arguments.
17002                 if (checkComponentPermission(
17003                         android.Manifest.permission.CHANGE_DEVICE_IDLE_TEMP_WHITELIST,
17004                         Binder.getCallingPid(), Binder.getCallingUid(), -1, true)
17005                         != PackageManager.PERMISSION_GRANTED) {
17006                     String msg = "Permission Denial: " + intent.getAction()
17007                             + " broadcast from " + callerPackage + " (pid=" + callingPid
17008                             + ", uid=" + callingUid + ")"
17009                             + " requires "
17010                             + android.Manifest.permission.CHANGE_DEVICE_IDLE_TEMP_WHITELIST;
17011                     Slog.w(TAG, msg);
17012                     throw new SecurityException(msg);
17013                 }
17014             }
17015         }
17016
17017         /*
17018          * Prevent non-system code (defined here to be non-persistent
17019          * processes) from sending protected broadcasts.
17020          */
17021         int callingAppId = UserHandle.getAppId(callingUid);
17022         if (callingAppId == Process.SYSTEM_UID || callingAppId == Process.PHONE_UID
17023             || callingAppId == Process.SHELL_UID || callingAppId == Process.BLUETOOTH_UID
17024             || callingAppId == Process.NFC_UID || callingUid == 0) {
17025             // Always okay.
17026         } else if (callerApp == null || !callerApp.persistent) {
17027             try {
17028                 if (AppGlobals.getPackageManager().isProtectedBroadcast(
17029                         intent.getAction())) {
17030                     String msg = "Permission Denial: not allowed to send broadcast "
17031                             + intent.getAction() + " from pid="
17032                             + callingPid + ", uid=" + callingUid;
17033                     Slog.w(TAG, msg);
17034                     throw new SecurityException(msg);
17035                 } else if (AppWidgetManager.ACTION_APPWIDGET_CONFIGURE.equals(intent.getAction())) {
17036                     // Special case for compatibility: we don't want apps to send this,
17037                     // but historically it has not been protected and apps may be using it
17038                     // to poke their own app widget.  So, instead of making it protected,
17039                     // just limit it to the caller.
17040                     if (callerApp == null) {
17041                         String msg = "Permission Denial: not allowed to send broadcast "
17042                                 + intent.getAction() + " from unknown caller.";
17043                         Slog.w(TAG, msg);
17044                         throw new SecurityException(msg);
17045                     } else if (intent.getComponent() != null) {
17046                         // They are good enough to send to an explicit component...  verify
17047                         // it is being sent to the calling app.
17048                         if (!intent.getComponent().getPackageName().equals(
17049                                 callerApp.info.packageName)) {
17050                             String msg = "Permission Denial: not allowed to send broadcast "
17051                                     + intent.getAction() + " to "
17052                                     + intent.getComponent().getPackageName() + " from "
17053                                     + callerApp.info.packageName;
17054                             Slog.w(TAG, msg);
17055                             throw new SecurityException(msg);
17056                         }
17057                     } else {
17058                         // Limit broadcast to their own package.
17059                         intent.setPackage(callerApp.info.packageName);
17060                     }
17061                 }
17062             } catch (RemoteException e) {
17063                 Slog.w(TAG, "Remote exception", e);
17064                 return ActivityManager.BROADCAST_SUCCESS;
17065             }
17066         }
17067
17068         final String action = intent.getAction();
17069         if (action != null) {
17070             switch (action) {
17071                 case Intent.ACTION_UID_REMOVED:
17072                 case Intent.ACTION_PACKAGE_REMOVED:
17073                 case Intent.ACTION_PACKAGE_CHANGED:
17074                 case Intent.ACTION_EXTERNAL_APPLICATIONS_UNAVAILABLE:
17075                 case Intent.ACTION_EXTERNAL_APPLICATIONS_AVAILABLE:
17076                     // Handle special intents: if this broadcast is from the package
17077                     // manager about a package being removed, we need to remove all of
17078                     // its activities from the history stack.
17079                     if (checkComponentPermission(
17080                             android.Manifest.permission.BROADCAST_PACKAGE_REMOVED,
17081                             callingPid, callingUid, -1, true)
17082                             != PackageManager.PERMISSION_GRANTED) {
17083                         String msg = "Permission Denial: " + intent.getAction()
17084                                 + " broadcast from " + callerPackage + " (pid=" + callingPid
17085                                 + ", uid=" + callingUid + ")"
17086                                 + " requires "
17087                                 + android.Manifest.permission.BROADCAST_PACKAGE_REMOVED;
17088                         Slog.w(TAG, msg);
17089                         throw new SecurityException(msg);
17090                     }
17091                     switch (action) {
17092                         case Intent.ACTION_UID_REMOVED:
17093                             final Bundle intentExtras = intent.getExtras();
17094                             final int uid = intentExtras != null
17095                                     ? intentExtras.getInt(Intent.EXTRA_UID) : -1;
17096                             if (uid >= 0) {
17097                                 mBatteryStatsService.removeUid(uid);
17098                                 mAppOpsService.uidRemoved(uid);
17099                             }
17100                             break;
17101                         case Intent.ACTION_EXTERNAL_APPLICATIONS_UNAVAILABLE:
17102                             // If resources are unavailable just force stop all those packages
17103                             // and flush the attribute cache as well.
17104                             String list[] =
17105                                     intent.getStringArrayExtra(Intent.EXTRA_CHANGED_PACKAGE_LIST);
17106                             if (list != null && list.length > 0) {
17107                                 for (int i = 0; i < list.length; i++) {
17108                                     forceStopPackageLocked(list[i], -1, false, true, true,
17109                                             false, false, userId, "storage unmount");
17110                                 }
17111                                 mRecentTasks.cleanupLocked(UserHandle.USER_ALL);
17112                                 sendPackageBroadcastLocked(
17113                                         IApplicationThread.EXTERNAL_STORAGE_UNAVAILABLE, list,
17114                                         userId);
17115                             }
17116                             break;
17117                         case Intent.ACTION_EXTERNAL_APPLICATIONS_AVAILABLE:
17118                             mRecentTasks.cleanupLocked(UserHandle.USER_ALL);
17119                             break;
17120                         case Intent.ACTION_PACKAGE_REMOVED:
17121                         case Intent.ACTION_PACKAGE_CHANGED:
17122                             Uri data = intent.getData();
17123                             String ssp;
17124                             if (data != null && (ssp=data.getSchemeSpecificPart()) != null) {
17125                                 boolean removed = Intent.ACTION_PACKAGE_REMOVED.equals(action);
17126                                 boolean fullUninstall = removed &&
17127                                         !intent.getBooleanExtra(Intent.EXTRA_REPLACING, false);
17128                                 final boolean killProcess =
17129                                         !intent.getBooleanExtra(Intent.EXTRA_DONT_KILL_APP, false);
17130                                 if (killProcess) {
17131                                     forceStopPackageLocked(ssp, UserHandle.getAppId(
17132                                             intent.getIntExtra(Intent.EXTRA_UID, -1)),
17133                                             false, true, true, false, fullUninstall, userId,
17134                                             removed ? "pkg removed" : "pkg changed");
17135                                 }
17136                                 if (removed) {
17137                                     sendPackageBroadcastLocked(IApplicationThread.PACKAGE_REMOVED,
17138                                             new String[] {ssp}, userId);
17139                                     if (fullUninstall) {
17140                                         mAppOpsService.packageRemoved(
17141                                                 intent.getIntExtra(Intent.EXTRA_UID, -1), ssp);
17142
17143                                         // Remove all permissions granted from/to this package
17144                                         removeUriPermissionsForPackageLocked(ssp, userId, true);
17145
17146                                         removeTasksByPackageNameLocked(ssp, userId);
17147                                         mBatteryStatsService.notePackageUninstalled(ssp);
17148                                     }
17149                                 } else {
17150                                     cleanupDisabledPackageComponentsLocked(ssp, userId, killProcess,
17151                                             intent.getStringArrayExtra(
17152                                                     Intent.EXTRA_CHANGED_COMPONENT_NAME_LIST));
17153                                 }
17154                             }
17155                             break;
17156                     }
17157                     break;
17158                 case Intent.ACTION_PACKAGE_ADDED:
17159                     // Special case for adding a package: by default turn on compatibility mode.
17160                     Uri data = intent.getData();
17161                     String ssp;
17162                     if (data != null && (ssp = data.getSchemeSpecificPart()) != null) {
17163                         final boolean replacing =
17164                                 intent.getBooleanExtra(Intent.EXTRA_REPLACING, false);
17165                         mCompatModePackages.handlePackageAddedLocked(ssp, replacing);
17166
17167                         try {
17168                             ApplicationInfo ai = AppGlobals.getPackageManager().
17169                                     getApplicationInfo(ssp, 0, 0);
17170                             mBatteryStatsService.notePackageInstalled(ssp,
17171                                     ai != null ? ai.versionCode : 0);
17172                         } catch (RemoteException e) {
17173                         }
17174                     }
17175                     break;
17176                 case Intent.ACTION_TIMEZONE_CHANGED:
17177                     // If this is the time zone changed action, queue up a message that will reset
17178                     // the timezone of all currently running processes. This message will get
17179                     // queued up before the broadcast happens.
17180                     mHandler.sendEmptyMessage(UPDATE_TIME_ZONE);
17181                     break;
17182                 case Intent.ACTION_TIME_CHANGED:
17183                     // If the user set the time, let all running processes know.
17184                     final int is24Hour =
17185                             intent.getBooleanExtra(Intent.EXTRA_TIME_PREF_24_HOUR_FORMAT, false) ? 1
17186                                     : 0;
17187                     mHandler.sendMessage(mHandler.obtainMessage(UPDATE_TIME, is24Hour, 0));
17188                     BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
17189                     synchronized (stats) {
17190                         stats.noteCurrentTimeChangedLocked();
17191                     }
17192                     break;
17193                 case Intent.ACTION_CLEAR_DNS_CACHE:
17194                     mHandler.sendEmptyMessage(CLEAR_DNS_CACHE_MSG);
17195                     break;
17196                 case Proxy.PROXY_CHANGE_ACTION:
17197                     ProxyInfo proxy = intent.getParcelableExtra(Proxy.EXTRA_PROXY_INFO);
17198                     mHandler.sendMessage(mHandler.obtainMessage(UPDATE_HTTP_PROXY_MSG, proxy));
17199                     break;
17200             }
17201         }
17202
17203         // Add to the sticky list if requested.
17204         if (sticky) {
17205             if (checkPermission(android.Manifest.permission.BROADCAST_STICKY,
17206                     callingPid, callingUid)
17207                     != PackageManager.PERMISSION_GRANTED) {
17208                 String msg = "Permission Denial: broadcastIntent() requesting a sticky broadcast from pid="
17209                         + callingPid + ", uid=" + callingUid
17210                         + " requires " + android.Manifest.permission.BROADCAST_STICKY;
17211                 Slog.w(TAG, msg);
17212                 throw new SecurityException(msg);
17213             }
17214             if (requiredPermissions != null && requiredPermissions.length > 0) {
17215                 Slog.w(TAG, "Can't broadcast sticky intent " + intent
17216                         + " and enforce permissions " + Arrays.toString(requiredPermissions));
17217                 return ActivityManager.BROADCAST_STICKY_CANT_HAVE_PERMISSION;
17218             }
17219             if (intent.getComponent() != null) {
17220                 throw new SecurityException(
17221                         "Sticky broadcasts can't target a specific component");
17222             }
17223             // We use userId directly here, since the "all" target is maintained
17224             // as a separate set of sticky broadcasts.
17225             if (userId != UserHandle.USER_ALL) {
17226                 // But first, if this is not a broadcast to all users, then
17227                 // make sure it doesn't conflict with an existing broadcast to
17228                 // all users.
17229                 ArrayMap<String, ArrayList<Intent>> stickies = mStickyBroadcasts.get(
17230                         UserHandle.USER_ALL);
17231                 if (stickies != null) {
17232                     ArrayList<Intent> list = stickies.get(intent.getAction());
17233                     if (list != null) {
17234                         int N = list.size();
17235                         int i;
17236                         for (i=0; i<N; i++) {
17237                             if (intent.filterEquals(list.get(i))) {
17238                                 throw new IllegalArgumentException(
17239                                         "Sticky broadcast " + intent + " for user "
17240                                         + userId + " conflicts with existing global broadcast");
17241                             }
17242                         }
17243                     }
17244                 }
17245             }
17246             ArrayMap<String, ArrayList<Intent>> stickies = mStickyBroadcasts.get(userId);
17247             if (stickies == null) {
17248                 stickies = new ArrayMap<>();
17249                 mStickyBroadcasts.put(userId, stickies);
17250             }
17251             ArrayList<Intent> list = stickies.get(intent.getAction());
17252             if (list == null) {
17253                 list = new ArrayList<>();
17254                 stickies.put(intent.getAction(), list);
17255             }
17256             final int stickiesCount = list.size();
17257             int i;
17258             for (i = 0; i < stickiesCount; i++) {
17259                 if (intent.filterEquals(list.get(i))) {
17260                     // This sticky already exists, replace it.
17261                     list.set(i, new Intent(intent));
17262                     break;
17263                 }
17264             }
17265             if (i >= stickiesCount) {
17266                 list.add(new Intent(intent));
17267             }
17268         }
17269
17270         int[] users;
17271         if (userId == UserHandle.USER_ALL) {
17272             // Caller wants broadcast to go to all started users.
17273             users = mUserController.getStartedUserArrayLocked();
17274         } else {
17275             // Caller wants broadcast to go to one specific user.
17276             users = new int[] {userId};
17277         }
17278
17279         // Figure out who all will receive this broadcast.
17280         List receivers = null;
17281         List<BroadcastFilter> registeredReceivers = null;
17282         // Need to resolve the intent to interested receivers...
17283         if ((intent.getFlags()&Intent.FLAG_RECEIVER_REGISTERED_ONLY)
17284                  == 0) {
17285             receivers = collectReceiverComponents(intent, resolvedType, callingUid, users);
17286         }
17287         if (intent.getComponent() == null) {
17288             if (userId == UserHandle.USER_ALL && callingUid == Process.SHELL_UID) {
17289                 // Query one target user at a time, excluding shell-restricted users
17290                 for (int i = 0; i < users.length; i++) {
17291                     if (mUserController.hasUserRestriction(
17292                             UserManager.DISALLOW_DEBUGGING_FEATURES, users[i])) {
17293                         continue;
17294                     }
17295                     List<BroadcastFilter> registeredReceiversForUser =
17296                             mReceiverResolver.queryIntent(intent,
17297                                     resolvedType, false, users[i]);
17298                     if (registeredReceivers == null) {
17299                         registeredReceivers = registeredReceiversForUser;
17300                     } else if (registeredReceiversForUser != null) {
17301                         registeredReceivers.addAll(registeredReceiversForUser);
17302                     }
17303                 }
17304             } else {
17305                 registeredReceivers = mReceiverResolver.queryIntent(intent,
17306                         resolvedType, false, userId);
17307             }
17308         }
17309
17310         final boolean replacePending =
17311                 (intent.getFlags()&Intent.FLAG_RECEIVER_REPLACE_PENDING) != 0;
17312
17313         if (DEBUG_BROADCAST) Slog.v(TAG_BROADCAST, "Enqueing broadcast: " + intent.getAction()
17314                 + " replacePending=" + replacePending);
17315
17316         int NR = registeredReceivers != null ? registeredReceivers.size() : 0;
17317         if (!ordered && NR > 0) {
17318             // If we are not serializing this broadcast, then send the
17319             // registered receivers separately so they don't wait for the
17320             // components to be launched.
17321             final BroadcastQueue queue = broadcastQueueForIntent(intent);
17322             BroadcastRecord r = new BroadcastRecord(queue, intent, callerApp,
17323                     callerPackage, callingPid, callingUid, resolvedType, requiredPermissions,
17324                     appOp, brOptions, registeredReceivers, resultTo, resultCode, resultData,
17325                     resultExtras, ordered, sticky, false, userId);
17326             if (DEBUG_BROADCAST) Slog.v(TAG_BROADCAST, "Enqueueing parallel broadcast " + r);
17327             final boolean replaced = replacePending && queue.replaceParallelBroadcastLocked(r);
17328             if (!replaced) {
17329                 queue.enqueueParallelBroadcastLocked(r);
17330                 queue.scheduleBroadcastsLocked();
17331             }
17332             registeredReceivers = null;
17333             NR = 0;
17334         }
17335
17336         // Merge into one list.
17337         int ir = 0;
17338         if (receivers != null) {
17339             // A special case for PACKAGE_ADDED: do not allow the package
17340             // being added to see this broadcast.  This prevents them from
17341             // using this as a back door to get run as soon as they are
17342             // installed.  Maybe in the future we want to have a special install
17343             // broadcast or such for apps, but we'd like to deliberately make
17344             // this decision.
17345             String skipPackages[] = null;
17346             if (Intent.ACTION_PACKAGE_ADDED.equals(intent.getAction())
17347                     || Intent.ACTION_PACKAGE_RESTARTED.equals(intent.getAction())
17348                     || Intent.ACTION_PACKAGE_DATA_CLEARED.equals(intent.getAction())) {
17349                 Uri data = intent.getData();
17350                 if (data != null) {
17351                     String pkgName = data.getSchemeSpecificPart();
17352                     if (pkgName != null) {
17353                         skipPackages = new String[] { pkgName };
17354                     }
17355                 }
17356             } else if (Intent.ACTION_EXTERNAL_APPLICATIONS_AVAILABLE.equals(intent.getAction())) {
17357                 skipPackages = intent.getStringArrayExtra(Intent.EXTRA_CHANGED_PACKAGE_LIST);
17358             }
17359             if (skipPackages != null && (skipPackages.length > 0)) {
17360                 for (String skipPackage : skipPackages) {
17361                     if (skipPackage != null) {
17362                         int NT = receivers.size();
17363                         for (int it=0; it<NT; it++) {
17364                             ResolveInfo curt = (ResolveInfo)receivers.get(it);
17365                             if (curt.activityInfo.packageName.equals(skipPackage)) {
17366                                 receivers.remove(it);
17367                                 it--;
17368                                 NT--;
17369                             }
17370                         }
17371                     }
17372                 }
17373             }
17374
17375             int NT = receivers != null ? receivers.size() : 0;
17376             int it = 0;
17377             ResolveInfo curt = null;
17378             BroadcastFilter curr = null;
17379             while (it < NT && ir < NR) {
17380                 if (curt == null) {
17381                     curt = (ResolveInfo)receivers.get(it);
17382                 }
17383                 if (curr == null) {
17384                     curr = registeredReceivers.get(ir);
17385                 }
17386                 if (curr.getPriority() >= curt.priority) {
17387                     // Insert this broadcast record into the final list.
17388                     receivers.add(it, curr);
17389                     ir++;
17390                     curr = null;
17391                     it++;
17392                     NT++;
17393                 } else {
17394                     // Skip to the next ResolveInfo in the final list.
17395                     it++;
17396                     curt = null;
17397                 }
17398             }
17399         }
17400         while (ir < NR) {
17401             if (receivers == null) {
17402                 receivers = new ArrayList();
17403             }
17404             receivers.add(registeredReceivers.get(ir));
17405             ir++;
17406         }
17407
17408         if ((receivers != null && receivers.size() > 0)
17409                 || resultTo != null) {
17410             BroadcastQueue queue = broadcastQueueForIntent(intent);
17411             BroadcastRecord r = new BroadcastRecord(queue, intent, callerApp,
17412                     callerPackage, callingPid, callingUid, resolvedType,
17413                     requiredPermissions, appOp, brOptions, receivers, resultTo, resultCode,
17414                     resultData, resultExtras, ordered, sticky, false, userId);
17415
17416             if (DEBUG_BROADCAST) Slog.v(TAG_BROADCAST, "Enqueueing ordered broadcast " + r
17417                     + ": prev had " + queue.mOrderedBroadcasts.size());
17418             if (DEBUG_BROADCAST) Slog.i(TAG_BROADCAST,
17419                     "Enqueueing broadcast " + r.intent.getAction());
17420
17421             boolean replaced = replacePending && queue.replaceOrderedBroadcastLocked(r);
17422             if (!replaced) {
17423                 queue.enqueueOrderedBroadcastLocked(r);
17424                 queue.scheduleBroadcastsLocked();
17425             }
17426         }
17427
17428         return ActivityManager.BROADCAST_SUCCESS;
17429     }
17430
17431     final Intent verifyBroadcastLocked(Intent intent) {
17432         // Refuse possible leaked file descriptors
17433         if (intent != null && intent.hasFileDescriptors() == true) {
17434             throw new IllegalArgumentException("File descriptors passed in Intent");
17435         }
17436
17437         int flags = intent.getFlags();
17438
17439         if (!mProcessesReady) {
17440             // if the caller really truly claims to know what they're doing, go
17441             // ahead and allow the broadcast without launching any receivers
17442             if ((flags&Intent.FLAG_RECEIVER_REGISTERED_ONLY_BEFORE_BOOT) != 0) {
17443                 // This will be turned into a FLAG_RECEIVER_REGISTERED_ONLY later on if needed.
17444             } else if ((flags&Intent.FLAG_RECEIVER_REGISTERED_ONLY) == 0) {
17445                 Slog.e(TAG, "Attempt to launch receivers of broadcast intent " + intent
17446                         + " before boot completion");
17447                 throw new IllegalStateException("Cannot broadcast before boot completed");
17448             }
17449         }
17450
17451         if ((flags&Intent.FLAG_RECEIVER_BOOT_UPGRADE) != 0) {
17452             throw new IllegalArgumentException(
17453                     "Can't use FLAG_RECEIVER_BOOT_UPGRADE here");
17454         }
17455
17456         return intent;
17457     }
17458
17459     public final int broadcastIntent(IApplicationThread caller,
17460             Intent intent, String resolvedType, IIntentReceiver resultTo,
17461             int resultCode, String resultData, Bundle resultExtras,
17462             String[] requiredPermissions, int appOp, Bundle bOptions,
17463             boolean serialized, boolean sticky, int userId) {
17464         enforceNotIsolatedCaller("broadcastIntent");
17465         synchronized(this) {
17466             intent = verifyBroadcastLocked(intent);
17467
17468             final ProcessRecord callerApp = getRecordForAppLocked(caller);
17469             final int callingPid = Binder.getCallingPid();
17470             final int callingUid = Binder.getCallingUid();
17471             final long origId = Binder.clearCallingIdentity();
17472             int res = broadcastIntentLocked(callerApp,
17473                     callerApp != null ? callerApp.info.packageName : null,
17474                     intent, resolvedType, resultTo, resultCode, resultData, resultExtras,
17475                     requiredPermissions, appOp, null, serialized, sticky,
17476                     callingPid, callingUid, userId);
17477             Binder.restoreCallingIdentity(origId);
17478             return res;
17479         }
17480     }
17481
17482
17483     int broadcastIntentInPackage(String packageName, int uid,
17484             Intent intent, String resolvedType, IIntentReceiver resultTo,
17485             int resultCode, String resultData, Bundle resultExtras,
17486             String requiredPermission, Bundle bOptions, boolean serialized, boolean sticky,
17487             int userId) {
17488         synchronized(this) {
17489             intent = verifyBroadcastLocked(intent);
17490
17491             final long origId = Binder.clearCallingIdentity();
17492             String[] requiredPermissions = requiredPermission == null ? null
17493                     : new String[] {requiredPermission};
17494             int res = broadcastIntentLocked(null, packageName, intent, resolvedType,
17495                     resultTo, resultCode, resultData, resultExtras,
17496                     requiredPermissions, AppOpsManager.OP_NONE, bOptions, serialized,
17497                     sticky, -1, uid, userId);
17498             Binder.restoreCallingIdentity(origId);
17499             return res;
17500         }
17501     }
17502
17503     public final void unbroadcastIntent(IApplicationThread caller, Intent intent, int userId) {
17504         // Refuse possible leaked file descriptors
17505         if (intent != null && intent.hasFileDescriptors() == true) {
17506             throw new IllegalArgumentException("File descriptors passed in Intent");
17507         }
17508
17509         userId = mUserController.handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(),
17510                 userId, true, ALLOW_NON_FULL, "removeStickyBroadcast", null);
17511
17512         synchronized(this) {
17513             if (checkCallingPermission(android.Manifest.permission.BROADCAST_STICKY)
17514                     != PackageManager.PERMISSION_GRANTED) {
17515                 String msg = "Permission Denial: unbroadcastIntent() from pid="
17516                         + Binder.getCallingPid()
17517                         + ", uid=" + Binder.getCallingUid()
17518                         + " requires " + android.Manifest.permission.BROADCAST_STICKY;
17519                 Slog.w(TAG, msg);
17520                 throw new SecurityException(msg);
17521             }
17522             ArrayMap<String, ArrayList<Intent>> stickies = mStickyBroadcasts.get(userId);
17523             if (stickies != null) {
17524                 ArrayList<Intent> list = stickies.get(intent.getAction());
17525                 if (list != null) {
17526                     int N = list.size();
17527                     int i;
17528                     for (i=0; i<N; i++) {
17529                         if (intent.filterEquals(list.get(i))) {
17530                             list.remove(i);
17531                             break;
17532                         }
17533                     }
17534                     if (list.size() <= 0) {
17535                         stickies.remove(intent.getAction());
17536                     }
17537                 }
17538                 if (stickies.size() <= 0) {
17539                     mStickyBroadcasts.remove(userId);
17540                 }
17541             }
17542         }
17543     }
17544
17545     void backgroundServicesFinishedLocked(int userId) {
17546         for (BroadcastQueue queue : mBroadcastQueues) {
17547             queue.backgroundServicesFinishedLocked(userId);
17548         }
17549     }
17550
17551     public void finishReceiver(IBinder who, int resultCode, String resultData,
17552             Bundle resultExtras, boolean resultAbort, int flags) {
17553         if (DEBUG_BROADCAST) Slog.v(TAG_BROADCAST, "Finish receiver: " + who);
17554
17555         // Refuse possible leaked file descriptors
17556         if (resultExtras != null && resultExtras.hasFileDescriptors()) {
17557             throw new IllegalArgumentException("File descriptors passed in Bundle");
17558         }
17559
17560         final long origId = Binder.clearCallingIdentity();
17561         try {
17562             boolean doNext = false;
17563             BroadcastRecord r;
17564
17565             synchronized(this) {
17566                 BroadcastQueue queue = (flags & Intent.FLAG_RECEIVER_FOREGROUND) != 0
17567                         ? mFgBroadcastQueue : mBgBroadcastQueue;
17568                 r = queue.getMatchingOrderedReceiver(who);
17569                 if (r != null) {
17570                     doNext = r.queue.finishReceiverLocked(r, resultCode,
17571                         resultData, resultExtras, resultAbort, true);
17572                 }
17573             }
17574
17575             if (doNext) {
17576                 r.queue.processNextBroadcast(false);
17577             }
17578             trimApplications();
17579         } finally {
17580             Binder.restoreCallingIdentity(origId);
17581         }
17582     }
17583
17584     // =========================================================
17585     // INSTRUMENTATION
17586     // =========================================================
17587
17588     public boolean startInstrumentation(ComponentName className,
17589             String profileFile, int flags, Bundle arguments,
17590             IInstrumentationWatcher watcher, IUiAutomationConnection uiAutomationConnection,
17591             int userId, String abiOverride) {
17592         enforceNotIsolatedCaller("startInstrumentation");
17593         userId = mUserController.handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(),
17594                 userId, false, ALLOW_FULL_ONLY, "startInstrumentation", null);
17595         // Refuse possible leaked file descriptors
17596         if (arguments != null && arguments.hasFileDescriptors()) {
17597             throw new IllegalArgumentException("File descriptors passed in Bundle");
17598         }
17599
17600         synchronized(this) {
17601             InstrumentationInfo ii = null;
17602             ApplicationInfo ai = null;
17603             try {
17604                 ii = mContext.getPackageManager().getInstrumentationInfo(
17605                     className, STOCK_PM_FLAGS);
17606                 ai = AppGlobals.getPackageManager().getApplicationInfo(
17607                         ii.targetPackage, STOCK_PM_FLAGS, userId);
17608             } catch (PackageManager.NameNotFoundException e) {
17609             } catch (RemoteException e) {
17610             }
17611             if (ii == null) {
17612                 reportStartInstrumentationFailure(watcher, className,
17613                         "Unable to find instrumentation info for: " + className);
17614                 return false;
17615             }
17616             if (ai == null) {
17617                 reportStartInstrumentationFailure(watcher, className,
17618                         "Unable to find instrumentation target package: " + ii.targetPackage);
17619                 return false;
17620             }
17621
17622             int match = mContext.getPackageManager().checkSignatures(
17623                     ii.targetPackage, ii.packageName);
17624             if (match < 0 && match != PackageManager.SIGNATURE_FIRST_NOT_SIGNED) {
17625                 String msg = "Permission Denial: starting instrumentation "
17626                         + className + " from pid="
17627                         + Binder.getCallingPid()
17628                         + ", uid=" + Binder.getCallingPid()
17629                         + " not allowed because package " + ii.packageName
17630                         + " does not have a signature matching the target "
17631                         + ii.targetPackage;
17632                 reportStartInstrumentationFailure(watcher, className, msg);
17633                 throw new SecurityException(msg);
17634             }
17635
17636             final long origId = Binder.clearCallingIdentity();
17637             // Instrumentation can kill and relaunch even persistent processes
17638             forceStopPackageLocked(ii.targetPackage, -1, true, false, true, true, false, userId,
17639                     "start instr");
17640             ProcessRecord app = addAppLocked(ai, false, abiOverride);
17641             app.instrumentationClass = className;
17642             app.instrumentationInfo = ai;
17643             app.instrumentationProfileFile = profileFile;
17644             app.instrumentationArguments = arguments;
17645             app.instrumentationWatcher = watcher;
17646             app.instrumentationUiAutomationConnection = uiAutomationConnection;
17647             app.instrumentationResultClass = className;
17648             Binder.restoreCallingIdentity(origId);
17649         }
17650
17651         return true;
17652     }
17653
17654     /**
17655      * Report errors that occur while attempting to start Instrumentation.  Always writes the
17656      * error to the logs, but if somebody is watching, send the report there too.  This enables
17657      * the "am" command to report errors with more information.
17658      *
17659      * @param watcher The IInstrumentationWatcher.  Null if there isn't one.
17660      * @param cn The component name of the instrumentation.
17661      * @param report The error report.
17662      */
17663     private void reportStartInstrumentationFailure(IInstrumentationWatcher watcher,
17664             ComponentName cn, String report) {
17665         Slog.w(TAG, report);
17666         try {
17667             if (watcher != null) {
17668                 Bundle results = new Bundle();
17669                 results.putString(Instrumentation.REPORT_KEY_IDENTIFIER, "ActivityManagerService");
17670                 results.putString("Error", report);
17671                 watcher.instrumentationStatus(cn, -1, results);
17672             }
17673         } catch (RemoteException e) {
17674             Slog.w(TAG, e);
17675         }
17676     }
17677
17678     void finishInstrumentationLocked(ProcessRecord app, int resultCode, Bundle results) {
17679         if (app.instrumentationWatcher != null) {
17680             try {
17681                 // NOTE:  IInstrumentationWatcher *must* be oneway here
17682                 app.instrumentationWatcher.instrumentationFinished(
17683                     app.instrumentationClass,
17684                     resultCode,
17685                     results);
17686             } catch (RemoteException e) {
17687             }
17688         }
17689
17690         // Can't call out of the system process with a lock held, so post a message.
17691         if (app.instrumentationUiAutomationConnection != null) {
17692             mHandler.obtainMessage(SHUTDOWN_UI_AUTOMATION_CONNECTION_MSG,
17693                     app.instrumentationUiAutomationConnection).sendToTarget();
17694         }
17695
17696         app.instrumentationWatcher = null;
17697         app.instrumentationUiAutomationConnection = null;
17698         app.instrumentationClass = null;
17699         app.instrumentationInfo = null;
17700         app.instrumentationProfileFile = null;
17701         app.instrumentationArguments = null;
17702
17703         forceStopPackageLocked(app.info.packageName, -1, false, false, true, true, false, app.userId,
17704                 "finished inst");
17705     }
17706
17707     public void finishInstrumentation(IApplicationThread target,
17708             int resultCode, Bundle results) {
17709         int userId = UserHandle.getCallingUserId();
17710         // Refuse possible leaked file descriptors
17711         if (results != null && results.hasFileDescriptors()) {
17712             throw new IllegalArgumentException("File descriptors passed in Intent");
17713         }
17714
17715         synchronized(this) {
17716             ProcessRecord app = getRecordForAppLocked(target);
17717             if (app == null) {
17718                 Slog.w(TAG, "finishInstrumentation: no app for " + target);
17719                 return;
17720             }
17721             final long origId = Binder.clearCallingIdentity();
17722             finishInstrumentationLocked(app, resultCode, results);
17723             Binder.restoreCallingIdentity(origId);
17724         }
17725     }
17726
17727     // =========================================================
17728     // CONFIGURATION
17729     // =========================================================
17730
17731     public ConfigurationInfo getDeviceConfigurationInfo() {
17732         ConfigurationInfo config = new ConfigurationInfo();
17733         synchronized (this) {
17734             config.reqTouchScreen = mConfiguration.touchscreen;
17735             config.reqKeyboardType = mConfiguration.keyboard;
17736             config.reqNavigation = mConfiguration.navigation;
17737             if (mConfiguration.navigation == Configuration.NAVIGATION_DPAD
17738                     || mConfiguration.navigation == Configuration.NAVIGATION_TRACKBALL) {
17739                 config.reqInputFeatures |= ConfigurationInfo.INPUT_FEATURE_FIVE_WAY_NAV;
17740             }
17741             if (mConfiguration.keyboard != Configuration.KEYBOARD_UNDEFINED
17742                     && mConfiguration.keyboard != Configuration.KEYBOARD_NOKEYS) {
17743                 config.reqInputFeatures |= ConfigurationInfo.INPUT_FEATURE_HARD_KEYBOARD;
17744             }
17745             config.reqGlEsVersion = GL_ES_VERSION;
17746         }
17747         return config;
17748     }
17749
17750     ActivityStack getFocusedStack() {
17751         return mStackSupervisor.getFocusedStack();
17752     }
17753
17754     @Override
17755     public int getFocusedStackId() throws RemoteException {
17756         ActivityStack focusedStack = getFocusedStack();
17757         if (focusedStack != null) {
17758             return focusedStack.getStackId();
17759         }
17760         return -1;
17761     }
17762
17763     public Configuration getConfiguration() {
17764         Configuration ci;
17765         synchronized(this) {
17766             ci = new Configuration(mConfiguration);
17767             ci.userSetLocale = false;
17768         }
17769         return ci;
17770     }
17771
17772     @Override
17773     public void suppressResizeConfigChanges(boolean suppress) throws RemoteException {
17774         enforceCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS,
17775                 "suppressResizeConfigChanges()");
17776         synchronized (this) {
17777             mSuppressResizeConfigChanges = suppress;
17778         }
17779     }
17780
17781     @Override
17782     public void removeStack(int stackId) {
17783         enforceCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS,
17784                 "detahStack()");
17785         if (stackId == HOME_STACK_ID) {
17786             throw new IllegalArgumentException("Removing home stack is not allowed.");
17787         }
17788         synchronized (this) {
17789             long origId = Binder.clearCallingIdentity();
17790             ActivityStack stack = mStackSupervisor.getStack(stackId);
17791             if (stack != null) {
17792                 ArrayList<TaskRecord> tasks = stack.getAllTasks();
17793                 for (int i = tasks.size() - 1; i >= 0; i--) {
17794                     removeTaskByIdLocked(tasks.get(i).taskId, false /* killProcess */,
17795                             !REMOVE_FROM_RECENTS);
17796                 }
17797             }
17798             Binder.restoreCallingIdentity(origId);
17799         }
17800     }
17801
17802     @Override
17803     public void updatePersistentConfiguration(Configuration values) {
17804         enforceCallingPermission(android.Manifest.permission.CHANGE_CONFIGURATION,
17805                 "updateConfiguration()");
17806         enforceWriteSettingsPermission("updateConfiguration()");
17807         if (values == null) {
17808             throw new NullPointerException("Configuration must not be null");
17809         }
17810
17811         int userId = UserHandle.getCallingUserId();
17812
17813         synchronized(this) {
17814             final long origId = Binder.clearCallingIdentity();
17815             updateConfigurationLocked(values, null, false, true, userId);
17816             Binder.restoreCallingIdentity(origId);
17817         }
17818     }
17819
17820     private void enforceWriteSettingsPermission(String func) {
17821         int uid = Binder.getCallingUid();
17822         if (uid == Process.ROOT_UID) {
17823             return;
17824         }
17825
17826         if (Settings.checkAndNoteWriteSettingsOperation(mContext, uid,
17827                 Settings.getPackageNameForUid(mContext, uid), false)) {
17828             return;
17829         }
17830
17831         String msg = "Permission Denial: " + func + " from pid="
17832                 + Binder.getCallingPid()
17833                 + ", uid=" + uid
17834                 + " requires " + android.Manifest.permission.WRITE_SETTINGS;
17835         Slog.w(TAG, msg);
17836         throw new SecurityException(msg);
17837     }
17838
17839     public void updateConfiguration(Configuration values) {
17840         enforceCallingPermission(android.Manifest.permission.CHANGE_CONFIGURATION,
17841                 "updateConfiguration()");
17842
17843         synchronized(this) {
17844             if (values == null && mWindowManager != null) {
17845                 // sentinel: fetch the current configuration from the window manager
17846                 values = mWindowManager.computeNewConfiguration();
17847             }
17848
17849             if (mWindowManager != null) {
17850                 mProcessList.applyDisplaySize(mWindowManager);
17851             }
17852
17853             final long origId = Binder.clearCallingIdentity();
17854             if (values != null) {
17855                 Settings.System.clearConfiguration(values);
17856             }
17857             updateConfigurationLocked(values, null, false);
17858             Binder.restoreCallingIdentity(origId);
17859         }
17860     }
17861
17862     void updateUserConfigurationLocked() {
17863         Configuration configuration = new Configuration(mConfiguration);
17864         Settings.System.getConfigurationForUser(mContext.getContentResolver(), configuration,
17865                 mUserController.getCurrentUserIdLocked());
17866         updateConfigurationLocked(configuration, null, false);
17867     }
17868
17869     boolean updateConfigurationLocked(Configuration values,
17870             ActivityRecord starting, boolean initLocale) {
17871         // pass UserHandle.USER_NULL as userId because we don't persist configuration for any user
17872         return updateConfigurationLocked(values, starting, initLocale, false,
17873                 UserHandle.USER_NULL);
17874     }
17875
17876     // To cache the list of supported system locales
17877     private String[] mSupportedSystemLocales = null;
17878
17879     /**
17880      * Do either or both things: (1) change the current configuration, and (2)
17881      * make sure the given activity is running with the (now) current
17882      * configuration.  Returns true if the activity has been left running, or
17883      * false if <var>starting</var> is being destroyed to match the new
17884      * configuration.
17885      *
17886      * @param userId is only used when persistent parameter is set to true to persist configuration
17887      *               for that particular user
17888      */
17889     private boolean updateConfigurationLocked(Configuration values,
17890             ActivityRecord starting, boolean initLocale, boolean persistent, int userId) {
17891         int changes = 0;
17892
17893         if (values != null) {
17894             Configuration newConfig = new Configuration(mConfiguration);
17895             changes = newConfig.updateFrom(values);
17896             if (changes != 0) {
17897                 if (DEBUG_SWITCH || DEBUG_CONFIGURATION) Slog.i(TAG_CONFIGURATION,
17898                         "Updating configuration to: " + values);
17899
17900                 EventLog.writeEvent(EventLogTags.CONFIGURATION_CHANGED, changes);
17901
17902                 if (!initLocale && !values.getLocales().isEmpty() && values.userSetLocale) {
17903                     if (mSupportedSystemLocales == null) {
17904                         mSupportedSystemLocales = Resources.getSystem().getAssets().getLocales();
17905                     }
17906                     final Locale locale = values.getLocales().getBestMatch(mSupportedSystemLocales);
17907                     SystemProperties.set("persist.sys.locale", locale.toLanguageTag());
17908                     mHandler.sendMessage(mHandler.obtainMessage(SEND_LOCALE_TO_MOUNT_DAEMON_MSG,
17909                             locale));
17910                 }
17911
17912                 mConfigurationSeq++;
17913                 if (mConfigurationSeq <= 0) {
17914                     mConfigurationSeq = 1;
17915                 }
17916                 newConfig.seq = mConfigurationSeq;
17917                 mConfiguration = newConfig;
17918                 Slog.i(TAG, "Config changes=" + Integer.toHexString(changes) + " " + newConfig);
17919                 mUsageStatsService.reportConfigurationChange(newConfig,
17920                         mUserController.getCurrentUserIdLocked());
17921                 //mUsageStatsService.noteStartConfig(newConfig);
17922
17923                 final Configuration configCopy = new Configuration(mConfiguration);
17924
17925                 // TODO: If our config changes, should we auto dismiss any currently
17926                 // showing dialogs?
17927                 mShowDialogs = shouldShowDialogs(newConfig);
17928
17929                 AttributeCache ac = AttributeCache.instance();
17930                 if (ac != null) {
17931                     ac.updateConfiguration(configCopy);
17932                 }
17933
17934                 // Make sure all resources in our process are updated
17935                 // right now, so that anyone who is going to retrieve
17936                 // resource values after we return will be sure to get
17937                 // the new ones.  This is especially important during
17938                 // boot, where the first config change needs to guarantee
17939                 // all resources have that config before following boot
17940                 // code is executed.
17941                 mSystemThread.applyConfigurationToResources(configCopy);
17942
17943                 if (persistent && Settings.System.hasInterestingConfigurationChanges(changes)) {
17944                     Message msg = mHandler.obtainMessage(UPDATE_CONFIGURATION_MSG);
17945                     msg.obj = new Configuration(configCopy);
17946                     msg.arg1 = userId;
17947                     mHandler.sendMessage(msg);
17948                 }
17949
17950                 for (int i=mLruProcesses.size()-1; i>=0; i--) {
17951                     ProcessRecord app = mLruProcesses.get(i);
17952                     try {
17953                         if (app.thread != null) {
17954                             if (DEBUG_CONFIGURATION) Slog.v(TAG_CONFIGURATION, "Sending to proc "
17955                                     + app.processName + " new config " + mConfiguration);
17956                             app.thread.scheduleConfigurationChanged(configCopy);
17957                         }
17958                     } catch (Exception e) {
17959                     }
17960                 }
17961                 Intent intent = new Intent(Intent.ACTION_CONFIGURATION_CHANGED);
17962                 intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY
17963                         | Intent.FLAG_RECEIVER_REPLACE_PENDING
17964                         | Intent.FLAG_RECEIVER_FOREGROUND);
17965                 broadcastIntentLocked(null, null, intent, null, null, 0, null, null,
17966                         null, AppOpsManager.OP_NONE, null, false, false,
17967                         MY_PID, Process.SYSTEM_UID, UserHandle.USER_ALL);
17968                 if ((changes&ActivityInfo.CONFIG_LOCALE) != 0) {
17969                     intent = new Intent(Intent.ACTION_LOCALE_CHANGED);
17970                     intent.addFlags(Intent.FLAG_RECEIVER_FOREGROUND);
17971                     if (!mProcessesReady) {
17972                         intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY);
17973                     }
17974                     broadcastIntentLocked(null, null, intent,
17975                             null, null, 0, null, null, null, AppOpsManager.OP_NONE,
17976                             null, false, false, MY_PID, Process.SYSTEM_UID, UserHandle.USER_ALL);
17977                 }
17978             }
17979         }
17980
17981         boolean kept = true;
17982         final ActivityStack mainStack = mStackSupervisor.getFocusedStack();
17983         // mainStack is null during startup.
17984         if (mainStack != null) {
17985             if (changes != 0 && starting == null) {
17986                 // If the configuration changed, and the caller is not already
17987                 // in the process of starting an activity, then find the top
17988                 // activity to check if its configuration needs to change.
17989                 starting = mainStack.topRunningActivityLocked();
17990             }
17991
17992             if (starting != null) {
17993                 kept = mainStack.ensureActivityConfigurationLocked(starting, changes, false);
17994                 // And we need to make sure at this point that all other activities
17995                 // are made visible with the correct configuration.
17996                 mStackSupervisor.ensureActivitiesVisibleLocked(starting, changes,
17997                         !PRESERVE_WINDOWS);
17998             }
17999         }
18000
18001         if (values != null && mWindowManager != null) {
18002             mWindowManager.setNewConfiguration(mConfiguration);
18003         }
18004
18005         return kept;
18006     }
18007
18008     /**
18009      * Decide based on the configuration whether we should shouw the ANR,
18010      * crash, etc dialogs.  The idea is that if there is no affordnace to
18011      * press the on-screen buttons, we shouldn't show the dialog.
18012      *
18013      * A thought: SystemUI might also want to get told about this, the Power
18014      * dialog / global actions also might want different behaviors.
18015      */
18016     private static final boolean shouldShowDialogs(Configuration config) {
18017         return !(config.keyboard == Configuration.KEYBOARD_NOKEYS
18018                 && config.touchscreen == Configuration.TOUCHSCREEN_NOTOUCH
18019                 && config.navigation == Configuration.NAVIGATION_NONAV);
18020     }
18021
18022     @Override
18023     public boolean shouldUpRecreateTask(IBinder token, String destAffinity) {
18024         synchronized (this) {
18025             ActivityRecord srec = ActivityRecord.forTokenLocked(token);
18026             if (srec != null) {
18027                 return srec.task.stack.shouldUpRecreateTaskLocked(srec, destAffinity);
18028             }
18029         }
18030         return false;
18031     }
18032
18033     public boolean navigateUpTo(IBinder token, Intent destIntent, int resultCode,
18034             Intent resultData) {
18035
18036         synchronized (this) {
18037             final ActivityRecord r = ActivityRecord.forTokenLocked(token);
18038             if (r != null) {
18039                 return r.task.stack.navigateUpToLocked(r, destIntent, resultCode, resultData);
18040             }
18041             return false;
18042         }
18043     }
18044
18045     public int getLaunchedFromUid(IBinder activityToken) {
18046         ActivityRecord srec;
18047         synchronized (this) {
18048             srec = ActivityRecord.forTokenLocked(activityToken);
18049         }
18050         if (srec == null) {
18051             return -1;
18052         }
18053         return srec.launchedFromUid;
18054     }
18055
18056     public String getLaunchedFromPackage(IBinder activityToken) {
18057         ActivityRecord srec;
18058         synchronized (this) {
18059             srec = ActivityRecord.forTokenLocked(activityToken);
18060         }
18061         if (srec == null) {
18062             return null;
18063         }
18064         return srec.launchedFromPackage;
18065     }
18066
18067     // =========================================================
18068     // LIFETIME MANAGEMENT
18069     // =========================================================
18070
18071     // Returns which broadcast queue the app is the current [or imminent] receiver
18072     // on, or 'null' if the app is not an active broadcast recipient.
18073     private BroadcastQueue isReceivingBroadcast(ProcessRecord app) {
18074         BroadcastRecord r = app.curReceiver;
18075         if (r != null) {
18076             return r.queue;
18077         }
18078
18079         // It's not the current receiver, but it might be starting up to become one
18080         synchronized (this) {
18081             for (BroadcastQueue queue : mBroadcastQueues) {
18082                 r = queue.mPendingBroadcast;
18083                 if (r != null && r.curApp == app) {
18084                     // found it; report which queue it's in
18085                     return queue;
18086                 }
18087             }
18088         }
18089
18090         return null;
18091     }
18092
18093     Association startAssociationLocked(int sourceUid, String sourceProcess, int targetUid,
18094             ComponentName targetComponent, String targetProcess) {
18095         if (!mTrackingAssociations) {
18096             return null;
18097         }
18098         ArrayMap<ComponentName, SparseArray<ArrayMap<String, Association>>> components
18099                 = mAssociations.get(targetUid);
18100         if (components == null) {
18101             components = new ArrayMap<>();
18102             mAssociations.put(targetUid, components);
18103         }
18104         SparseArray<ArrayMap<String, Association>> sourceUids = components.get(targetComponent);
18105         if (sourceUids == null) {
18106             sourceUids = new SparseArray<>();
18107             components.put(targetComponent, sourceUids);
18108         }
18109         ArrayMap<String, Association> sourceProcesses = sourceUids.get(sourceUid);
18110         if (sourceProcesses == null) {
18111             sourceProcesses = new ArrayMap<>();
18112             sourceUids.put(sourceUid, sourceProcesses);
18113         }
18114         Association ass = sourceProcesses.get(sourceProcess);
18115         if (ass == null) {
18116             ass = new Association(sourceUid, sourceProcess, targetUid, targetComponent,
18117                     targetProcess);
18118             sourceProcesses.put(sourceProcess, ass);
18119         }
18120         ass.mCount++;
18121         ass.mNesting++;
18122         if (ass.mNesting == 1) {
18123             ass.mStartTime = SystemClock.uptimeMillis();
18124         }
18125         return ass;
18126     }
18127
18128     void stopAssociationLocked(int sourceUid, String sourceProcess, int targetUid,
18129             ComponentName targetComponent) {
18130         if (!mTrackingAssociations) {
18131             return;
18132         }
18133         ArrayMap<ComponentName, SparseArray<ArrayMap<String, Association>>> components
18134                 = mAssociations.get(targetUid);
18135         if (components == null) {
18136             return;
18137         }
18138         SparseArray<ArrayMap<String, Association>> sourceUids = components.get(targetComponent);
18139         if (sourceUids == null) {
18140             return;
18141         }
18142         ArrayMap<String, Association> sourceProcesses = sourceUids.get(sourceUid);
18143         if (sourceProcesses == null) {
18144             return;
18145         }
18146         Association ass = sourceProcesses.get(sourceProcess);
18147         if (ass == null || ass.mNesting <= 0) {
18148             return;
18149         }
18150         ass.mNesting--;
18151         if (ass.mNesting == 0) {
18152             ass.mTime += SystemClock.uptimeMillis() - ass.mStartTime;
18153         }
18154     }
18155
18156     private final int computeOomAdjLocked(ProcessRecord app, int cachedAdj, ProcessRecord TOP_APP,
18157             boolean doingAll, long now) {
18158         if (mAdjSeq == app.adjSeq) {
18159             // This adjustment has already been computed.
18160             return app.curRawAdj;
18161         }
18162
18163         if (app.thread == null) {
18164             app.adjSeq = mAdjSeq;
18165             app.curSchedGroup = Process.THREAD_GROUP_BG_NONINTERACTIVE;
18166             app.curProcState = ActivityManager.PROCESS_STATE_CACHED_EMPTY;
18167             return (app.curAdj=app.curRawAdj=ProcessList.CACHED_APP_MAX_ADJ);
18168         }
18169
18170         app.adjTypeCode = ActivityManager.RunningAppProcessInfo.REASON_UNKNOWN;
18171         app.adjSource = null;
18172         app.adjTarget = null;
18173         app.empty = false;
18174         app.cached = false;
18175
18176         final int activitiesSize = app.activities.size();
18177
18178         if (app.maxAdj <= ProcessList.FOREGROUND_APP_ADJ) {
18179             // The max adjustment doesn't allow this app to be anything
18180             // below foreground, so it is not worth doing work for it.
18181             app.adjType = "fixed";
18182             app.adjSeq = mAdjSeq;
18183             app.curRawAdj = app.maxAdj;
18184             app.foregroundActivities = false;
18185             app.curSchedGroup = Process.THREAD_GROUP_DEFAULT;
18186             app.curProcState = ActivityManager.PROCESS_STATE_PERSISTENT;
18187             // System processes can do UI, and when they do we want to have
18188             // them trim their memory after the user leaves the UI.  To
18189             // facilitate this, here we need to determine whether or not it
18190             // is currently showing UI.
18191             app.systemNoUi = true;
18192             if (app == TOP_APP) {
18193                 app.systemNoUi = false;
18194             } else if (activitiesSize > 0) {
18195                 for (int j = 0; j < activitiesSize; j++) {
18196                     final ActivityRecord r = app.activities.get(j);
18197                     if (r.visible) {
18198                         app.systemNoUi = false;
18199                     }
18200                 }
18201             }
18202             if (!app.systemNoUi) {
18203                 app.curProcState = ActivityManager.PROCESS_STATE_PERSISTENT_UI;
18204             }
18205             return (app.curAdj=app.maxAdj);
18206         }
18207
18208         app.systemNoUi = false;
18209
18210         final int PROCESS_STATE_CUR_TOP = mTopProcessState;
18211
18212         // Determine the importance of the process, starting with most
18213         // important to least, and assign an appropriate OOM adjustment.
18214         int adj;
18215         int schedGroup;
18216         int procState;
18217         boolean foregroundActivities = false;
18218         BroadcastQueue queue;
18219         if (app == TOP_APP) {
18220             // The last app on the list is the foreground app.
18221             adj = ProcessList.FOREGROUND_APP_ADJ;
18222             schedGroup = Process.THREAD_GROUP_DEFAULT;
18223             app.adjType = "top-activity";
18224             foregroundActivities = true;
18225             procState = PROCESS_STATE_CUR_TOP;
18226         } else if (app.instrumentationClass != null) {
18227             // Don't want to kill running instrumentation.
18228             adj = ProcessList.FOREGROUND_APP_ADJ;
18229             schedGroup = Process.THREAD_GROUP_DEFAULT;
18230             app.adjType = "instrumentation";
18231             procState = ActivityManager.PROCESS_STATE_FOREGROUND_SERVICE;
18232         } else if ((queue = isReceivingBroadcast(app)) != null) {
18233             // An app that is currently receiving a broadcast also
18234             // counts as being in the foreground for OOM killer purposes.
18235             // It's placed in a sched group based on the nature of the
18236             // broadcast as reflected by which queue it's active in.
18237             adj = ProcessList.FOREGROUND_APP_ADJ;
18238             schedGroup = (queue == mFgBroadcastQueue)
18239                     ? Process.THREAD_GROUP_DEFAULT : Process.THREAD_GROUP_BG_NONINTERACTIVE;
18240             app.adjType = "broadcast";
18241             procState = ActivityManager.PROCESS_STATE_RECEIVER;
18242         } else if (app.executingServices.size() > 0) {
18243             // An app that is currently executing a service callback also
18244             // counts as being in the foreground.
18245             adj = ProcessList.FOREGROUND_APP_ADJ;
18246             schedGroup = app.execServicesFg ?
18247                     Process.THREAD_GROUP_DEFAULT : Process.THREAD_GROUP_BG_NONINTERACTIVE;
18248             app.adjType = "exec-service";
18249             procState = ActivityManager.PROCESS_STATE_SERVICE;
18250             //Slog.i(TAG, "EXEC " + (app.execServicesFg ? "FG" : "BG") + ": " + app);
18251         } else {
18252             // As far as we know the process is empty.  We may change our mind later.
18253             schedGroup = Process.THREAD_GROUP_BG_NONINTERACTIVE;
18254             // At this point we don't actually know the adjustment.  Use the cached adj
18255             // value that the caller wants us to.
18256             adj = cachedAdj;
18257             procState = ActivityManager.PROCESS_STATE_CACHED_EMPTY;
18258             app.cached = true;
18259             app.empty = true;
18260             app.adjType = "cch-empty";
18261         }
18262
18263         // Examine all activities if not already foreground.
18264         if (!foregroundActivities && activitiesSize > 0) {
18265             int minLayer = ProcessList.VISIBLE_APP_LAYER_MAX;
18266             for (int j = 0; j < activitiesSize; j++) {
18267                 final ActivityRecord r = app.activities.get(j);
18268                 if (r.app != app) {
18269                     Slog.w(TAG, "Wtf, activity " + r + " in proc activity list not using proc "
18270                             + app + "?!? Using " + r.app + " instead.");
18271                     continue;
18272                 }
18273                 if (r.visible) {
18274                     // App has a visible activity; only upgrade adjustment.
18275                     if (adj > ProcessList.VISIBLE_APP_ADJ) {
18276                         adj = ProcessList.VISIBLE_APP_ADJ;
18277                         app.adjType = "visible";
18278                     }
18279                     if (procState > PROCESS_STATE_CUR_TOP) {
18280                         procState = PROCESS_STATE_CUR_TOP;
18281                     }
18282                     schedGroup = Process.THREAD_GROUP_DEFAULT;
18283                     app.cached = false;
18284                     app.empty = false;
18285                     foregroundActivities = true;
18286                     if (r.task != null && minLayer > 0) {
18287                         final int layer = r.task.mLayerRank;
18288                         if (layer >= 0 && minLayer > layer) {
18289                             minLayer = layer;
18290                         }
18291                     }
18292                     break;
18293                 } else if (r.state == ActivityState.PAUSING || r.state == ActivityState.PAUSED) {
18294                     if (adj > ProcessList.PERCEPTIBLE_APP_ADJ) {
18295                         adj = ProcessList.PERCEPTIBLE_APP_ADJ;
18296                         app.adjType = "pausing";
18297                     }
18298                     if (procState > PROCESS_STATE_CUR_TOP) {
18299                         procState = PROCESS_STATE_CUR_TOP;
18300                     }
18301                     schedGroup = Process.THREAD_GROUP_DEFAULT;
18302                     app.cached = false;
18303                     app.empty = false;
18304                     foregroundActivities = true;
18305                 } else if (r.state == ActivityState.STOPPING) {
18306                     if (adj > ProcessList.PERCEPTIBLE_APP_ADJ) {
18307                         adj = ProcessList.PERCEPTIBLE_APP_ADJ;
18308                         app.adjType = "stopping";
18309                     }
18310                     // For the process state, we will at this point consider the
18311                     // process to be cached.  It will be cached either as an activity
18312                     // or empty depending on whether the activity is finishing.  We do
18313                     // this so that we can treat the process as cached for purposes of
18314                     // memory trimming (determing current memory level, trim command to
18315                     // send to process) since there can be an arbitrary number of stopping
18316                     // processes and they should soon all go into the cached state.
18317                     if (!r.finishing) {
18318                         if (procState > ActivityManager.PROCESS_STATE_LAST_ACTIVITY) {
18319                             procState = ActivityManager.PROCESS_STATE_LAST_ACTIVITY;
18320                         }
18321                     }
18322                     app.cached = false;
18323                     app.empty = false;
18324                     foregroundActivities = true;
18325                 } else {
18326                     if (procState > ActivityManager.PROCESS_STATE_CACHED_ACTIVITY) {
18327                         procState = ActivityManager.PROCESS_STATE_CACHED_ACTIVITY;
18328                         app.adjType = "cch-act";
18329                     }
18330                 }
18331             }
18332             if (adj == ProcessList.VISIBLE_APP_ADJ) {
18333                 adj += minLayer;
18334             }
18335         }
18336
18337         if (adj > ProcessList.PERCEPTIBLE_APP_ADJ
18338                 || procState > ActivityManager.PROCESS_STATE_FOREGROUND_SERVICE) {
18339             if (app.foregroundServices) {
18340                 // The user is aware of this app, so make it visible.
18341                 adj = ProcessList.PERCEPTIBLE_APP_ADJ;
18342                 procState = ActivityManager.PROCESS_STATE_FOREGROUND_SERVICE;
18343                 app.cached = false;
18344                 app.adjType = "fg-service";
18345                 schedGroup = Process.THREAD_GROUP_DEFAULT;
18346             } else if (app.forcingToForeground != null) {
18347                 // The user is aware of this app, so make it visible.
18348                 adj = ProcessList.PERCEPTIBLE_APP_ADJ;
18349                 procState = ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND;
18350                 app.cached = false;
18351                 app.adjType = "force-fg";
18352                 app.adjSource = app.forcingToForeground;
18353                 schedGroup = Process.THREAD_GROUP_DEFAULT;
18354             }
18355         }
18356
18357         if (app == mHeavyWeightProcess) {
18358             if (adj > ProcessList.HEAVY_WEIGHT_APP_ADJ) {
18359                 // We don't want to kill the current heavy-weight process.
18360                 adj = ProcessList.HEAVY_WEIGHT_APP_ADJ;
18361                 schedGroup = Process.THREAD_GROUP_BG_NONINTERACTIVE;
18362                 app.cached = false;
18363                 app.adjType = "heavy";
18364             }
18365             if (procState > ActivityManager.PROCESS_STATE_HEAVY_WEIGHT) {
18366                 procState = ActivityManager.PROCESS_STATE_HEAVY_WEIGHT;
18367             }
18368         }
18369
18370         if (app == mHomeProcess) {
18371             if (adj > ProcessList.HOME_APP_ADJ) {
18372                 // This process is hosting what we currently consider to be the
18373                 // home app, so we don't want to let it go into the background.
18374                 adj = ProcessList.HOME_APP_ADJ;
18375                 schedGroup = Process.THREAD_GROUP_BG_NONINTERACTIVE;
18376                 app.cached = false;
18377                 app.adjType = "home";
18378             }
18379             if (procState > ActivityManager.PROCESS_STATE_HOME) {
18380                 procState = ActivityManager.PROCESS_STATE_HOME;
18381             }
18382         }
18383
18384         if (app == mPreviousProcess && app.activities.size() > 0) {
18385             if (adj > ProcessList.PREVIOUS_APP_ADJ) {
18386                 // This was the previous process that showed UI to the user.
18387                 // We want to try to keep it around more aggressively, to give
18388                 // a good experience around switching between two apps.
18389                 adj = ProcessList.PREVIOUS_APP_ADJ;
18390                 schedGroup = Process.THREAD_GROUP_BG_NONINTERACTIVE;
18391                 app.cached = false;
18392                 app.adjType = "previous";
18393             }
18394             if (procState > ActivityManager.PROCESS_STATE_LAST_ACTIVITY) {
18395                 procState = ActivityManager.PROCESS_STATE_LAST_ACTIVITY;
18396             }
18397         }
18398
18399         if (false) Slog.i(TAG, "OOM " + app + ": initial adj=" + adj
18400                 + " reason=" + app.adjType);
18401
18402         // By default, we use the computed adjustment.  It may be changed if
18403         // there are applications dependent on our services or providers, but
18404         // this gives us a baseline and makes sure we don't get into an
18405         // infinite recursion.
18406         app.adjSeq = mAdjSeq;
18407         app.curRawAdj = adj;
18408         app.hasStartedServices = false;
18409
18410         if (mBackupTarget != null && app == mBackupTarget.app) {
18411             // If possible we want to avoid killing apps while they're being backed up
18412             if (adj > ProcessList.BACKUP_APP_ADJ) {
18413                 if (DEBUG_BACKUP) Slog.v(TAG_BACKUP, "oom BACKUP_APP_ADJ for " + app);
18414                 adj = ProcessList.BACKUP_APP_ADJ;
18415                 if (procState > ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND) {
18416                     procState = ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND;
18417                 }
18418                 app.adjType = "backup";
18419                 app.cached = false;
18420             }
18421             if (procState > ActivityManager.PROCESS_STATE_BACKUP) {
18422                 procState = ActivityManager.PROCESS_STATE_BACKUP;
18423             }
18424         }
18425
18426         boolean mayBeTop = false;
18427
18428         for (int is = app.services.size()-1;
18429                 is >= 0 && (adj > ProcessList.FOREGROUND_APP_ADJ
18430                         || schedGroup == Process.THREAD_GROUP_BG_NONINTERACTIVE
18431                         || procState > ActivityManager.PROCESS_STATE_TOP);
18432                 is--) {
18433             ServiceRecord s = app.services.valueAt(is);
18434             if (s.startRequested) {
18435                 app.hasStartedServices = true;
18436                 if (procState > ActivityManager.PROCESS_STATE_SERVICE) {
18437                     procState = ActivityManager.PROCESS_STATE_SERVICE;
18438                 }
18439                 if (app.hasShownUi && app != mHomeProcess) {
18440                     // If this process has shown some UI, let it immediately
18441                     // go to the LRU list because it may be pretty heavy with
18442                     // UI stuff.  We'll tag it with a label just to help
18443                     // debug and understand what is going on.
18444                     if (adj > ProcessList.SERVICE_ADJ) {
18445                         app.adjType = "cch-started-ui-services";
18446                     }
18447                 } else {
18448                     if (now < (s.lastActivity + ActiveServices.MAX_SERVICE_INACTIVITY)) {
18449                         // This service has seen some activity within
18450                         // recent memory, so we will keep its process ahead
18451                         // of the background processes.
18452                         if (adj > ProcessList.SERVICE_ADJ) {
18453                             adj = ProcessList.SERVICE_ADJ;
18454                             app.adjType = "started-services";
18455                             app.cached = false;
18456                         }
18457                     }
18458                     // If we have let the service slide into the background
18459                     // state, still have some text describing what it is doing
18460                     // even though the service no longer has an impact.
18461                     if (adj > ProcessList.SERVICE_ADJ) {
18462                         app.adjType = "cch-started-services";
18463                     }
18464                 }
18465             }
18466             for (int conni = s.connections.size()-1;
18467                     conni >= 0 && (adj > ProcessList.FOREGROUND_APP_ADJ
18468                             || schedGroup == Process.THREAD_GROUP_BG_NONINTERACTIVE
18469                             || procState > ActivityManager.PROCESS_STATE_TOP);
18470                     conni--) {
18471                 ArrayList<ConnectionRecord> clist = s.connections.valueAt(conni);
18472                 for (int i = 0;
18473                         i < clist.size() && (adj > ProcessList.FOREGROUND_APP_ADJ
18474                                 || schedGroup == Process.THREAD_GROUP_BG_NONINTERACTIVE
18475                                 || procState > ActivityManager.PROCESS_STATE_TOP);
18476                         i++) {
18477                     // XXX should compute this based on the max of
18478                     // all connected clients.
18479                     ConnectionRecord cr = clist.get(i);
18480                     if (cr.binding.client == app) {
18481                         // Binding to ourself is not interesting.
18482                         continue;
18483                     }
18484                     if ((cr.flags&Context.BIND_WAIVE_PRIORITY) == 0) {
18485                         ProcessRecord client = cr.binding.client;
18486                         int clientAdj = computeOomAdjLocked(client, cachedAdj,
18487                                 TOP_APP, doingAll, now);
18488                         int clientProcState = client.curProcState;
18489                         if (clientProcState >= ActivityManager.PROCESS_STATE_CACHED_ACTIVITY) {
18490                             // If the other app is cached for any reason, for purposes here
18491                             // we are going to consider it empty.  The specific cached state
18492                             // doesn't propagate except under certain conditions.
18493                             clientProcState = ActivityManager.PROCESS_STATE_CACHED_EMPTY;
18494                         }
18495                         String adjType = null;
18496                         if ((cr.flags&Context.BIND_ALLOW_OOM_MANAGEMENT) != 0) {
18497                             // Not doing bind OOM management, so treat
18498                             // this guy more like a started service.
18499                             if (app.hasShownUi && app != mHomeProcess) {
18500                                 // If this process has shown some UI, let it immediately
18501                                 // go to the LRU list because it may be pretty heavy with
18502                                 // UI stuff.  We'll tag it with a label just to help
18503                                 // debug and understand what is going on.
18504                                 if (adj > clientAdj) {
18505                                     adjType = "cch-bound-ui-services";
18506                                 }
18507                                 app.cached = false;
18508                                 clientAdj = adj;
18509                                 clientProcState = procState;
18510                             } else {
18511                                 if (now >= (s.lastActivity
18512                                         + ActiveServices.MAX_SERVICE_INACTIVITY)) {
18513                                     // This service has not seen activity within
18514                                     // recent memory, so allow it to drop to the
18515                                     // LRU list if there is no other reason to keep
18516                                     // it around.  We'll also tag it with a label just
18517                                     // to help debug and undertand what is going on.
18518                                     if (adj > clientAdj) {
18519                                         adjType = "cch-bound-services";
18520                                     }
18521                                     clientAdj = adj;
18522                                 }
18523                             }
18524                         }
18525                         if (adj > clientAdj) {
18526                             // If this process has recently shown UI, and
18527                             // the process that is binding to it is less
18528                             // important than being visible, then we don't
18529                             // care about the binding as much as we care
18530                             // about letting this process get into the LRU
18531                             // list to be killed and restarted if needed for
18532                             // memory.
18533                             if (app.hasShownUi && app != mHomeProcess
18534                                     && clientAdj > ProcessList.PERCEPTIBLE_APP_ADJ) {
18535                                 adjType = "cch-bound-ui-services";
18536                             } else {
18537                                 if ((cr.flags&(Context.BIND_ABOVE_CLIENT
18538                                         |Context.BIND_IMPORTANT)) != 0) {
18539                                     adj = clientAdj >= ProcessList.PERSISTENT_SERVICE_ADJ
18540                                             ? clientAdj : ProcessList.PERSISTENT_SERVICE_ADJ;
18541                                 } else if ((cr.flags&Context.BIND_NOT_VISIBLE) != 0
18542                                         && clientAdj < ProcessList.PERCEPTIBLE_APP_ADJ
18543                                         && adj > ProcessList.PERCEPTIBLE_APP_ADJ) {
18544                                     adj = ProcessList.PERCEPTIBLE_APP_ADJ;
18545                                 } else if (clientAdj >= ProcessList.PERCEPTIBLE_APP_ADJ) {
18546                                     adj = clientAdj;
18547                                 } else {
18548                                     if (adj > ProcessList.VISIBLE_APP_ADJ) {
18549                                         adj = Math.max(clientAdj, ProcessList.VISIBLE_APP_ADJ);
18550                                     }
18551                                 }
18552                                 if (!client.cached) {
18553                                     app.cached = false;
18554                                 }
18555                                 adjType = "service";
18556                             }
18557                         }
18558                         if ((cr.flags&Context.BIND_NOT_FOREGROUND) == 0) {
18559                             if (client.curSchedGroup == Process.THREAD_GROUP_DEFAULT) {
18560                                 schedGroup = Process.THREAD_GROUP_DEFAULT;
18561                             }
18562                             if (clientProcState <= ActivityManager.PROCESS_STATE_TOP) {
18563                                 if (clientProcState == ActivityManager.PROCESS_STATE_TOP) {
18564                                     // Special handling of clients who are in the top state.
18565                                     // We *may* want to consider this process to be in the
18566                                     // top state as well, but only if there is not another
18567                                     // reason for it to be running.  Being on the top is a
18568                                     // special state, meaning you are specifically running
18569                                     // for the current top app.  If the process is already
18570                                     // running in the background for some other reason, it
18571                                     // is more important to continue considering it to be
18572                                     // in the background state.
18573                                     mayBeTop = true;
18574                                     clientProcState = ActivityManager.PROCESS_STATE_CACHED_EMPTY;
18575                                 } else {
18576                                     // Special handling for above-top states (persistent
18577                                     // processes).  These should not bring the current process
18578                                     // into the top state, since they are not on top.  Instead
18579                                     // give them the best state after that.
18580                                     if ((cr.flags&Context.BIND_FOREGROUND_SERVICE) != 0) {
18581                                         clientProcState =
18582                                                 ActivityManager.PROCESS_STATE_BOUND_FOREGROUND_SERVICE;
18583                                     } else if (mWakefulness
18584                                                     == PowerManagerInternal.WAKEFULNESS_AWAKE &&
18585                                             (cr.flags&Context.BIND_FOREGROUND_SERVICE_WHILE_AWAKE)
18586                                                     != 0) {
18587                                         clientProcState =
18588                                                 ActivityManager.PROCESS_STATE_BOUND_FOREGROUND_SERVICE;
18589                                     } else {
18590                                         clientProcState =
18591                                                 ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND;
18592                                     }
18593                                 }
18594                             }
18595                         } else {
18596                             if (clientProcState <
18597                                     ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND) {
18598                                 clientProcState =
18599                                         ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND;
18600                             }
18601                         }
18602                         if (procState > clientProcState) {
18603                             procState = clientProcState;
18604                         }
18605                         if (procState < ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND
18606                                 && (cr.flags&Context.BIND_SHOWING_UI) != 0) {
18607                             app.pendingUiClean = true;
18608                         }
18609                         if (adjType != null) {
18610                             app.adjType = adjType;
18611                             app.adjTypeCode = ActivityManager.RunningAppProcessInfo
18612                                     .REASON_SERVICE_IN_USE;
18613                             app.adjSource = cr.binding.client;
18614                             app.adjSourceProcState = clientProcState;
18615                             app.adjTarget = s.name;
18616                         }
18617                     }
18618                     if ((cr.flags&Context.BIND_TREAT_LIKE_ACTIVITY) != 0) {
18619                         app.treatLikeActivity = true;
18620                     }
18621                     final ActivityRecord a = cr.activity;
18622                     if ((cr.flags&Context.BIND_ADJUST_WITH_ACTIVITY) != 0) {
18623                         if (a != null && adj > ProcessList.FOREGROUND_APP_ADJ &&
18624                                 (a.visible || a.state == ActivityState.RESUMED
18625                                  || a.state == ActivityState.PAUSING)) {
18626                             adj = ProcessList.FOREGROUND_APP_ADJ;
18627                             if ((cr.flags&Context.BIND_NOT_FOREGROUND) == 0) {
18628                                 schedGroup = Process.THREAD_GROUP_DEFAULT;
18629                             }
18630                             app.cached = false;
18631                             app.adjType = "service";
18632                             app.adjTypeCode = ActivityManager.RunningAppProcessInfo
18633                                     .REASON_SERVICE_IN_USE;
18634                             app.adjSource = a;
18635                             app.adjSourceProcState = procState;
18636                             app.adjTarget = s.name;
18637                         }
18638                     }
18639                 }
18640             }
18641         }
18642
18643         for (int provi = app.pubProviders.size()-1;
18644                 provi >= 0 && (adj > ProcessList.FOREGROUND_APP_ADJ
18645                         || schedGroup == Process.THREAD_GROUP_BG_NONINTERACTIVE
18646                         || procState > ActivityManager.PROCESS_STATE_TOP);
18647                 provi--) {
18648             ContentProviderRecord cpr = app.pubProviders.valueAt(provi);
18649             for (int i = cpr.connections.size()-1;
18650                     i >= 0 && (adj > ProcessList.FOREGROUND_APP_ADJ
18651                             || schedGroup == Process.THREAD_GROUP_BG_NONINTERACTIVE
18652                             || procState > ActivityManager.PROCESS_STATE_TOP);
18653                     i--) {
18654                 ContentProviderConnection conn = cpr.connections.get(i);
18655                 ProcessRecord client = conn.client;
18656                 if (client == app) {
18657                     // Being our own client is not interesting.
18658                     continue;
18659                 }
18660                 int clientAdj = computeOomAdjLocked(client, cachedAdj, TOP_APP, doingAll, now);
18661                 int clientProcState = client.curProcState;
18662                 if (clientProcState >= ActivityManager.PROCESS_STATE_CACHED_ACTIVITY) {
18663                     // If the other app is cached for any reason, for purposes here
18664                     // we are going to consider it empty.
18665                     clientProcState = ActivityManager.PROCESS_STATE_CACHED_EMPTY;
18666                 }
18667                 if (adj > clientAdj) {
18668                     if (app.hasShownUi && app != mHomeProcess
18669                             && clientAdj > ProcessList.PERCEPTIBLE_APP_ADJ) {
18670                         app.adjType = "cch-ui-provider";
18671                     } else {
18672                         adj = clientAdj > ProcessList.FOREGROUND_APP_ADJ
18673                                 ? clientAdj : ProcessList.FOREGROUND_APP_ADJ;
18674                         app.adjType = "provider";
18675                     }
18676                     app.cached &= client.cached;
18677                     app.adjTypeCode = ActivityManager.RunningAppProcessInfo
18678                             .REASON_PROVIDER_IN_USE;
18679                     app.adjSource = client;
18680                     app.adjSourceProcState = clientProcState;
18681                     app.adjTarget = cpr.name;
18682                 }
18683                 if (clientProcState <= ActivityManager.PROCESS_STATE_TOP) {
18684                     if (clientProcState == ActivityManager.PROCESS_STATE_TOP) {
18685                         // Special handling of clients who are in the top state.
18686                         // We *may* want to consider this process to be in the
18687                         // top state as well, but only if there is not another
18688                         // reason for it to be running.  Being on the top is a
18689                         // special state, meaning you are specifically running
18690                         // for the current top app.  If the process is already
18691                         // running in the background for some other reason, it
18692                         // is more important to continue considering it to be
18693                         // in the background state.
18694                         mayBeTop = true;
18695                         clientProcState = ActivityManager.PROCESS_STATE_CACHED_EMPTY;
18696                     } else {
18697                         // Special handling for above-top states (persistent
18698                         // processes).  These should not bring the current process
18699                         // into the top state, since they are not on top.  Instead
18700                         // give them the best state after that.
18701                         clientProcState =
18702                                 ActivityManager.PROCESS_STATE_BOUND_FOREGROUND_SERVICE;
18703                     }
18704                 }
18705                 if (procState > clientProcState) {
18706                     procState = clientProcState;
18707                 }
18708                 if (client.curSchedGroup == Process.THREAD_GROUP_DEFAULT) {
18709                     schedGroup = Process.THREAD_GROUP_DEFAULT;
18710                 }
18711             }
18712             // If the provider has external (non-framework) process
18713             // dependencies, ensure that its adjustment is at least
18714             // FOREGROUND_APP_ADJ.
18715             if (cpr.hasExternalProcessHandles()) {
18716                 if (adj > ProcessList.FOREGROUND_APP_ADJ) {
18717                     adj = ProcessList.FOREGROUND_APP_ADJ;
18718                     schedGroup = Process.THREAD_GROUP_DEFAULT;
18719                     app.cached = false;
18720                     app.adjType = "provider";
18721                     app.adjTarget = cpr.name;
18722                 }
18723                 if (procState > ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND) {
18724                     procState = ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND;
18725                 }
18726             }
18727         }
18728
18729         if (app.lastProviderTime > 0 && (app.lastProviderTime+CONTENT_PROVIDER_RETAIN_TIME) > now) {
18730             if (adj > ProcessList.PREVIOUS_APP_ADJ) {
18731                 adj = ProcessList.PREVIOUS_APP_ADJ;
18732                 schedGroup = Process.THREAD_GROUP_BG_NONINTERACTIVE;
18733                 app.cached = false;
18734                 app.adjType = "provider";
18735             }
18736             if (procState > ActivityManager.PROCESS_STATE_LAST_ACTIVITY) {
18737                 procState = ActivityManager.PROCESS_STATE_LAST_ACTIVITY;
18738             }
18739         }
18740
18741         if (mayBeTop && procState > ActivityManager.PROCESS_STATE_TOP) {
18742             // A client of one of our services or providers is in the top state.  We
18743             // *may* want to be in the top state, but not if we are already running in
18744             // the background for some other reason.  For the decision here, we are going
18745             // to pick out a few specific states that we want to remain in when a client
18746             // is top (states that tend to be longer-term) and otherwise allow it to go
18747             // to the top state.
18748             switch (procState) {
18749                 case ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND:
18750                 case ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND:
18751                 case ActivityManager.PROCESS_STATE_SERVICE:
18752                     // These all are longer-term states, so pull them up to the top
18753                     // of the background states, but not all the way to the top state.
18754                     procState = ActivityManager.PROCESS_STATE_BOUND_FOREGROUND_SERVICE;
18755                     break;
18756                 default:
18757                     // Otherwise, top is a better choice, so take it.
18758                     procState = ActivityManager.PROCESS_STATE_TOP;
18759                     break;
18760             }
18761         }
18762
18763         if (procState >= ActivityManager.PROCESS_STATE_CACHED_EMPTY) {
18764             if (app.hasClientActivities) {
18765                 // This is a cached process, but with client activities.  Mark it so.
18766                 procState = ActivityManager.PROCESS_STATE_CACHED_ACTIVITY_CLIENT;
18767                 app.adjType = "cch-client-act";
18768             } else if (app.treatLikeActivity) {
18769                 // This is a cached process, but somebody wants us to treat it like it has
18770                 // an activity, okay!
18771                 procState = ActivityManager.PROCESS_STATE_CACHED_ACTIVITY;
18772                 app.adjType = "cch-as-act";
18773             }
18774         }
18775
18776         if (adj == ProcessList.SERVICE_ADJ) {
18777             if (doingAll) {
18778                 app.serviceb = mNewNumAServiceProcs > (mNumServiceProcs/3);
18779                 mNewNumServiceProcs++;
18780                 //Slog.i(TAG, "ADJ " + app + " serviceb=" + app.serviceb);
18781                 if (!app.serviceb) {
18782                     // This service isn't far enough down on the LRU list to
18783                     // normally be a B service, but if we are low on RAM and it
18784                     // is large we want to force it down since we would prefer to
18785                     // keep launcher over it.
18786                     if (mLastMemoryLevel > ProcessStats.ADJ_MEM_FACTOR_NORMAL
18787                             && app.lastPss >= mProcessList.getCachedRestoreThresholdKb()) {
18788                         app.serviceHighRam = true;
18789                         app.serviceb = true;
18790                         //Slog.i(TAG, "ADJ " + app + " high ram!");
18791                     } else {
18792                         mNewNumAServiceProcs++;
18793                         //Slog.i(TAG, "ADJ " + app + " not high ram!");
18794                     }
18795                 } else {
18796                     app.serviceHighRam = false;
18797                 }
18798             }
18799             if (app.serviceb) {
18800                 adj = ProcessList.SERVICE_B_ADJ;
18801             }
18802         }
18803
18804         app.curRawAdj = adj;
18805
18806         //Slog.i(TAG, "OOM ADJ " + app + ": pid=" + app.pid +
18807         //      " adj=" + adj + " curAdj=" + app.curAdj + " maxAdj=" + app.maxAdj);
18808         if (adj > app.maxAdj) {
18809             adj = app.maxAdj;
18810             if (app.maxAdj <= ProcessList.PERCEPTIBLE_APP_ADJ) {
18811                 schedGroup = Process.THREAD_GROUP_DEFAULT;
18812             }
18813         }
18814
18815         // Do final modification to adj.  Everything we do between here and applying
18816         // the final setAdj must be done in this function, because we will also use
18817         // it when computing the final cached adj later.  Note that we don't need to
18818         // worry about this for max adj above, since max adj will always be used to
18819         // keep it out of the cached vaues.
18820         app.curAdj = app.modifyRawOomAdj(adj);
18821         app.curSchedGroup = schedGroup;
18822         app.curProcState = procState;
18823         app.foregroundActivities = foregroundActivities;
18824
18825         return app.curRawAdj;
18826     }
18827
18828     /**
18829      * Record new PSS sample for a process.
18830      */
18831     void recordPssSampleLocked(ProcessRecord proc, int procState, long pss, long uss, long now) {
18832         EventLogTags.writeAmPss(proc.pid, proc.uid, proc.processName, pss * 1024, uss * 1024);
18833         proc.lastPssTime = now;
18834         proc.baseProcessTracker.addPss(pss, uss, true, proc.pkgList);
18835         if (DEBUG_PSS) Slog.d(TAG_PSS,
18836                 "PSS of " + proc.toShortString() + ": " + pss + " lastPss=" + proc.lastPss
18837                 + " state=" + ProcessList.makeProcStateString(procState));
18838         if (proc.initialIdlePss == 0) {
18839             proc.initialIdlePss = pss;
18840         }
18841         proc.lastPss = pss;
18842         if (procState >= ActivityManager.PROCESS_STATE_HOME) {
18843             proc.lastCachedPss = pss;
18844         }
18845
18846         final SparseArray<Pair<Long, String>> watchUids
18847                 = mMemWatchProcesses.getMap().get(proc.processName);
18848         Long check = null;
18849         if (watchUids != null) {
18850             Pair<Long, String> val = watchUids.get(proc.uid);
18851             if (val == null) {
18852                 val = watchUids.get(0);
18853             }
18854             if (val != null) {
18855                 check = val.first;
18856             }
18857         }
18858         if (check != null) {
18859             if ((pss * 1024) >= check && proc.thread != null && mMemWatchDumpProcName == null) {
18860                 boolean isDebuggable = "1".equals(SystemProperties.get(SYSTEM_DEBUGGABLE, "0"));
18861                 if (!isDebuggable) {
18862                     if ((proc.info.flags&ApplicationInfo.FLAG_DEBUGGABLE) != 0) {
18863                         isDebuggable = true;
18864                     }
18865                 }
18866                 if (isDebuggable) {
18867                     Slog.w(TAG, "Process " + proc + " exceeded pss limit " + check + "; reporting");
18868                     final ProcessRecord myProc = proc;
18869                     final File heapdumpFile = DumpHeapProvider.getJavaFile();
18870                     mMemWatchDumpProcName = proc.processName;
18871                     mMemWatchDumpFile = heapdumpFile.toString();
18872                     mMemWatchDumpPid = proc.pid;
18873                     mMemWatchDumpUid = proc.uid;
18874                     BackgroundThread.getHandler().post(new Runnable() {
18875                         @Override
18876                         public void run() {
18877                             revokeUriPermission(ActivityThread.currentActivityThread()
18878                                             .getApplicationThread(),
18879                                     DumpHeapActivity.JAVA_URI,
18880                                     Intent.FLAG_GRANT_READ_URI_PERMISSION
18881                                             | Intent.FLAG_GRANT_WRITE_URI_PERMISSION,
18882                                     UserHandle.myUserId());
18883                             ParcelFileDescriptor fd = null;
18884                             try {
18885                                 heapdumpFile.delete();
18886                                 fd = ParcelFileDescriptor.open(heapdumpFile,
18887                                         ParcelFileDescriptor.MODE_CREATE |
18888                                                 ParcelFileDescriptor.MODE_TRUNCATE |
18889                                                 ParcelFileDescriptor.MODE_WRITE_ONLY |
18890                                                 ParcelFileDescriptor.MODE_APPEND);
18891                                 IApplicationThread thread = myProc.thread;
18892                                 if (thread != null) {
18893                                     try {
18894                                         if (DEBUG_PSS) Slog.d(TAG_PSS,
18895                                                 "Requesting dump heap from "
18896                                                 + myProc + " to " + heapdumpFile);
18897                                         thread.dumpHeap(true, heapdumpFile.toString(), fd);
18898                                     } catch (RemoteException e) {
18899                                     }
18900                                 }
18901                             } catch (FileNotFoundException e) {
18902                                 e.printStackTrace();
18903                             } finally {
18904                                 if (fd != null) {
18905                                     try {
18906                                         fd.close();
18907                                     } catch (IOException e) {
18908                                     }
18909                                 }
18910                             }
18911                         }
18912                     });
18913                 } else {
18914                     Slog.w(TAG, "Process " + proc + " exceeded pss limit " + check
18915                             + ", but debugging not enabled");
18916                 }
18917             }
18918         }
18919     }
18920
18921     /**
18922      * Schedule PSS collection of a process.
18923      */
18924     void requestPssLocked(ProcessRecord proc, int procState) {
18925         if (mPendingPssProcesses.contains(proc)) {
18926             return;
18927         }
18928         if (mPendingPssProcesses.size() == 0) {
18929             mBgHandler.sendEmptyMessage(COLLECT_PSS_BG_MSG);
18930         }
18931         if (DEBUG_PSS) Slog.d(TAG_PSS, "Requesting PSS of: " + proc);
18932         proc.pssProcState = procState;
18933         mPendingPssProcesses.add(proc);
18934     }
18935
18936     /**
18937      * Schedule PSS collection of all processes.
18938      */
18939     void requestPssAllProcsLocked(long now, boolean always, boolean memLowered) {
18940         if (!always) {
18941             if (now < (mLastFullPssTime +
18942                     (memLowered ? FULL_PSS_LOWERED_INTERVAL : FULL_PSS_MIN_INTERVAL))) {
18943                 return;
18944             }
18945         }
18946         if (DEBUG_PSS) Slog.d(TAG_PSS, "Requesting PSS of all procs!  memLowered=" + memLowered);
18947         mLastFullPssTime = now;
18948         mFullPssPending = true;
18949         mPendingPssProcesses.ensureCapacity(mLruProcesses.size());
18950         mPendingPssProcesses.clear();
18951         for (int i = mLruProcesses.size() - 1; i >= 0; i--) {
18952             ProcessRecord app = mLruProcesses.get(i);
18953             if (app.thread == null
18954                     || app.curProcState == ActivityManager.PROCESS_STATE_NONEXISTENT) {
18955                 continue;
18956             }
18957             if (memLowered || now > (app.lastStateTime+ProcessList.PSS_ALL_INTERVAL)) {
18958                 app.pssProcState = app.setProcState;
18959                 app.nextPssTime = ProcessList.computeNextPssTime(app.curProcState, true,
18960                         mTestPssMode, isSleeping(), now);
18961                 mPendingPssProcesses.add(app);
18962             }
18963         }
18964         mBgHandler.sendEmptyMessage(COLLECT_PSS_BG_MSG);
18965     }
18966
18967     public void setTestPssMode(boolean enabled) {
18968         synchronized (this) {
18969             mTestPssMode = enabled;
18970             if (enabled) {
18971                 // Whenever we enable the mode, we want to take a snapshot all of current
18972                 // process mem use.
18973                 requestPssAllProcsLocked(SystemClock.uptimeMillis(), true, true);
18974             }
18975         }
18976     }
18977
18978     /**
18979      * Ask a given process to GC right now.
18980      */
18981     final void performAppGcLocked(ProcessRecord app) {
18982         try {
18983             app.lastRequestedGc = SystemClock.uptimeMillis();
18984             if (app.thread != null) {
18985                 if (app.reportLowMemory) {
18986                     app.reportLowMemory = false;
18987                     app.thread.scheduleLowMemory();
18988                 } else {
18989                     app.thread.processInBackground();
18990                 }
18991             }
18992         } catch (Exception e) {
18993             // whatever.
18994         }
18995     }
18996
18997     /**
18998      * Returns true if things are idle enough to perform GCs.
18999      */
19000     private final boolean canGcNowLocked() {
19001         boolean processingBroadcasts = false;
19002         for (BroadcastQueue q : mBroadcastQueues) {
19003             if (q.mParallelBroadcasts.size() != 0 || q.mOrderedBroadcasts.size() != 0) {
19004                 processingBroadcasts = true;
19005             }
19006         }
19007         return !processingBroadcasts
19008                 && (isSleeping() || mStackSupervisor.allResumedActivitiesIdle());
19009     }
19010
19011     /**
19012      * Perform GCs on all processes that are waiting for it, but only
19013      * if things are idle.
19014      */
19015     final void performAppGcsLocked() {
19016         final int N = mProcessesToGc.size();
19017         if (N <= 0) {
19018             return;
19019         }
19020         if (canGcNowLocked()) {
19021             while (mProcessesToGc.size() > 0) {
19022                 ProcessRecord proc = mProcessesToGc.remove(0);
19023                 if (proc.curRawAdj > ProcessList.PERCEPTIBLE_APP_ADJ || proc.reportLowMemory) {
19024                     if ((proc.lastRequestedGc+GC_MIN_INTERVAL)
19025                             <= SystemClock.uptimeMillis()) {
19026                         // To avoid spamming the system, we will GC processes one
19027                         // at a time, waiting a few seconds between each.
19028                         performAppGcLocked(proc);
19029                         scheduleAppGcsLocked();
19030                         return;
19031                     } else {
19032                         // It hasn't been long enough since we last GCed this
19033                         // process...  put it in the list to wait for its time.
19034                         addProcessToGcListLocked(proc);
19035                         break;
19036                     }
19037                 }
19038             }
19039
19040             scheduleAppGcsLocked();
19041         }
19042     }
19043
19044     /**
19045      * If all looks good, perform GCs on all processes waiting for them.
19046      */
19047     final void performAppGcsIfAppropriateLocked() {
19048         if (canGcNowLocked()) {
19049             performAppGcsLocked();
19050             return;
19051         }
19052         // Still not idle, wait some more.
19053         scheduleAppGcsLocked();
19054     }
19055
19056     /**
19057      * Schedule the execution of all pending app GCs.
19058      */
19059     final void scheduleAppGcsLocked() {
19060         mHandler.removeMessages(GC_BACKGROUND_PROCESSES_MSG);
19061
19062         if (mProcessesToGc.size() > 0) {
19063             // Schedule a GC for the time to the next process.
19064             ProcessRecord proc = mProcessesToGc.get(0);
19065             Message msg = mHandler.obtainMessage(GC_BACKGROUND_PROCESSES_MSG);
19066
19067             long when = proc.lastRequestedGc + GC_MIN_INTERVAL;
19068             long now = SystemClock.uptimeMillis();
19069             if (when < (now+GC_TIMEOUT)) {
19070                 when = now + GC_TIMEOUT;
19071             }
19072             mHandler.sendMessageAtTime(msg, when);
19073         }
19074     }
19075
19076     /**
19077      * Add a process to the array of processes waiting to be GCed.  Keeps the
19078      * list in sorted order by the last GC time.  The process can't already be
19079      * on the list.
19080      */
19081     final void addProcessToGcListLocked(ProcessRecord proc) {
19082         boolean added = false;
19083         for (int i=mProcessesToGc.size()-1; i>=0; i--) {
19084             if (mProcessesToGc.get(i).lastRequestedGc <
19085                     proc.lastRequestedGc) {
19086                 added = true;
19087                 mProcessesToGc.add(i+1, proc);
19088                 break;
19089             }
19090         }
19091         if (!added) {
19092             mProcessesToGc.add(0, proc);
19093         }
19094     }
19095
19096     /**
19097      * Set up to ask a process to GC itself.  This will either do it
19098      * immediately, or put it on the list of processes to gc the next
19099      * time things are idle.
19100      */
19101     final void scheduleAppGcLocked(ProcessRecord app) {
19102         long now = SystemClock.uptimeMillis();
19103         if ((app.lastRequestedGc+GC_MIN_INTERVAL) > now) {
19104             return;
19105         }
19106         if (!mProcessesToGc.contains(app)) {
19107             addProcessToGcListLocked(app);
19108             scheduleAppGcsLocked();
19109         }
19110     }
19111
19112     final void checkExcessivePowerUsageLocked(boolean doKills) {
19113         updateCpuStatsNow();
19114
19115         BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
19116         boolean doWakeKills = doKills;
19117         boolean doCpuKills = doKills;
19118         if (mLastPowerCheckRealtime == 0) {
19119             doWakeKills = false;
19120         }
19121         if (mLastPowerCheckUptime == 0) {
19122             doCpuKills = false;
19123         }
19124         if (stats.isScreenOn()) {
19125             doWakeKills = false;
19126         }
19127         final long curRealtime = SystemClock.elapsedRealtime();
19128         final long realtimeSince = curRealtime - mLastPowerCheckRealtime;
19129         final long curUptime = SystemClock.uptimeMillis();
19130         final long uptimeSince = curUptime - mLastPowerCheckUptime;
19131         mLastPowerCheckRealtime = curRealtime;
19132         mLastPowerCheckUptime = curUptime;
19133         if (realtimeSince < WAKE_LOCK_MIN_CHECK_DURATION) {
19134             doWakeKills = false;
19135         }
19136         if (uptimeSince < CPU_MIN_CHECK_DURATION) {
19137             doCpuKills = false;
19138         }
19139         int i = mLruProcesses.size();
19140         while (i > 0) {
19141             i--;
19142             ProcessRecord app = mLruProcesses.get(i);
19143             if (app.setProcState >= ActivityManager.PROCESS_STATE_HOME) {
19144                 long wtime;
19145                 synchronized (stats) {
19146                     wtime = stats.getProcessWakeTime(app.info.uid,
19147                             app.pid, curRealtime);
19148                 }
19149                 long wtimeUsed = wtime - app.lastWakeTime;
19150                 long cputimeUsed = app.curCpuTime - app.lastCpuTime;
19151                 if (DEBUG_POWER) {
19152                     StringBuilder sb = new StringBuilder(128);
19153                     sb.append("Wake for ");
19154                     app.toShortString(sb);
19155                     sb.append(": over ");
19156                     TimeUtils.formatDuration(realtimeSince, sb);
19157                     sb.append(" used ");
19158                     TimeUtils.formatDuration(wtimeUsed, sb);
19159                     sb.append(" (");
19160                     sb.append((wtimeUsed*100)/realtimeSince);
19161                     sb.append("%)");
19162                     Slog.i(TAG_POWER, sb.toString());
19163                     sb.setLength(0);
19164                     sb.append("CPU for ");
19165                     app.toShortString(sb);
19166                     sb.append(": over ");
19167                     TimeUtils.formatDuration(uptimeSince, sb);
19168                     sb.append(" used ");
19169                     TimeUtils.formatDuration(cputimeUsed, sb);
19170                     sb.append(" (");
19171                     sb.append((cputimeUsed*100)/uptimeSince);
19172                     sb.append("%)");
19173                     Slog.i(TAG_POWER, sb.toString());
19174                 }
19175                 // If a process has held a wake lock for more
19176                 // than 50% of the time during this period,
19177                 // that sounds bad.  Kill!
19178                 if (doWakeKills && realtimeSince > 0
19179                         && ((wtimeUsed*100)/realtimeSince) >= 50) {
19180                     synchronized (stats) {
19181                         stats.reportExcessiveWakeLocked(app.info.uid, app.processName,
19182                                 realtimeSince, wtimeUsed);
19183                     }
19184                     app.kill("excessive wake held " + wtimeUsed + " during " + realtimeSince, true);
19185                     app.baseProcessTracker.reportExcessiveWake(app.pkgList);
19186                 } else if (doCpuKills && uptimeSince > 0
19187                         && ((cputimeUsed*100)/uptimeSince) >= 25) {
19188                     synchronized (stats) {
19189                         stats.reportExcessiveCpuLocked(app.info.uid, app.processName,
19190                                 uptimeSince, cputimeUsed);
19191                     }
19192                     app.kill("excessive cpu " + cputimeUsed + " during " + uptimeSince, true);
19193                     app.baseProcessTracker.reportExcessiveCpu(app.pkgList);
19194                 } else {
19195                     app.lastWakeTime = wtime;
19196                     app.lastCpuTime = app.curCpuTime;
19197                 }
19198             }
19199         }
19200     }
19201
19202     private final boolean applyOomAdjLocked(ProcessRecord app, boolean doingAll, long now,
19203             long nowElapsed) {
19204         boolean success = true;
19205
19206         if (app.curRawAdj != app.setRawAdj) {
19207             app.setRawAdj = app.curRawAdj;
19208         }
19209
19210         int changes = 0;
19211
19212         if (app.curAdj != app.setAdj) {
19213             ProcessList.setOomAdj(app.pid, app.info.uid, app.curAdj);
19214             if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG_OOM_ADJ,
19215                     "Set " + app.pid + " " + app.processName + " adj " + app.curAdj + ": "
19216                     + app.adjType);
19217             app.setAdj = app.curAdj;
19218         }
19219
19220         if (app.setSchedGroup != app.curSchedGroup) {
19221             app.setSchedGroup = app.curSchedGroup;
19222             if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG_OOM_ADJ,
19223                     "Setting process group of " + app.processName
19224                     + " to " + app.curSchedGroup);
19225             if (app.waitingToKill != null && app.curReceiver == null
19226                     && app.setSchedGroup == Process.THREAD_GROUP_BG_NONINTERACTIVE) {
19227                 app.kill(app.waitingToKill, true);
19228                 success = false;
19229             } else {
19230                 if (true) {
19231                     long oldId = Binder.clearCallingIdentity();
19232                     try {
19233                         Process.setProcessGroup(app.pid, app.curSchedGroup);
19234                     } catch (Exception e) {
19235                         Slog.w(TAG, "Failed setting process group of " + app.pid
19236                                 + " to " + app.curSchedGroup);
19237                         e.printStackTrace();
19238                     } finally {
19239                         Binder.restoreCallingIdentity(oldId);
19240                     }
19241                 } else {
19242                     if (app.thread != null) {
19243                         try {
19244                             app.thread.setSchedulingGroup(app.curSchedGroup);
19245                         } catch (RemoteException e) {
19246                         }
19247                     }
19248                 }
19249             }
19250         }
19251         if (app.repForegroundActivities != app.foregroundActivities) {
19252             app.repForegroundActivities = app.foregroundActivities;
19253             changes |= ProcessChangeItem.CHANGE_ACTIVITIES;
19254         }
19255         if (app.repProcState != app.curProcState) {
19256             app.repProcState = app.curProcState;
19257             changes |= ProcessChangeItem.CHANGE_PROCESS_STATE;
19258             if (app.thread != null) {
19259                 try {
19260                     if (false) {
19261                         //RuntimeException h = new RuntimeException("here");
19262                         Slog.i(TAG, "Sending new process state " + app.repProcState
19263                                 + " to " + app /*, h*/);
19264                     }
19265                     app.thread.setProcessState(app.repProcState);
19266                 } catch (RemoteException e) {
19267                 }
19268             }
19269         }
19270         if (app.setProcState == ActivityManager.PROCESS_STATE_NONEXISTENT
19271                 || ProcessList.procStatesDifferForMem(app.curProcState, app.setProcState)) {
19272             if (false && mTestPssMode && app.setProcState >= 0 && app.lastStateTime <= (now-200)) {
19273                 // Experimental code to more aggressively collect pss while
19274                 // running test...  the problem is that this tends to collect
19275                 // the data right when a process is transitioning between process
19276                 // states, which well tend to give noisy data.
19277                 long start = SystemClock.uptimeMillis();
19278                 long pss = Debug.getPss(app.pid, mTmpLong, null);
19279                 recordPssSampleLocked(app, app.curProcState, pss, mTmpLong[0], now);
19280                 mPendingPssProcesses.remove(app);
19281                 Slog.i(TAG, "Recorded pss for " + app + " state " + app.setProcState
19282                         + " to " + app.curProcState + ": "
19283                         + (SystemClock.uptimeMillis()-start) + "ms");
19284             }
19285             app.lastStateTime = now;
19286             app.nextPssTime = ProcessList.computeNextPssTime(app.curProcState, true,
19287                     mTestPssMode, isSleeping(), now);
19288             if (DEBUG_PSS) Slog.d(TAG_PSS, "Process state change from "
19289                     + ProcessList.makeProcStateString(app.setProcState) + " to "
19290                     + ProcessList.makeProcStateString(app.curProcState) + " next pss in "
19291                     + (app.nextPssTime-now) + ": " + app);
19292         } else {
19293             if (now > app.nextPssTime || (now > (app.lastPssTime+ProcessList.PSS_MAX_INTERVAL)
19294                     && now > (app.lastStateTime+ProcessList.minTimeFromStateChange(
19295                     mTestPssMode)))) {
19296                 requestPssLocked(app, app.setProcState);
19297                 app.nextPssTime = ProcessList.computeNextPssTime(app.curProcState, false,
19298                         mTestPssMode, isSleeping(), now);
19299             } else if (false && DEBUG_PSS) Slog.d(TAG_PSS,
19300                     "Not requesting PSS of " + app + ": next=" + (app.nextPssTime-now));
19301         }
19302         if (app.setProcState != app.curProcState) {
19303             if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG_OOM_ADJ,
19304                     "Proc state change of " + app.processName
19305                             + " to " + app.curProcState);
19306             boolean setImportant = app.setProcState < ActivityManager.PROCESS_STATE_SERVICE;
19307             boolean curImportant = app.curProcState < ActivityManager.PROCESS_STATE_SERVICE;
19308             if (setImportant && !curImportant) {
19309                 // This app is no longer something we consider important enough to allow to
19310                 // use arbitrary amounts of battery power.  Note
19311                 // its current wake lock time to later know to kill it if
19312                 // it is not behaving well.
19313                 BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
19314                 synchronized (stats) {
19315                     app.lastWakeTime = stats.getProcessWakeTime(app.info.uid,
19316                             app.pid, nowElapsed);
19317                 }
19318                 app.lastCpuTime = app.curCpuTime;
19319
19320             }
19321             // Inform UsageStats of important process state change
19322             // Must be called before updating setProcState
19323             maybeUpdateUsageStatsLocked(app, nowElapsed);
19324
19325             app.setProcState = app.curProcState;
19326             if (app.setProcState >= ActivityManager.PROCESS_STATE_HOME) {
19327                 app.notCachedSinceIdle = false;
19328             }
19329             if (!doingAll) {
19330                 setProcessTrackerStateLocked(app, mProcessStats.getMemFactorLocked(), now);
19331             } else {
19332                 app.procStateChanged = true;
19333             }
19334         } else if (app.reportedInteraction && (nowElapsed-app.interactionEventTime)
19335                 > USAGE_STATS_INTERACTION_INTERVAL) {
19336             // For apps that sit around for a long time in the interactive state, we need
19337             // to report this at least once a day so they don't go idle.
19338             maybeUpdateUsageStatsLocked(app, nowElapsed);
19339         }
19340
19341         if (changes != 0) {
19342             if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG_PROCESS_OBSERVERS,
19343                     "Changes in " + app + ": " + changes);
19344             int i = mPendingProcessChanges.size()-1;
19345             ProcessChangeItem item = null;
19346             while (i >= 0) {
19347                 item = mPendingProcessChanges.get(i);
19348                 if (item.pid == app.pid) {
19349                     if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG_PROCESS_OBSERVERS,
19350                             "Re-using existing item: " + item);
19351                     break;
19352                 }
19353                 i--;
19354             }
19355             if (i < 0) {
19356                 // No existing item in pending changes; need a new one.
19357                 final int NA = mAvailProcessChanges.size();
19358                 if (NA > 0) {
19359                     item = mAvailProcessChanges.remove(NA-1);
19360                     if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG_PROCESS_OBSERVERS,
19361                             "Retrieving available item: " + item);
19362                 } else {
19363                     item = new ProcessChangeItem();
19364                     if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG_PROCESS_OBSERVERS,
19365                             "Allocating new item: " + item);
19366                 }
19367                 item.changes = 0;
19368                 item.pid = app.pid;
19369                 item.uid = app.info.uid;
19370                 if (mPendingProcessChanges.size() == 0) {
19371                     if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG_PROCESS_OBSERVERS,
19372                             "*** Enqueueing dispatch processes changed!");
19373                     mUiHandler.obtainMessage(DISPATCH_PROCESSES_CHANGED_UI_MSG).sendToTarget();
19374                 }
19375                 mPendingProcessChanges.add(item);
19376             }
19377             item.changes |= changes;
19378             item.processState = app.repProcState;
19379             item.foregroundActivities = app.repForegroundActivities;
19380             if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG_PROCESS_OBSERVERS,
19381                     "Item " + Integer.toHexString(System.identityHashCode(item))
19382                     + " " + app.toShortString() + ": changes=" + item.changes
19383                     + " procState=" + item.processState
19384                     + " foreground=" + item.foregroundActivities
19385                     + " type=" + app.adjType + " source=" + app.adjSource
19386                     + " target=" + app.adjTarget);
19387         }
19388
19389         return success;
19390     }
19391
19392     private final void enqueueUidChangeLocked(UidRecord uidRec, int uid, int change) {
19393         final UidRecord.ChangeItem pendingChange;
19394         if (uidRec == null || uidRec.pendingChange == null) {
19395             if (mPendingUidChanges.size() == 0) {
19396                 if (DEBUG_UID_OBSERVERS) Slog.i(TAG_UID_OBSERVERS,
19397                         "*** Enqueueing dispatch uid changed!");
19398                 mUiHandler.obtainMessage(DISPATCH_UIDS_CHANGED_UI_MSG).sendToTarget();
19399             }
19400             final int NA = mAvailUidChanges.size();
19401             if (NA > 0) {
19402                 pendingChange = mAvailUidChanges.remove(NA-1);
19403                 if (DEBUG_UID_OBSERVERS) Slog.i(TAG_UID_OBSERVERS,
19404                         "Retrieving available item: " + pendingChange);
19405             } else {
19406                 pendingChange = new UidRecord.ChangeItem();
19407                 if (DEBUG_UID_OBSERVERS) Slog.i(TAG_UID_OBSERVERS,
19408                         "Allocating new item: " + pendingChange);
19409             }
19410             if (uidRec != null) {
19411                 uidRec.pendingChange = pendingChange;
19412                 if (change == UidRecord.CHANGE_GONE && !uidRec.idle) {
19413                     // If this uid is going away, and we haven't yet reported it is gone,
19414                     // then do so now.
19415                     change = UidRecord.CHANGE_GONE_IDLE;
19416                 }
19417             } else if (uid < 0) {
19418                 throw new IllegalArgumentException("No UidRecord or uid");
19419             }
19420             pendingChange.uidRecord = uidRec;
19421             pendingChange.uid = uidRec != null ? uidRec.uid : uid;
19422             mPendingUidChanges.add(pendingChange);
19423         } else {
19424             pendingChange = uidRec.pendingChange;
19425             if (change == UidRecord.CHANGE_GONE && pendingChange.change == UidRecord.CHANGE_IDLE) {
19426                 change = UidRecord.CHANGE_GONE_IDLE;
19427             }
19428         }
19429         pendingChange.change = change;
19430         pendingChange.processState = uidRec != null
19431                 ? uidRec.setProcState : ActivityManager.PROCESS_STATE_NONEXISTENT;
19432     }
19433
19434     private void maybeUpdateProviderUsageStatsLocked(ProcessRecord app, String providerPkgName,
19435             String authority) {
19436         if (app == null) return;
19437         if (app.curProcState <= ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND) {
19438             UserState userState = mUserController.getStartedUserStateLocked(app.userId);
19439             if (userState == null) return;
19440             final long now = SystemClock.elapsedRealtime();
19441             Long lastReported = userState.mProviderLastReportedFg.get(authority);
19442             if (lastReported == null || lastReported < now - 60 * 1000L) {
19443                 mUsageStatsService.reportContentProviderUsage(
19444                         authority, providerPkgName, app.userId);
19445                 userState.mProviderLastReportedFg.put(authority, now);
19446             }
19447         }
19448     }
19449
19450     private void maybeUpdateUsageStatsLocked(ProcessRecord app, long nowElapsed) {
19451         if (DEBUG_USAGE_STATS) {
19452             Slog.d(TAG, "Checking proc [" + Arrays.toString(app.getPackageList())
19453                     + "] state changes: old = " + app.setProcState + ", new = "
19454                     + app.curProcState);
19455         }
19456         if (mUsageStatsService == null) {
19457             return;
19458         }
19459         boolean isInteraction;
19460         // To avoid some abuse patterns, we are going to be careful about what we consider
19461         // to be an app interaction.  Being the top activity doesn't count while the display
19462         // is sleeping, nor do short foreground services.
19463         if (app.curProcState <= ActivityManager.PROCESS_STATE_BOUND_FOREGROUND_SERVICE) {
19464             isInteraction = true;
19465             app.fgInteractionTime = 0;
19466         } else if (app.curProcState <= ActivityManager.PROCESS_STATE_TOP_SLEEPING) {
19467             if (app.fgInteractionTime == 0) {
19468                 app.fgInteractionTime = nowElapsed;
19469                 isInteraction = false;
19470             } else {
19471                 isInteraction = nowElapsed > app.fgInteractionTime + SERVICE_USAGE_INTERACTION_TIME;
19472             }
19473         } else {
19474             isInteraction = app.curProcState
19475                     <= ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND;
19476             app.fgInteractionTime = 0;
19477         }
19478         if (isInteraction && (!app.reportedInteraction
19479                 || (nowElapsed-app.interactionEventTime) > USAGE_STATS_INTERACTION_INTERVAL)) {
19480             app.interactionEventTime = nowElapsed;
19481             String[] packages = app.getPackageList();
19482             if (packages != null) {
19483                 for (int i = 0; i < packages.length; i++) {
19484                     mUsageStatsService.reportEvent(packages[i], app.userId,
19485                             UsageEvents.Event.SYSTEM_INTERACTION);
19486                 }
19487             }
19488         }
19489         app.reportedInteraction = isInteraction;
19490         if (!isInteraction) {
19491             app.interactionEventTime = 0;
19492         }
19493     }
19494
19495     private final void setProcessTrackerStateLocked(ProcessRecord proc, int memFactor, long now) {
19496         if (proc.thread != null) {
19497             if (proc.baseProcessTracker != null) {
19498                 proc.baseProcessTracker.setState(proc.repProcState, memFactor, now, proc.pkgList);
19499             }
19500             if (proc.repProcState >= 0) {
19501                 mBatteryStatsService.noteProcessState(proc.processName, proc.info.uid,
19502                         proc.repProcState);
19503             }
19504         }
19505     }
19506
19507     private final boolean updateOomAdjLocked(ProcessRecord app, int cachedAdj,
19508             ProcessRecord TOP_APP, boolean doingAll, long now) {
19509         if (app.thread == null) {
19510             return false;
19511         }
19512
19513         computeOomAdjLocked(app, cachedAdj, TOP_APP, doingAll, now);
19514
19515         return applyOomAdjLocked(app, doingAll, now, SystemClock.elapsedRealtime());
19516     }
19517
19518     final void updateProcessForegroundLocked(ProcessRecord proc, boolean isForeground,
19519             boolean oomAdj) {
19520         if (isForeground != proc.foregroundServices) {
19521             proc.foregroundServices = isForeground;
19522             ArrayList<ProcessRecord> curProcs = mForegroundPackages.get(proc.info.packageName,
19523                     proc.info.uid);
19524             if (isForeground) {
19525                 if (curProcs == null) {
19526                     curProcs = new ArrayList<ProcessRecord>();
19527                     mForegroundPackages.put(proc.info.packageName, proc.info.uid, curProcs);
19528                 }
19529                 if (!curProcs.contains(proc)) {
19530                     curProcs.add(proc);
19531                     mBatteryStatsService.noteEvent(BatteryStats.HistoryItem.EVENT_FOREGROUND_START,
19532                             proc.info.packageName, proc.info.uid);
19533                 }
19534             } else {
19535                 if (curProcs != null) {
19536                     if (curProcs.remove(proc)) {
19537                         mBatteryStatsService.noteEvent(
19538                                 BatteryStats.HistoryItem.EVENT_FOREGROUND_FINISH,
19539                                 proc.info.packageName, proc.info.uid);
19540                         if (curProcs.size() <= 0) {
19541                             mForegroundPackages.remove(proc.info.packageName, proc.info.uid);
19542                         }
19543                     }
19544                 }
19545             }
19546             if (oomAdj) {
19547                 updateOomAdjLocked();
19548             }
19549         }
19550     }
19551
19552     private final ActivityRecord resumedAppLocked() {
19553         ActivityRecord act = mStackSupervisor.resumedAppLocked();
19554         String pkg;
19555         int uid;
19556         if (act != null) {
19557             pkg = act.packageName;
19558             uid = act.info.applicationInfo.uid;
19559         } else {
19560             pkg = null;
19561             uid = -1;
19562         }
19563         // Has the UID or resumed package name changed?
19564         if (uid != mCurResumedUid || (pkg != mCurResumedPackage
19565                 && (pkg == null || !pkg.equals(mCurResumedPackage)))) {
19566             if (mCurResumedPackage != null) {
19567                 mBatteryStatsService.noteEvent(BatteryStats.HistoryItem.EVENT_TOP_FINISH,
19568                         mCurResumedPackage, mCurResumedUid);
19569             }
19570             mCurResumedPackage = pkg;
19571             mCurResumedUid = uid;
19572             if (mCurResumedPackage != null) {
19573                 mBatteryStatsService.noteEvent(BatteryStats.HistoryItem.EVENT_TOP_START,
19574                         mCurResumedPackage, mCurResumedUid);
19575             }
19576         }
19577         return act;
19578     }
19579
19580     final boolean updateOomAdjLocked(ProcessRecord app) {
19581         final ActivityRecord TOP_ACT = resumedAppLocked();
19582         final ProcessRecord TOP_APP = TOP_ACT != null ? TOP_ACT.app : null;
19583         final boolean wasCached = app.cached;
19584
19585         mAdjSeq++;
19586
19587         // This is the desired cached adjusment we want to tell it to use.
19588         // If our app is currently cached, we know it, and that is it.  Otherwise,
19589         // we don't know it yet, and it needs to now be cached we will then
19590         // need to do a complete oom adj.
19591         final int cachedAdj = app.curRawAdj >= ProcessList.CACHED_APP_MIN_ADJ
19592                 ? app.curRawAdj : ProcessList.UNKNOWN_ADJ;
19593         boolean success = updateOomAdjLocked(app, cachedAdj, TOP_APP, false,
19594                 SystemClock.uptimeMillis());
19595         if (wasCached != app.cached || app.curRawAdj == ProcessList.UNKNOWN_ADJ) {
19596             // Changed to/from cached state, so apps after it in the LRU
19597             // list may also be changed.
19598             updateOomAdjLocked();
19599         }
19600         return success;
19601     }
19602
19603     final void updateOomAdjLocked() {
19604         final ActivityRecord TOP_ACT = resumedAppLocked();
19605         final ProcessRecord TOP_APP = TOP_ACT != null ? TOP_ACT.app : null;
19606         final long now = SystemClock.uptimeMillis();
19607         final long nowElapsed = SystemClock.elapsedRealtime();
19608         final long oldTime = now - ProcessList.MAX_EMPTY_TIME;
19609         final int N = mLruProcesses.size();
19610
19611         if (false) {
19612             RuntimeException e = new RuntimeException();
19613             e.fillInStackTrace();
19614             Slog.i(TAG, "updateOomAdj: top=" + TOP_ACT, e);
19615         }
19616
19617         // Reset state in all uid records.
19618         for (int i=mActiveUids.size()-1; i>=0; i--) {
19619             final UidRecord uidRec = mActiveUids.valueAt(i);
19620             if (false && DEBUG_UID_OBSERVERS) Slog.i(TAG_UID_OBSERVERS,
19621                     "Starting update of " + uidRec);
19622             uidRec.reset();
19623         }
19624
19625         mStackSupervisor.rankTaskLayersIfNeeded();
19626
19627         mAdjSeq++;
19628         mNewNumServiceProcs = 0;
19629         mNewNumAServiceProcs = 0;
19630
19631         final int emptyProcessLimit;
19632         final int cachedProcessLimit;
19633         if (mProcessLimit <= 0) {
19634             emptyProcessLimit = cachedProcessLimit = 0;
19635         } else if (mProcessLimit == 1) {
19636             emptyProcessLimit = 1;
19637             cachedProcessLimit = 0;
19638         } else {
19639             emptyProcessLimit = ProcessList.computeEmptyProcessLimit(mProcessLimit);
19640             cachedProcessLimit = mProcessLimit - emptyProcessLimit;
19641         }
19642
19643         // Let's determine how many processes we have running vs.
19644         // how many slots we have for background processes; we may want
19645         // to put multiple processes in a slot of there are enough of
19646         // them.
19647         int numSlots = (ProcessList.CACHED_APP_MAX_ADJ
19648                 - ProcessList.CACHED_APP_MIN_ADJ + 1) / 2;
19649         int numEmptyProcs = N - mNumNonCachedProcs - mNumCachedHiddenProcs;
19650         if (numEmptyProcs > cachedProcessLimit) {
19651             // If there are more empty processes than our limit on cached
19652             // processes, then use the cached process limit for the factor.
19653             // This ensures that the really old empty processes get pushed
19654             // down to the bottom, so if we are running low on memory we will
19655             // have a better chance at keeping around more cached processes
19656             // instead of a gazillion empty processes.
19657             numEmptyProcs = cachedProcessLimit;
19658         }
19659         int emptyFactor = numEmptyProcs/numSlots;
19660         if (emptyFactor < 1) emptyFactor = 1;
19661         int cachedFactor = (mNumCachedHiddenProcs > 0 ? mNumCachedHiddenProcs : 1)/numSlots;
19662         if (cachedFactor < 1) cachedFactor = 1;
19663         int stepCached = 0;
19664         int stepEmpty = 0;
19665         int numCached = 0;
19666         int numEmpty = 0;
19667         int numTrimming = 0;
19668
19669         mNumNonCachedProcs = 0;
19670         mNumCachedHiddenProcs = 0;
19671
19672         // First update the OOM adjustment for each of the
19673         // application processes based on their current state.
19674         int curCachedAdj = ProcessList.CACHED_APP_MIN_ADJ;
19675         int nextCachedAdj = curCachedAdj+1;
19676         int curEmptyAdj = ProcessList.CACHED_APP_MIN_ADJ;
19677         int nextEmptyAdj = curEmptyAdj+2;
19678         for (int i=N-1; i>=0; i--) {
19679             ProcessRecord app = mLruProcesses.get(i);
19680             if (!app.killedByAm && app.thread != null) {
19681                 app.procStateChanged = false;
19682                 computeOomAdjLocked(app, ProcessList.UNKNOWN_ADJ, TOP_APP, true, now);
19683
19684                 // If we haven't yet assigned the final cached adj
19685                 // to the process, do that now.
19686                 if (app.curAdj >= ProcessList.UNKNOWN_ADJ) {
19687                     switch (app.curProcState) {
19688                         case ActivityManager.PROCESS_STATE_CACHED_ACTIVITY:
19689                         case ActivityManager.PROCESS_STATE_CACHED_ACTIVITY_CLIENT:
19690                             // This process is a cached process holding activities...
19691                             // assign it the next cached value for that type, and then
19692                             // step that cached level.
19693                             app.curRawAdj = curCachedAdj;
19694                             app.curAdj = app.modifyRawOomAdj(curCachedAdj);
19695                             if (DEBUG_LRU && false) Slog.d(TAG_LRU, "Assigning activity LRU #" + i
19696                                     + " adj: " + app.curAdj + " (curCachedAdj=" + curCachedAdj
19697                                     + ")");
19698                             if (curCachedAdj != nextCachedAdj) {
19699                                 stepCached++;
19700                                 if (stepCached >= cachedFactor) {
19701                                     stepCached = 0;
19702                                     curCachedAdj = nextCachedAdj;
19703                                     nextCachedAdj += 2;
19704                                     if (nextCachedAdj > ProcessList.CACHED_APP_MAX_ADJ) {
19705                                         nextCachedAdj = ProcessList.CACHED_APP_MAX_ADJ;
19706                                     }
19707                                 }
19708                             }
19709                             break;
19710                         default:
19711                             // For everything else, assign next empty cached process
19712                             // level and bump that up.  Note that this means that
19713                             // long-running services that have dropped down to the
19714                             // cached level will be treated as empty (since their process
19715                             // state is still as a service), which is what we want.
19716                             app.curRawAdj = curEmptyAdj;
19717                             app.curAdj = app.modifyRawOomAdj(curEmptyAdj);
19718                             if (DEBUG_LRU && false) Slog.d(TAG_LRU, "Assigning empty LRU #" + i
19719                                     + " adj: " + app.curAdj + " (curEmptyAdj=" + curEmptyAdj
19720                                     + ")");
19721                             if (curEmptyAdj != nextEmptyAdj) {
19722                                 stepEmpty++;
19723                                 if (stepEmpty >= emptyFactor) {
19724                                     stepEmpty = 0;
19725                                     curEmptyAdj = nextEmptyAdj;
19726                                     nextEmptyAdj += 2;
19727                                     if (nextEmptyAdj > ProcessList.CACHED_APP_MAX_ADJ) {
19728                                         nextEmptyAdj = ProcessList.CACHED_APP_MAX_ADJ;
19729                                     }
19730                                 }
19731                             }
19732                             break;
19733                     }
19734                 }
19735
19736                 applyOomAdjLocked(app, true, now, nowElapsed);
19737
19738                 // Count the number of process types.
19739                 switch (app.curProcState) {
19740                     case ActivityManager.PROCESS_STATE_CACHED_ACTIVITY:
19741                     case ActivityManager.PROCESS_STATE_CACHED_ACTIVITY_CLIENT:
19742                         mNumCachedHiddenProcs++;
19743                         numCached++;
19744                         if (numCached > cachedProcessLimit) {
19745                             app.kill("cached #" + numCached, true);
19746                         }
19747                         break;
19748                     case ActivityManager.PROCESS_STATE_CACHED_EMPTY:
19749                         if (numEmpty > ProcessList.TRIM_EMPTY_APPS
19750                                 && app.lastActivityTime < oldTime) {
19751                             app.kill("empty for "
19752                                     + ((oldTime + ProcessList.MAX_EMPTY_TIME - app.lastActivityTime)
19753                                     / 1000) + "s", true);
19754                         } else {
19755                             numEmpty++;
19756                             if (numEmpty > emptyProcessLimit) {
19757                                 app.kill("empty #" + numEmpty, true);
19758                             }
19759                         }
19760                         break;
19761                     default:
19762                         mNumNonCachedProcs++;
19763                         break;
19764                 }
19765
19766                 if (app.isolated && app.services.size() <= 0) {
19767                     // If this is an isolated process, and there are no
19768                     // services running in it, then the process is no longer
19769                     // needed.  We agressively kill these because we can by
19770                     // definition not re-use the same process again, and it is
19771                     // good to avoid having whatever code was running in them
19772                     // left sitting around after no longer needed.
19773                     app.kill("isolated not needed", true);
19774                 } else {
19775                     // Keeping this process, update its uid.
19776                     final UidRecord uidRec = app.uidRecord;
19777                     if (uidRec != null && uidRec.curProcState > app.curProcState) {
19778                         uidRec.curProcState = app.curProcState;
19779                     }
19780                 }
19781
19782                 if (app.curProcState >= ActivityManager.PROCESS_STATE_HOME
19783                         && !app.killedByAm) {
19784                     numTrimming++;
19785                 }
19786             }
19787         }
19788
19789         mNumServiceProcs = mNewNumServiceProcs;
19790
19791         // Now determine the memory trimming level of background processes.
19792         // Unfortunately we need to start at the back of the list to do this
19793         // properly.  We only do this if the number of background apps we
19794         // are managing to keep around is less than half the maximum we desire;
19795         // if we are keeping a good number around, we'll let them use whatever
19796         // memory they want.
19797         final int numCachedAndEmpty = numCached + numEmpty;
19798         int memFactor;
19799         if (numCached <= ProcessList.TRIM_CACHED_APPS
19800                 && numEmpty <= ProcessList.TRIM_EMPTY_APPS) {
19801             if (numCachedAndEmpty <= ProcessList.TRIM_CRITICAL_THRESHOLD) {
19802                 memFactor = ProcessStats.ADJ_MEM_FACTOR_CRITICAL;
19803             } else if (numCachedAndEmpty <= ProcessList.TRIM_LOW_THRESHOLD) {
19804                 memFactor = ProcessStats.ADJ_MEM_FACTOR_LOW;
19805             } else {
19806                 memFactor = ProcessStats.ADJ_MEM_FACTOR_MODERATE;
19807             }
19808         } else {
19809             memFactor = ProcessStats.ADJ_MEM_FACTOR_NORMAL;
19810         }
19811         // We always allow the memory level to go up (better).  We only allow it to go
19812         // down if we are in a state where that is allowed, *and* the total number of processes
19813         // has gone down since last time.
19814         if (DEBUG_OOM_ADJ) Slog.d(TAG_OOM_ADJ, "oom: memFactor=" + memFactor
19815                 + " last=" + mLastMemoryLevel + " allowLow=" + mAllowLowerMemLevel
19816                 + " numProcs=" + mLruProcesses.size() + " last=" + mLastNumProcesses);
19817         if (memFactor > mLastMemoryLevel) {
19818             if (!mAllowLowerMemLevel || mLruProcesses.size() >= mLastNumProcesses) {
19819                 memFactor = mLastMemoryLevel;
19820                 if (DEBUG_OOM_ADJ) Slog.d(TAG_OOM_ADJ, "Keeping last mem factor!");
19821             }
19822         }
19823         mLastMemoryLevel = memFactor;
19824         mLastNumProcesses = mLruProcesses.size();
19825         boolean allChanged = mProcessStats.setMemFactorLocked(memFactor, !isSleeping(), now);
19826         final int trackerMemFactor = mProcessStats.getMemFactorLocked();
19827         if (memFactor != ProcessStats.ADJ_MEM_FACTOR_NORMAL) {
19828             if (mLowRamStartTime == 0) {
19829                 mLowRamStartTime = now;
19830             }
19831             int step = 0;
19832             int fgTrimLevel;
19833             switch (memFactor) {
19834                 case ProcessStats.ADJ_MEM_FACTOR_CRITICAL:
19835                     fgTrimLevel = ComponentCallbacks2.TRIM_MEMORY_RUNNING_CRITICAL;
19836                     break;
19837                 case ProcessStats.ADJ_MEM_FACTOR_LOW:
19838                     fgTrimLevel = ComponentCallbacks2.TRIM_MEMORY_RUNNING_LOW;
19839                     break;
19840                 default:
19841                     fgTrimLevel = ComponentCallbacks2.TRIM_MEMORY_RUNNING_MODERATE;
19842                     break;
19843             }
19844             int factor = numTrimming/3;
19845             int minFactor = 2;
19846             if (mHomeProcess != null) minFactor++;
19847             if (mPreviousProcess != null) minFactor++;
19848             if (factor < minFactor) factor = minFactor;
19849             int curLevel = ComponentCallbacks2.TRIM_MEMORY_COMPLETE;
19850             for (int i=N-1; i>=0; i--) {
19851                 ProcessRecord app = mLruProcesses.get(i);
19852                 if (allChanged || app.procStateChanged) {
19853                     setProcessTrackerStateLocked(app, trackerMemFactor, now);
19854                     app.procStateChanged = false;
19855                 }
19856                 if (app.curProcState >= ActivityManager.PROCESS_STATE_HOME
19857                         && !app.killedByAm) {
19858                     if (app.trimMemoryLevel < curLevel && app.thread != null) {
19859                         try {
19860                             if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG_OOM_ADJ,
19861                                     "Trimming memory of " + app.processName + " to " + curLevel);
19862                             app.thread.scheduleTrimMemory(curLevel);
19863                         } catch (RemoteException e) {
19864                         }
19865                         if (false) {
19866                             // For now we won't do this; our memory trimming seems
19867                             // to be good enough at this point that destroying
19868                             // activities causes more harm than good.
19869                             if (curLevel >= ComponentCallbacks2.TRIM_MEMORY_COMPLETE
19870                                     && app != mHomeProcess && app != mPreviousProcess) {
19871                                 // Need to do this on its own message because the stack may not
19872                                 // be in a consistent state at this point.
19873                                 // For these apps we will also finish their activities
19874                                 // to help them free memory.
19875                                 mStackSupervisor.scheduleDestroyAllActivities(app, "trim");
19876                             }
19877                         }
19878                     }
19879                     app.trimMemoryLevel = curLevel;
19880                     step++;
19881                     if (step >= factor) {
19882                         step = 0;
19883                         switch (curLevel) {
19884                             case ComponentCallbacks2.TRIM_MEMORY_COMPLETE:
19885                                 curLevel = ComponentCallbacks2.TRIM_MEMORY_MODERATE;
19886                                 break;
19887                             case ComponentCallbacks2.TRIM_MEMORY_MODERATE:
19888                                 curLevel = ComponentCallbacks2.TRIM_MEMORY_BACKGROUND;
19889                                 break;
19890                         }
19891                     }
19892                 } else if (app.curProcState == ActivityManager.PROCESS_STATE_HEAVY_WEIGHT) {
19893                     if (app.trimMemoryLevel < ComponentCallbacks2.TRIM_MEMORY_BACKGROUND
19894                             && app.thread != null) {
19895                         try {
19896                             if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG_OOM_ADJ,
19897                                     "Trimming memory of heavy-weight " + app.processName
19898                                     + " to " + ComponentCallbacks2.TRIM_MEMORY_BACKGROUND);
19899                             app.thread.scheduleTrimMemory(
19900                                     ComponentCallbacks2.TRIM_MEMORY_BACKGROUND);
19901                         } catch (RemoteException e) {
19902                         }
19903                     }
19904                     app.trimMemoryLevel = ComponentCallbacks2.TRIM_MEMORY_BACKGROUND;
19905                 } else {
19906                     if ((app.curProcState >= ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND
19907                             || app.systemNoUi) && app.pendingUiClean) {
19908                         // If this application is now in the background and it
19909                         // had done UI, then give it the special trim level to
19910                         // have it free UI resources.
19911                         final int level = ComponentCallbacks2.TRIM_MEMORY_UI_HIDDEN;
19912                         if (app.trimMemoryLevel < level && app.thread != null) {
19913                             try {
19914                                 if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG_OOM_ADJ,
19915                                         "Trimming memory of bg-ui " + app.processName
19916                                         + " to " + level);
19917                                 app.thread.scheduleTrimMemory(level);
19918                             } catch (RemoteException e) {
19919                             }
19920                         }
19921                         app.pendingUiClean = false;
19922                     }
19923                     if (app.trimMemoryLevel < fgTrimLevel && app.thread != null) {
19924                         try {
19925                             if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG_OOM_ADJ,
19926                                     "Trimming memory of fg " + app.processName
19927                                     + " to " + fgTrimLevel);
19928                             app.thread.scheduleTrimMemory(fgTrimLevel);
19929                         } catch (RemoteException e) {
19930                         }
19931                     }
19932                     app.trimMemoryLevel = fgTrimLevel;
19933                 }
19934             }
19935         } else {
19936             if (mLowRamStartTime != 0) {
19937                 mLowRamTimeSinceLastIdle += now - mLowRamStartTime;
19938                 mLowRamStartTime = 0;
19939             }
19940             for (int i=N-1; i>=0; i--) {
19941                 ProcessRecord app = mLruProcesses.get(i);
19942                 if (allChanged || app.procStateChanged) {
19943                     setProcessTrackerStateLocked(app, trackerMemFactor, now);
19944                     app.procStateChanged = false;
19945                 }
19946                 if ((app.curProcState >= ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND
19947                         || app.systemNoUi) && app.pendingUiClean) {
19948                     if (app.trimMemoryLevel < ComponentCallbacks2.TRIM_MEMORY_UI_HIDDEN
19949                             && app.thread != null) {
19950                         try {
19951                             if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG_OOM_ADJ,
19952                                     "Trimming memory of ui hidden " + app.processName
19953                                     + " to " + ComponentCallbacks2.TRIM_MEMORY_UI_HIDDEN);
19954                             app.thread.scheduleTrimMemory(
19955                                     ComponentCallbacks2.TRIM_MEMORY_UI_HIDDEN);
19956                         } catch (RemoteException e) {
19957                         }
19958                     }
19959                     app.pendingUiClean = false;
19960                 }
19961                 app.trimMemoryLevel = 0;
19962             }
19963         }
19964
19965         if (mAlwaysFinishActivities) {
19966             // Need to do this on its own message because the stack may not
19967             // be in a consistent state at this point.
19968             mStackSupervisor.scheduleDestroyAllActivities(null, "always-finish");
19969         }
19970
19971         if (allChanged) {
19972             requestPssAllProcsLocked(now, false, mProcessStats.isMemFactorLowered());
19973         }
19974
19975         // Update from any uid changes.
19976         for (int i=mActiveUids.size()-1; i>=0; i--) {
19977             final UidRecord uidRec = mActiveUids.valueAt(i);
19978             int uidChange = UidRecord.CHANGE_PROCSTATE;
19979             if (uidRec.setProcState != uidRec.curProcState) {
19980                 if (DEBUG_UID_OBSERVERS) Slog.i(TAG_UID_OBSERVERS,
19981                         "Changes in " + uidRec + ": proc state from " + uidRec.setProcState
19982                         + " to " + uidRec.curProcState);
19983                 if (ActivityManager.isProcStateBackground(uidRec.curProcState)) {
19984                     if (!ActivityManager.isProcStateBackground(uidRec.setProcState)) {
19985                         uidRec.lastBackgroundTime = nowElapsed;
19986                         if (!mHandler.hasMessages(IDLE_UIDS_MSG)) {
19987                             // Note: the background settle time is in elapsed realtime, while
19988                             // the handler time base is uptime.  All this means is that we may
19989                             // stop background uids later than we had intended, but that only
19990                             // happens because the device was sleeping so we are okay anyway.
19991                             mHandler.sendEmptyMessageDelayed(IDLE_UIDS_MSG, BACKGROUND_SETTLE_TIME);
19992                         }
19993                     }
19994                 } else {
19995                     if (uidRec.idle) {
19996                         uidChange = UidRecord.CHANGE_ACTIVE;
19997                         uidRec.idle = false;
19998                     }
19999                     uidRec.lastBackgroundTime = 0;
20000                 }
20001                 uidRec.setProcState = uidRec.curProcState;
20002                 enqueueUidChangeLocked(uidRec, -1, uidChange);
20003             }
20004         }
20005
20006         if (mProcessStats.shouldWriteNowLocked(now)) {
20007             mHandler.post(new Runnable() {
20008                 @Override public void run() {
20009                     synchronized (ActivityManagerService.this) {
20010                         mProcessStats.writeStateAsyncLocked();
20011                     }
20012                 }
20013             });
20014         }
20015
20016         if (DEBUG_OOM_ADJ) {
20017             final long duration = SystemClock.uptimeMillis() - now;
20018             if (false) {
20019                 Slog.d(TAG_OOM_ADJ, "Did OOM ADJ in " + duration + "ms",
20020                         new RuntimeException("here").fillInStackTrace());
20021             } else {
20022                 Slog.d(TAG_OOM_ADJ, "Did OOM ADJ in " + duration + "ms");
20023             }
20024         }
20025     }
20026
20027     final void idleUids() {
20028         synchronized (this) {
20029             final long nowElapsed = SystemClock.elapsedRealtime();
20030             final long maxBgTime = nowElapsed - BACKGROUND_SETTLE_TIME;
20031             long nextTime = 0;
20032             for (int i=mActiveUids.size()-1; i>=0; i--) {
20033                 final UidRecord uidRec = mActiveUids.valueAt(i);
20034                 final long bgTime = uidRec.lastBackgroundTime;
20035                 if (bgTime > 0 && !uidRec.idle) {
20036                     if (bgTime <= maxBgTime) {
20037                         uidRec.idle = true;
20038                         doStopUidLocked(uidRec.uid, uidRec);
20039                     } else {
20040                         if (nextTime == 0 || nextTime > bgTime) {
20041                             nextTime = bgTime;
20042                         }
20043                     }
20044                 }
20045             }
20046             if (nextTime > 0) {
20047                 mHandler.removeMessages(IDLE_UIDS_MSG);
20048                 mHandler.sendEmptyMessageDelayed(IDLE_UIDS_MSG,
20049                         nextTime + BACKGROUND_SETTLE_TIME - nowElapsed);
20050             }
20051         }
20052     }
20053
20054     final void runInBackgroundDisabled(int uid) {
20055         synchronized (this) {
20056             UidRecord uidRec = mActiveUids.get(uid);
20057             if (uidRec != null) {
20058                 // This uid is actually running...  should it be considered background now?
20059                 if (uidRec.idle) {
20060                     doStopUidLocked(uidRec.uid, uidRec);
20061                 }
20062             } else {
20063                 // This uid isn't actually running...  still send a report about it being "stopped".
20064                 doStopUidLocked(uid, null);
20065             }
20066         }
20067     }
20068
20069     final void doStopUidLocked(int uid, final UidRecord uidRec) {
20070         mServices.stopInBackgroundLocked(uid);
20071         enqueueUidChangeLocked(uidRec, uid, UidRecord.CHANGE_IDLE);
20072     }
20073
20074     final void trimApplications() {
20075         synchronized (this) {
20076             int i;
20077
20078             // First remove any unused application processes whose package
20079             // has been removed.
20080             for (i=mRemovedProcesses.size()-1; i>=0; i--) {
20081                 final ProcessRecord app = mRemovedProcesses.get(i);
20082                 if (app.activities.size() == 0
20083                         && app.curReceiver == null && app.services.size() == 0) {
20084                     Slog.i(
20085                         TAG, "Exiting empty application process "
20086                         + app.processName + " ("
20087                         + (app.thread != null ? app.thread.asBinder() : null)
20088                         + ")\n");
20089                     if (app.pid > 0 && app.pid != MY_PID) {
20090                         app.kill("empty", false);
20091                     } else {
20092                         try {
20093                             app.thread.scheduleExit();
20094                         } catch (Exception e) {
20095                             // Ignore exceptions.
20096                         }
20097                     }
20098                     cleanUpApplicationRecordLocked(app, false, true, -1);
20099                     mRemovedProcesses.remove(i);
20100
20101                     if (app.persistent) {
20102                         addAppLocked(app.info, false, null /* ABI override */);
20103                     }
20104                 }
20105             }
20106
20107             // Now update the oom adj for all processes.
20108             updateOomAdjLocked();
20109         }
20110     }
20111
20112     /** This method sends the specified signal to each of the persistent apps */
20113     public void signalPersistentProcesses(int sig) throws RemoteException {
20114         if (sig != Process.SIGNAL_USR1) {
20115             throw new SecurityException("Only SIGNAL_USR1 is allowed");
20116         }
20117
20118         synchronized (this) {
20119             if (checkCallingPermission(android.Manifest.permission.SIGNAL_PERSISTENT_PROCESSES)
20120                     != PackageManager.PERMISSION_GRANTED) {
20121                 throw new SecurityException("Requires permission "
20122                         + android.Manifest.permission.SIGNAL_PERSISTENT_PROCESSES);
20123             }
20124
20125             for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) {
20126                 ProcessRecord r = mLruProcesses.get(i);
20127                 if (r.thread != null && r.persistent) {
20128                     Process.sendSignal(r.pid, sig);
20129                 }
20130             }
20131         }
20132     }
20133
20134     private void stopProfilerLocked(ProcessRecord proc, int profileType) {
20135         if (proc == null || proc == mProfileProc) {
20136             proc = mProfileProc;
20137             profileType = mProfileType;
20138             clearProfilerLocked();
20139         }
20140         if (proc == null) {
20141             return;
20142         }
20143         try {
20144             proc.thread.profilerControl(false, null, profileType);
20145         } catch (RemoteException e) {
20146             throw new IllegalStateException("Process disappeared");
20147         }
20148     }
20149
20150     private void clearProfilerLocked() {
20151         if (mProfileFd != null) {
20152             try {
20153                 mProfileFd.close();
20154             } catch (IOException e) {
20155             }
20156         }
20157         mProfileApp = null;
20158         mProfileProc = null;
20159         mProfileFile = null;
20160         mProfileType = 0;
20161         mAutoStopProfiler = false;
20162         mSamplingInterval = 0;
20163     }
20164
20165     public boolean profileControl(String process, int userId, boolean start,
20166             ProfilerInfo profilerInfo, int profileType) throws RemoteException {
20167
20168         try {
20169             synchronized (this) {
20170                 // note: hijacking SET_ACTIVITY_WATCHER, but should be changed to
20171                 // its own permission.
20172                 if (checkCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER)
20173                         != PackageManager.PERMISSION_GRANTED) {
20174                     throw new SecurityException("Requires permission "
20175                             + android.Manifest.permission.SET_ACTIVITY_WATCHER);
20176                 }
20177
20178                 if (start && (profilerInfo == null || profilerInfo.profileFd == null)) {
20179                     throw new IllegalArgumentException("null profile info or fd");
20180                 }
20181
20182                 ProcessRecord proc = null;
20183                 if (process != null) {
20184                     proc = findProcessLocked(process, userId, "profileControl");
20185                 }
20186
20187                 if (start && (proc == null || proc.thread == null)) {
20188                     throw new IllegalArgumentException("Unknown process: " + process);
20189                 }
20190
20191                 if (start) {
20192                     stopProfilerLocked(null, 0);
20193                     setProfileApp(proc.info, proc.processName, profilerInfo);
20194                     mProfileProc = proc;
20195                     mProfileType = profileType;
20196                     ParcelFileDescriptor fd = profilerInfo.profileFd;
20197                     try {
20198                         fd = fd.dup();
20199                     } catch (IOException e) {
20200                         fd = null;
20201                     }
20202                     profilerInfo.profileFd = fd;
20203                     proc.thread.profilerControl(start, profilerInfo, profileType);
20204                     fd = null;
20205                     mProfileFd = null;
20206                 } else {
20207                     stopProfilerLocked(proc, profileType);
20208                     if (profilerInfo != null && profilerInfo.profileFd != null) {
20209                         try {
20210                             profilerInfo.profileFd.close();
20211                         } catch (IOException e) {
20212                         }
20213                     }
20214                 }
20215
20216                 return true;
20217             }
20218         } catch (RemoteException e) {
20219             throw new IllegalStateException("Process disappeared");
20220         } finally {
20221             if (profilerInfo != null && profilerInfo.profileFd != null) {
20222                 try {
20223                     profilerInfo.profileFd.close();
20224                 } catch (IOException e) {
20225                 }
20226             }
20227         }
20228     }
20229
20230     private ProcessRecord findProcessLocked(String process, int userId, String callName) {
20231         userId = mUserController.handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(),
20232                 userId, true, ALLOW_FULL_ONLY, callName, null);
20233         ProcessRecord proc = null;
20234         try {
20235             int pid = Integer.parseInt(process);
20236             synchronized (mPidsSelfLocked) {
20237                 proc = mPidsSelfLocked.get(pid);
20238             }
20239         } catch (NumberFormatException e) {
20240         }
20241
20242         if (proc == null) {
20243             ArrayMap<String, SparseArray<ProcessRecord>> all
20244                     = mProcessNames.getMap();
20245             SparseArray<ProcessRecord> procs = all.get(process);
20246             if (procs != null && procs.size() > 0) {
20247                 proc = procs.valueAt(0);
20248                 if (userId != UserHandle.USER_ALL && proc.userId != userId) {
20249                     for (int i=1; i<procs.size(); i++) {
20250                         ProcessRecord thisProc = procs.valueAt(i);
20251                         if (thisProc.userId == userId) {
20252                             proc = thisProc;
20253                             break;
20254                         }
20255                     }
20256                 }
20257             }
20258         }
20259
20260         return proc;
20261     }
20262
20263     public boolean dumpHeap(String process, int userId, boolean managed,
20264             String path, ParcelFileDescriptor fd) throws RemoteException {
20265
20266         try {
20267             synchronized (this) {
20268                 // note: hijacking SET_ACTIVITY_WATCHER, but should be changed to
20269                 // its own permission (same as profileControl).
20270                 if (checkCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER)
20271                         != PackageManager.PERMISSION_GRANTED) {
20272                     throw new SecurityException("Requires permission "
20273                             + android.Manifest.permission.SET_ACTIVITY_WATCHER);
20274                 }
20275
20276                 if (fd == null) {
20277                     throw new IllegalArgumentException("null fd");
20278                 }
20279
20280                 ProcessRecord proc = findProcessLocked(process, userId, "dumpHeap");
20281                 if (proc == null || proc.thread == null) {
20282                     throw new IllegalArgumentException("Unknown process: " + process);
20283                 }
20284
20285                 boolean isDebuggable = "1".equals(SystemProperties.get(SYSTEM_DEBUGGABLE, "0"));
20286                 if (!isDebuggable) {
20287                     if ((proc.info.flags&ApplicationInfo.FLAG_DEBUGGABLE) == 0) {
20288                         throw new SecurityException("Process not debuggable: " + proc);
20289                     }
20290                 }
20291
20292                 proc.thread.dumpHeap(managed, path, fd);
20293                 fd = null;
20294                 return true;
20295             }
20296         } catch (RemoteException e) {
20297             throw new IllegalStateException("Process disappeared");
20298         } finally {
20299             if (fd != null) {
20300                 try {
20301                     fd.close();
20302                 } catch (IOException e) {
20303                 }
20304             }
20305         }
20306     }
20307
20308     @Override
20309     public void setDumpHeapDebugLimit(String processName, int uid, long maxMemSize,
20310             String reportPackage) {
20311         if (processName != null) {
20312             enforceCallingPermission(android.Manifest.permission.SET_DEBUG_APP,
20313                     "setDumpHeapDebugLimit()");
20314         } else {
20315             synchronized (mPidsSelfLocked) {
20316                 ProcessRecord proc = mPidsSelfLocked.get(Binder.getCallingPid());
20317                 if (proc == null) {
20318                     throw new SecurityException("No process found for calling pid "
20319                             + Binder.getCallingPid());
20320                 }
20321                 if (!Build.IS_DEBUGGABLE
20322                         && (proc.info.flags&ApplicationInfo.FLAG_DEBUGGABLE) == 0) {
20323                     throw new SecurityException("Not running a debuggable build");
20324                 }
20325                 processName = proc.processName;
20326                 uid = proc.uid;
20327                 if (reportPackage != null && !proc.pkgList.containsKey(reportPackage)) {
20328                     throw new SecurityException("Package " + reportPackage + " is not running in "
20329                             + proc);
20330                 }
20331             }
20332         }
20333         synchronized (this) {
20334             if (maxMemSize > 0) {
20335                 mMemWatchProcesses.put(processName, uid, new Pair(maxMemSize, reportPackage));
20336             } else {
20337                 if (uid != 0) {
20338                     mMemWatchProcesses.remove(processName, uid);
20339                 } else {
20340                     mMemWatchProcesses.getMap().remove(processName);
20341                 }
20342             }
20343         }
20344     }
20345
20346     @Override
20347     public void dumpHeapFinished(String path) {
20348         synchronized (this) {
20349             if (Binder.getCallingPid() != mMemWatchDumpPid) {
20350                 Slog.w(TAG, "dumpHeapFinished: Calling pid " + Binder.getCallingPid()
20351                         + " does not match last pid " + mMemWatchDumpPid);
20352                 return;
20353             }
20354             if (mMemWatchDumpFile == null || !mMemWatchDumpFile.equals(path)) {
20355                 Slog.w(TAG, "dumpHeapFinished: Calling path " + path
20356                         + " does not match last path " + mMemWatchDumpFile);
20357                 return;
20358             }
20359             if (DEBUG_PSS) Slog.d(TAG_PSS, "Dump heap finished for " + path);
20360             mHandler.sendEmptyMessage(POST_DUMP_HEAP_NOTIFICATION_MSG);
20361         }
20362     }
20363
20364     /** In this method we try to acquire our lock to make sure that we have not deadlocked */
20365     public void monitor() {
20366         synchronized (this) { }
20367     }
20368
20369     void onCoreSettingsChange(Bundle settings) {
20370         for (int i = mLruProcesses.size() - 1; i >= 0; i--) {
20371             ProcessRecord processRecord = mLruProcesses.get(i);
20372             try {
20373                 if (processRecord.thread != null) {
20374                     processRecord.thread.setCoreSettings(settings);
20375                 }
20376             } catch (RemoteException re) {
20377                 /* ignore */
20378             }
20379         }
20380     }
20381
20382     // Multi-user methods
20383
20384     /**
20385      * Start user, if its not already running, but don't bring it to foreground.
20386      */
20387     @Override
20388     public boolean startUserInBackground(final int userId) {
20389         return mUserController.startUser(userId, /* foreground */ false);
20390     }
20391
20392     @Override
20393     public boolean unlockUser(int userId, byte[] token) {
20394         return mUserController.unlockUser(userId, token);
20395     }
20396
20397     @Override
20398     public boolean switchUser(final int targetUserId) {
20399         enforceShellRestriction(UserManager.DISALLOW_DEBUGGING_FEATURES, targetUserId);
20400         UserInfo currentUserInfo;
20401         UserInfo targetUserInfo;
20402         synchronized (this) {
20403             int currentUserId = mUserController.getCurrentUserIdLocked();
20404             currentUserInfo = mUserController.getUserInfo(currentUserId);
20405             targetUserInfo = mUserController.getUserInfo(targetUserId);
20406             if (targetUserInfo == null) {
20407                 Slog.w(TAG, "No user info for user #" + targetUserId);
20408                 return false;
20409             }
20410             if (targetUserInfo.isManagedProfile()) {
20411                 Slog.w(TAG, "Cannot switch to User #" + targetUserId + ": not a full user");
20412                 return false;
20413             }
20414             mUserController.setTargetUserIdLocked(targetUserId);
20415         }
20416         Pair<UserInfo, UserInfo> userNames = new Pair<>(currentUserInfo, targetUserInfo);
20417         mUiHandler.removeMessages(START_USER_SWITCH_UI_MSG);
20418         mUiHandler.sendMessage(mUiHandler.obtainMessage(START_USER_SWITCH_UI_MSG, userNames));
20419         return true;
20420     }
20421
20422     void scheduleStartProfilesLocked() {
20423         if (!mHandler.hasMessages(START_PROFILES_MSG)) {
20424             mHandler.sendMessageDelayed(mHandler.obtainMessage(START_PROFILES_MSG),
20425                     DateUtils.SECOND_IN_MILLIS);
20426         }
20427     }
20428
20429     @Override
20430     public int stopUser(final int userId, boolean force, final IStopUserCallback callback) {
20431         return mUserController.stopUser(userId, force, callback);
20432     }
20433
20434     void onUserRemovedLocked(int userId) {
20435         mRecentTasks.removeTasksForUserLocked(userId);
20436     }
20437
20438     @Override
20439     public UserInfo getCurrentUser() {
20440         return mUserController.getCurrentUser();
20441     }
20442
20443     @Override
20444     public boolean isUserRunning(int userId, int flags) {
20445         if (checkCallingPermission(INTERACT_ACROSS_USERS)
20446                 != PackageManager.PERMISSION_GRANTED) {
20447             String msg = "Permission Denial: isUserRunning() from pid="
20448                     + Binder.getCallingPid()
20449                     + ", uid=" + Binder.getCallingUid()
20450                     + " requires " + INTERACT_ACROSS_USERS;
20451             Slog.w(TAG, msg);
20452             throw new SecurityException(msg);
20453         }
20454         synchronized (this) {
20455             return mUserController.isUserRunningLocked(userId, flags);
20456         }
20457     }
20458
20459     @Override
20460     public int[] getRunningUserIds() {
20461         if (checkCallingPermission(INTERACT_ACROSS_USERS)
20462                 != PackageManager.PERMISSION_GRANTED) {
20463             String msg = "Permission Denial: isUserRunning() from pid="
20464                     + Binder.getCallingPid()
20465                     + ", uid=" + Binder.getCallingUid()
20466                     + " requires " + INTERACT_ACROSS_USERS;
20467             Slog.w(TAG, msg);
20468             throw new SecurityException(msg);
20469         }
20470         synchronized (this) {
20471             return mUserController.getStartedUserArrayLocked();
20472         }
20473     }
20474
20475     @Override
20476     public void registerUserSwitchObserver(IUserSwitchObserver observer) {
20477         mUserController.registerUserSwitchObserver(observer);
20478     }
20479
20480     @Override
20481     public void unregisterUserSwitchObserver(IUserSwitchObserver observer) {
20482         mUserController.unregisterUserSwitchObserver(observer);
20483     }
20484
20485     ApplicationInfo getAppInfoForUser(ApplicationInfo info, int userId) {
20486         if (info == null) return null;
20487         ApplicationInfo newInfo = new ApplicationInfo(info);
20488         newInfo.initForUser(userId);
20489         return newInfo;
20490     }
20491
20492     ActivityInfo getActivityInfoForUser(ActivityInfo aInfo, int userId) {
20493         if (aInfo == null
20494                 || (userId < 1 && aInfo.applicationInfo.uid < UserHandle.PER_USER_RANGE)) {
20495             return aInfo;
20496         }
20497
20498         ActivityInfo info = new ActivityInfo(aInfo);
20499         info.applicationInfo = getAppInfoForUser(info.applicationInfo, userId);
20500         return info;
20501     }
20502
20503     private boolean processSanityChecksLocked(ProcessRecord process) {
20504         if (process == null || process.thread == null) {
20505             return false;
20506         }
20507
20508         boolean isDebuggable = "1".equals(SystemProperties.get(SYSTEM_DEBUGGABLE, "0"));
20509         if (!isDebuggable) {
20510             if ((process.info.flags&ApplicationInfo.FLAG_DEBUGGABLE) == 0) {
20511                 return false;
20512             }
20513         }
20514
20515         return true;
20516     }
20517
20518     public boolean startBinderTracking() throws RemoteException {
20519         synchronized (this) {
20520             mBinderTransactionTrackingEnabled = true;
20521             // TODO: hijacking SET_ACTIVITY_WATCHER, but should be changed to its own
20522             // permission (same as profileControl).
20523             if (checkCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER)
20524                     != PackageManager.PERMISSION_GRANTED) {
20525                 throw new SecurityException("Requires permission "
20526                         + android.Manifest.permission.SET_ACTIVITY_WATCHER);
20527             }
20528
20529             for (int i = 0; i < mLruProcesses.size(); i++) {
20530                 ProcessRecord process = mLruProcesses.get(i);
20531                 if (!processSanityChecksLocked(process)) {
20532                     continue;
20533                 }
20534                 try {
20535                     process.thread.startBinderTracking();
20536                 } catch (RemoteException e) {
20537                     Log.v(TAG, "Process disappared");
20538                 }
20539             }
20540             return true;
20541         }
20542     }
20543
20544     public boolean stopBinderTrackingAndDump(ParcelFileDescriptor fd) throws RemoteException {
20545         try {
20546             synchronized (this) {
20547                 mBinderTransactionTrackingEnabled = false;
20548                 // TODO: hijacking SET_ACTIVITY_WATCHER, but should be changed to its own
20549                 // permission (same as profileControl).
20550                 if (checkCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER)
20551                         != PackageManager.PERMISSION_GRANTED) {
20552                     throw new SecurityException("Requires permission "
20553                             + android.Manifest.permission.SET_ACTIVITY_WATCHER);
20554                 }
20555
20556                 if (fd == null) {
20557                     throw new IllegalArgumentException("null fd");
20558                 }
20559
20560                 PrintWriter pw = new FastPrintWriter(new FileOutputStream(fd.getFileDescriptor()));
20561                 pw.println("Binder transaction traces for all processes.\n");
20562                 for (ProcessRecord process : mLruProcesses) {
20563                     if (!processSanityChecksLocked(process)) {
20564                         continue;
20565                     }
20566
20567                     pw.println("Traces for process: " + process.processName);
20568                     pw.flush();
20569                     try {
20570                         TransferPipe tp = new TransferPipe();
20571                         try {
20572                             process.thread.stopBinderTrackingAndDump(
20573                                     tp.getWriteFd().getFileDescriptor());
20574                             tp.go(fd.getFileDescriptor());
20575                         } finally {
20576                             tp.kill();
20577                         }
20578                     } catch (IOException e) {
20579                         pw.println("Failure while dumping IPC traces from " + process +
20580                                 ".  Exception: " + e);
20581                         pw.flush();
20582                     } catch (RemoteException e) {
20583                         pw.println("Got a RemoteException while dumping IPC traces from " +
20584                                 process + ".  Exception: " + e);
20585                         pw.flush();
20586                     }
20587                 }
20588                 fd = null;
20589                 return true;
20590             }
20591         } finally {
20592             if (fd != null) {
20593                 try {
20594                     fd.close();
20595                 } catch (IOException e) {
20596                 }
20597             }
20598         }
20599     }
20600
20601     void stopReportingCrashesLocked(ProcessRecord proc) {
20602         if (mAppsNotReportingCrashes == null) {
20603             mAppsNotReportingCrashes = new ArraySet<>();
20604         }
20605         mAppsNotReportingCrashes.add(proc.info.packageName);
20606     }
20607
20608     private final class LocalService extends ActivityManagerInternal {
20609         @Override
20610         public void onWakefulnessChanged(int wakefulness) {
20611             ActivityManagerService.this.onWakefulnessChanged(wakefulness);
20612         }
20613
20614         @Override
20615         public int startIsolatedProcess(String entryPoint, String[] entryPointArgs,
20616                 String processName, String abiOverride, int uid, Runnable crashHandler) {
20617             return ActivityManagerService.this.startIsolatedProcess(entryPoint, entryPointArgs,
20618                     processName, abiOverride, uid, crashHandler);
20619         }
20620
20621         @Override
20622         public SleepToken acquireSleepToken(String tag) {
20623             Preconditions.checkNotNull(tag);
20624
20625             synchronized (ActivityManagerService.this) {
20626                 SleepTokenImpl token = new SleepTokenImpl(tag);
20627                 mSleepTokens.add(token);
20628                 updateSleepIfNeededLocked();
20629                 return token;
20630             }
20631         }
20632
20633         @Override
20634         public ComponentName getHomeActivityForUser(int userId) {
20635             synchronized (ActivityManagerService.this) {
20636                 ActivityRecord homeActivity = mStackSupervisor.getHomeActivityForUser(userId);
20637                 return homeActivity == null ? null : homeActivity.realActivity;
20638             }
20639         }
20640
20641         @Override
20642         public void onUserRemoved(int userId) {
20643             synchronized (ActivityManagerService.this) {
20644                 ActivityManagerService.this.onUserRemovedLocked(userId);
20645             }
20646         }
20647     }
20648
20649     private final class SleepTokenImpl extends SleepToken {
20650         private final String mTag;
20651         private final long mAcquireTime;
20652
20653         public SleepTokenImpl(String tag) {
20654             mTag = tag;
20655             mAcquireTime = SystemClock.uptimeMillis();
20656         }
20657
20658         @Override
20659         public void release() {
20660             synchronized (ActivityManagerService.this) {
20661                 if (mSleepTokens.remove(this)) {
20662                     updateSleepIfNeededLocked();
20663                 }
20664             }
20665         }
20666
20667         @Override
20668         public String toString() {
20669             return "{\"" + mTag + "\", acquire at " + TimeUtils.formatUptime(mAcquireTime) + "}";
20670         }
20671     }
20672
20673     /**
20674      * An implementation of IAppTask, that allows an app to manage its own tasks via
20675      * {@link android.app.ActivityManager.AppTask}.  We keep track of the callingUid to ensure that
20676      * only the process that calls getAppTasks() can call the AppTask methods.
20677      */
20678     class AppTaskImpl extends IAppTask.Stub {
20679         private int mTaskId;
20680         private int mCallingUid;
20681
20682         public AppTaskImpl(int taskId, int callingUid) {
20683             mTaskId = taskId;
20684             mCallingUid = callingUid;
20685         }
20686
20687         private void checkCaller() {
20688             if (mCallingUid != Binder.getCallingUid()) {
20689                 throw new SecurityException("Caller " + mCallingUid
20690                         + " does not match caller of getAppTasks(): " + Binder.getCallingUid());
20691             }
20692         }
20693
20694         @Override
20695         public void finishAndRemoveTask() {
20696             checkCaller();
20697
20698             synchronized (ActivityManagerService.this) {
20699                 long origId = Binder.clearCallingIdentity();
20700                 try {
20701                     // We remove the task from recents to preserve backwards
20702                     if (!removeTaskByIdLocked(mTaskId, false, REMOVE_FROM_RECENTS)) {
20703                         throw new IllegalArgumentException("Unable to find task ID " + mTaskId);
20704                     }
20705                 } finally {
20706                     Binder.restoreCallingIdentity(origId);
20707                 }
20708             }
20709         }
20710
20711         @Override
20712         public ActivityManager.RecentTaskInfo getTaskInfo() {
20713             checkCaller();
20714
20715             synchronized (ActivityManagerService.this) {
20716                 long origId = Binder.clearCallingIdentity();
20717                 try {
20718                     TaskRecord tr = mStackSupervisor.anyTaskForIdLocked(mTaskId);
20719                     if (tr == null) {
20720                         throw new IllegalArgumentException("Unable to find task ID " + mTaskId);
20721                     }
20722                     return createRecentTaskInfoFromTaskRecord(tr);
20723                 } finally {
20724                     Binder.restoreCallingIdentity(origId);
20725                 }
20726             }
20727         }
20728
20729         @Override
20730         public void moveToFront() {
20731             checkCaller();
20732             // Will bring task to front if it already has a root activity.
20733             startActivityFromRecentsInner(mTaskId, INVALID_STACK_ID, null);
20734         }
20735
20736         @Override
20737         public int startActivity(IBinder whoThread, String callingPackage,
20738                 Intent intent, String resolvedType, Bundle bOptions) {
20739             checkCaller();
20740
20741             int callingUser = UserHandle.getCallingUserId();
20742             TaskRecord tr;
20743             IApplicationThread appThread;
20744             synchronized (ActivityManagerService.this) {
20745                 tr = mStackSupervisor.anyTaskForIdLocked(mTaskId);
20746                 if (tr == null) {
20747                     throw new IllegalArgumentException("Unable to find task ID " + mTaskId);
20748                 }
20749                 appThread = ApplicationThreadNative.asInterface(whoThread);
20750                 if (appThread == null) {
20751                     throw new IllegalArgumentException("Bad app thread " + appThread);
20752                 }
20753             }
20754             return mStackSupervisor.startActivityMayWait(appThread, -1, callingPackage, intent,
20755                     resolvedType, null, null, null, null, 0, 0, null, null,
20756                     null, bOptions, false, callingUser, null, tr);
20757         }
20758
20759         @Override
20760         public void setExcludeFromRecents(boolean exclude) {
20761             checkCaller();
20762
20763             synchronized (ActivityManagerService.this) {
20764                 long origId = Binder.clearCallingIdentity();
20765                 try {
20766                     TaskRecord tr = mStackSupervisor.anyTaskForIdLocked(mTaskId);
20767                     if (tr == null) {
20768                         throw new IllegalArgumentException("Unable to find task ID " + mTaskId);
20769                     }
20770                     Intent intent = tr.getBaseIntent();
20771                     if (exclude) {
20772                         intent.addFlags(Intent.FLAG_ACTIVITY_EXCLUDE_FROM_RECENTS);
20773                     } else {
20774                         intent.setFlags(intent.getFlags()
20775                                 & ~Intent.FLAG_ACTIVITY_EXCLUDE_FROM_RECENTS);
20776                     }
20777                 } finally {
20778                     Binder.restoreCallingIdentity(origId);
20779                 }
20780             }
20781         }
20782     }
20783 }