OSDN Git Service

Merge changes from topic "am-09249f80-e618-46fc-ac06-c7fdc73c36ae" into oc-dev
[android-x86/frameworks-base.git] / services / core / java / com / android / server / am / ActivityManagerService.java
1 /*
2  * Copyright (C) 2006-2008 The Android Open Source Project
3  *
4  * Licensed under the Apache License, Version 2.0 (the "License");
5  * you may not use this file except in compliance with the License.
6  * You may obtain a copy of the License at
7  *
8  *      http://www.apache.org/licenses/LICENSE-2.0
9  *
10  * Unless required by applicable law or agreed to in writing, software
11  * distributed under the License is distributed on an "AS IS" BASIS,
12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13  * See the License for the specific language governing permissions and
14  * limitations under the License.
15  */
16
17 package com.android.server.am;
18
19 import static android.Manifest.permission.CHANGE_CONFIGURATION;
20 import static android.Manifest.permission.CHANGE_DEVICE_IDLE_TEMP_WHITELIST;
21 import static android.Manifest.permission.INTERACT_ACROSS_USERS;
22 import static android.Manifest.permission.INTERACT_ACROSS_USERS_FULL;
23 import static android.Manifest.permission.INTERNAL_SYSTEM_WINDOW;
24 import static android.Manifest.permission.MANAGE_ACTIVITY_STACKS;
25 import static android.Manifest.permission.READ_FRAME_BUFFER;
26 import static android.Manifest.permission.START_TASKS_FROM_RECENTS;
27 import static android.app.ActivityManager.DOCKED_STACK_CREATE_MODE_TOP_OR_LEFT;
28 import static android.app.ActivityManager.RESIZE_MODE_PRESERVE_WINDOW;
29 import static android.app.ActivityManager.StackId.DOCKED_STACK_ID;
30 import static android.app.ActivityManager.StackId.FREEFORM_WORKSPACE_STACK_ID;
31 import static android.app.ActivityManager.StackId.FULLSCREEN_WORKSPACE_STACK_ID;
32 import static android.app.ActivityManager.StackId.INVALID_STACK_ID;
33 import static android.app.ActivityManager.StackId.PINNED_STACK_ID;
34 import static android.content.pm.PackageManager.FEATURE_ACTIVITIES_ON_SECONDARY_DISPLAYS;
35 import static android.content.pm.PackageManager.FEATURE_FREEFORM_WINDOW_MANAGEMENT;
36 import static android.content.pm.PackageManager.FEATURE_LEANBACK_ONLY;
37 import static android.content.pm.PackageManager.FEATURE_PICTURE_IN_PICTURE;
38 import static android.content.pm.PackageManager.GET_PROVIDERS;
39 import static android.content.pm.PackageManager.MATCH_ANY_USER;
40 import static android.content.pm.PackageManager.MATCH_DEBUG_TRIAGED_MISSING;
41 import static android.content.pm.PackageManager.MATCH_DIRECT_BOOT_AWARE;
42 import static android.content.pm.PackageManager.MATCH_DIRECT_BOOT_UNAWARE;
43 import static android.content.pm.PackageManager.MATCH_SYSTEM_ONLY;
44 import static android.content.pm.PackageManager.MATCH_UNINSTALLED_PACKAGES;
45 import static android.content.pm.PackageManager.PERMISSION_GRANTED;
46 import static android.content.res.Configuration.UI_MODE_TYPE_TELEVISION;
47 import static android.net.NetworkPolicyManager.isProcStateAllowedWhileIdleOrPowerSaveMode;
48 import static android.net.NetworkPolicyManager.isProcStateAllowedWhileOnRestrictBackground;
49 import static android.os.Build.VERSION_CODES.N;
50 import static android.os.Process.BLUETOOTH_UID;
51 import static android.os.Process.FIRST_APPLICATION_UID;
52 import static android.os.Process.FIRST_ISOLATED_UID;
53 import static android.os.Process.LAST_ISOLATED_UID;
54 import static android.os.Process.NFC_UID;
55 import static android.os.Process.PHONE_UID;
56 import static android.os.Process.PROC_CHAR;
57 import static android.os.Process.PROC_OUT_LONG;
58 import static android.os.Process.PROC_PARENS;
59 import static android.os.Process.PROC_SPACE_TERM;
60 import static android.os.Process.ProcessStartResult;
61 import static android.os.Process.ROOT_UID;
62 import static android.os.Process.SCHED_FIFO;
63 import static android.os.Process.SCHED_OTHER;
64 import static android.os.Process.SCHED_RESET_ON_FORK;
65 import static android.os.Process.SHELL_UID;
66 import static android.os.Process.SIGNAL_QUIT;
67 import static android.os.Process.SIGNAL_USR1;
68 import static android.os.Process.SYSTEM_UID;
69 import static android.os.Process.THREAD_GROUP_BG_NONINTERACTIVE;
70 import static android.os.Process.THREAD_GROUP_DEFAULT;
71 import static android.os.Process.THREAD_GROUP_TOP_APP;
72 import static android.os.Process.THREAD_PRIORITY_BACKGROUND;
73 import static android.os.Process.THREAD_PRIORITY_FOREGROUND;
74 import static android.os.Process.getFreeMemory;
75 import static android.os.Process.getTotalMemory;
76 import static android.os.Process.isThreadInProcess;
77 import static android.os.Process.killProcess;
78 import static android.os.Process.killProcessQuiet;
79 import static android.os.Process.myPid;
80 import static android.os.Process.myUid;
81 import static android.os.Process.readProcFile;
82 import static android.os.Process.removeAllProcessGroups;
83 import static android.os.Process.sendSignal;
84 import static android.os.Process.setProcessGroup;
85 import static android.os.Process.setThreadPriority;
86 import static android.os.Process.setThreadScheduler;
87 import static android.os.Process.startWebView;
88 import static android.os.Process.zygoteProcess;
89 import static android.provider.Settings.Global.ALWAYS_FINISH_ACTIVITIES;
90 import static android.provider.Settings.Global.DEBUG_APP;
91 import static android.provider.Settings.Global.DEVELOPMENT_ENABLE_FREEFORM_WINDOWS_SUPPORT;
92 import static android.provider.Settings.Global.DEVELOPMENT_FORCE_RESIZABLE_ACTIVITIES;
93 import static android.provider.Settings.Global.DEVELOPMENT_FORCE_RTL;
94 import static android.provider.Settings.Global.NETWORK_ACCESS_TIMEOUT_MS;
95 import static android.provider.Settings.Global.WAIT_FOR_DEBUGGER;
96 import static android.provider.Settings.System.FONT_SCALE;
97 import static android.service.voice.VoiceInteractionSession.SHOW_SOURCE_APPLICATION;
98 import static android.view.Display.DEFAULT_DISPLAY;
99 import static android.view.Display.INVALID_DISPLAY;
100 import static com.android.internal.util.XmlUtils.readBooleanAttribute;
101 import static com.android.internal.util.XmlUtils.readIntAttribute;
102 import static com.android.internal.util.XmlUtils.readLongAttribute;
103 import static com.android.internal.util.XmlUtils.writeBooleanAttribute;
104 import static com.android.internal.util.XmlUtils.writeIntAttribute;
105 import static com.android.internal.util.XmlUtils.writeLongAttribute;
106 import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_ALL;
107 import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_ANR;
108 import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_BACKGROUND_CHECK;
109 import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_BACKUP;
110 import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_BROADCAST;
111 import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_BROADCAST_BACKGROUND;
112 import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_BROADCAST_LIGHT;
113 import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_CLEANUP;
114 import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_CONFIGURATION;
115 import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_FOCUS;
116 import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_IMMERSIVE;
117 import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_LOCKTASK;
118 import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_LRU;
119 import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_MU;
120 import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_NETWORK;
121 import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_OOM_ADJ;
122 import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_OOM_ADJ_REASON;
123 import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_PERMISSIONS_REVIEW;
124 import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_POWER;
125 import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_PROCESSES;
126 import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_PROCESS_OBSERVERS;
127 import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_PROVIDER;
128 import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_PSS;
129 import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_RECENTS;
130 import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_SERVICE;
131 import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_STACK;
132 import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_SWITCH;
133 import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_TASKS;
134 import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_UID_OBSERVERS;
135 import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_URI_PERMISSION;
136 import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_USAGE_STATS;
137 import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_VISIBILITY;
138 import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_VISIBLE_BEHIND;
139 import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_WHITELISTS;
140 import static com.android.server.am.ActivityManagerDebugConfig.POSTFIX_BACKUP;
141 import static com.android.server.am.ActivityManagerDebugConfig.POSTFIX_BROADCAST;
142 import static com.android.server.am.ActivityManagerDebugConfig.POSTFIX_CLEANUP;
143 import static com.android.server.am.ActivityManagerDebugConfig.POSTFIX_CONFIGURATION;
144 import static com.android.server.am.ActivityManagerDebugConfig.POSTFIX_FOCUS;
145 import static com.android.server.am.ActivityManagerDebugConfig.POSTFIX_IMMERSIVE;
146 import static com.android.server.am.ActivityManagerDebugConfig.POSTFIX_LOCKSCREEN;
147 import static com.android.server.am.ActivityManagerDebugConfig.POSTFIX_LOCKTASK;
148 import static com.android.server.am.ActivityManagerDebugConfig.POSTFIX_LRU;
149 import static com.android.server.am.ActivityManagerDebugConfig.POSTFIX_MU;
150 import static com.android.server.am.ActivityManagerDebugConfig.POSTFIX_NETWORK;
151 import static com.android.server.am.ActivityManagerDebugConfig.POSTFIX_OOM_ADJ;
152 import static com.android.server.am.ActivityManagerDebugConfig.POSTFIX_POWER;
153 import static com.android.server.am.ActivityManagerDebugConfig.POSTFIX_PROCESSES;
154 import static com.android.server.am.ActivityManagerDebugConfig.POSTFIX_PROCESS_OBSERVERS;
155 import static com.android.server.am.ActivityManagerDebugConfig.POSTFIX_PROVIDER;
156 import static com.android.server.am.ActivityManagerDebugConfig.POSTFIX_PSS;
157 import static com.android.server.am.ActivityManagerDebugConfig.POSTFIX_RECENTS;
158 import static com.android.server.am.ActivityManagerDebugConfig.POSTFIX_SERVICE;
159 import static com.android.server.am.ActivityManagerDebugConfig.POSTFIX_STACK;
160 import static com.android.server.am.ActivityManagerDebugConfig.POSTFIX_SWITCH;
161 import static com.android.server.am.ActivityManagerDebugConfig.POSTFIX_UID_OBSERVERS;
162 import static com.android.server.am.ActivityManagerDebugConfig.POSTFIX_URI_PERMISSION;
163 import static com.android.server.am.ActivityManagerDebugConfig.POSTFIX_VISIBILITY;
164 import static com.android.server.am.ActivityManagerDebugConfig.POSTFIX_VISIBLE_BEHIND;
165 import static com.android.server.am.ActivityManagerDebugConfig.TAG_AM;
166 import static com.android.server.am.ActivityManagerDebugConfig.TAG_WITH_CLASS_NAME;
167 import static com.android.server.am.ActivityStackSupervisor.ActivityContainer.FORCE_NEW_TASK_FLAGS;
168 import static com.android.server.am.ActivityStackSupervisor.CREATE_IF_NEEDED;
169 import static com.android.server.am.ActivityStackSupervisor.DEFER_RESUME;
170 import static com.android.server.am.ActivityStackSupervisor.MATCH_TASK_IN_STACKS_ONLY;
171 import static com.android.server.am.ActivityStackSupervisor.MATCH_TASK_IN_STACKS_OR_RECENT_TASKS;
172 import static com.android.server.am.ActivityStackSupervisor.ON_TOP;
173 import static com.android.server.am.ActivityStackSupervisor.PRESERVE_WINDOWS;
174 import static com.android.server.am.ActivityStackSupervisor.REMOVE_FROM_RECENTS;
175 import static com.android.server.am.TaskRecord.INVALID_TASK_ID;
176 import static com.android.server.am.TaskRecord.LOCK_TASK_AUTH_DONT_LOCK;
177 import static com.android.server.am.TaskRecord.LOCK_TASK_AUTH_LAUNCHABLE_PRIV;
178 import static com.android.server.am.TaskRecord.LOCK_TASK_AUTH_PINNABLE;
179 import static com.android.server.am.TaskRecord.REPARENT_KEEP_STACK_AT_FRONT;
180 import static com.android.server.am.TaskRecord.REPARENT_LEAVE_STACK_IN_PLACE;
181 import static com.android.server.wm.AppTransition.TRANSIT_ACTIVITY_OPEN;
182 import static com.android.server.wm.AppTransition.TRANSIT_ACTIVITY_RELAUNCH;
183 import static com.android.server.wm.AppTransition.TRANSIT_NONE;
184 import static com.android.server.wm.AppTransition.TRANSIT_TASK_IN_PLACE;
185 import static com.android.server.wm.AppTransition.TRANSIT_TASK_OPEN;
186 import static com.android.server.wm.AppTransition.TRANSIT_TASK_TO_FRONT;
187 import static org.xmlpull.v1.XmlPullParser.END_DOCUMENT;
188 import static org.xmlpull.v1.XmlPullParser.START_TAG;
189
190 import android.Manifest;
191 import android.Manifest.permission;
192 import android.annotation.NonNull;
193 import android.annotation.Nullable;
194 import android.annotation.UserIdInt;
195 import android.app.Activity;
196 import android.app.ActivityManager;
197 import android.app.ActivityManager.RunningTaskInfo;
198 import android.app.ActivityManager.StackId;
199 import android.app.ActivityManager.StackInfo;
200 import android.app.ActivityManager.TaskSnapshot;
201 import android.app.ActivityManager.TaskThumbnailInfo;
202 import android.app.ActivityManagerInternal;
203 import android.app.ActivityManagerInternal.SleepToken;
204 import android.app.ActivityOptions;
205 import android.app.ActivityThread;
206 import android.app.AlertDialog;
207 import android.app.AppGlobals;
208 import android.app.AppOpsManager;
209 import android.app.ApplicationErrorReport;
210 import android.app.ApplicationThreadConstants;
211 import android.app.BroadcastOptions;
212 import android.app.ContentProviderHolder;
213 import android.app.Dialog;
214 import android.app.IActivityContainer;
215 import android.app.IActivityContainerCallback;
216 import android.app.IActivityController;
217 import android.app.IActivityManager;
218 import android.app.IAppTask;
219 import android.app.IApplicationThread;
220 import android.app.IInstrumentationWatcher;
221 import android.app.INotificationManager;
222 import android.app.IProcessObserver;
223 import android.app.IServiceConnection;
224 import android.app.IStopUserCallback;
225 import android.app.ITaskStackListener;
226 import android.app.IUiAutomationConnection;
227 import android.app.IUidObserver;
228 import android.app.IUserSwitchObserver;
229 import android.app.Instrumentation;
230 import android.app.Notification;
231 import android.app.NotificationManager;
232 import android.app.PendingIntent;
233 import android.app.PictureInPictureParams;
234 import android.app.ProfilerInfo;
235 import android.app.RemoteAction;
236 import android.app.WaitResult;
237 import android.app.admin.DevicePolicyManager;
238 import android.app.assist.AssistContent;
239 import android.app.assist.AssistStructure;
240 import android.app.backup.IBackupManager;
241 import android.app.usage.UsageEvents;
242 import android.app.usage.UsageStatsManagerInternal;
243 import android.appwidget.AppWidgetManager;
244 import android.content.ActivityNotFoundException;
245 import android.content.BroadcastReceiver;
246 import android.content.ClipData;
247 import android.content.ComponentCallbacks2;
248 import android.content.ComponentName;
249 import android.content.ContentProvider;
250 import android.content.ContentResolver;
251 import android.content.Context;
252 import android.content.DialogInterface;
253 import android.content.IContentProvider;
254 import android.content.IIntentReceiver;
255 import android.content.IIntentSender;
256 import android.content.Intent;
257 import android.content.IntentFilter;
258 import android.content.IntentSender;
259 import android.content.pm.ActivityInfo;
260 import android.content.pm.ApplicationInfo;
261 import android.content.pm.ConfigurationInfo;
262 import android.content.pm.IPackageDataObserver;
263 import android.content.pm.IPackageManager;
264 import android.content.pm.InstrumentationInfo;
265 import android.content.pm.PackageInfo;
266 import android.content.pm.PackageManager;
267 import android.content.pm.PackageManager.NameNotFoundException;
268 import android.content.pm.PackageManagerInternal;
269 import android.content.pm.ParceledListSlice;
270 import android.content.pm.PathPermission;
271 import android.content.pm.PermissionInfo;
272 import android.content.pm.ProviderInfo;
273 import android.content.pm.ResolveInfo;
274 import android.content.pm.SELinuxUtil;
275 import android.content.pm.ServiceInfo;
276 import android.content.pm.UserInfo;
277 import android.content.res.CompatibilityInfo;
278 import android.content.res.Configuration;
279 import android.content.res.Resources;
280 import android.database.ContentObserver;
281 import android.graphics.Bitmap;
282 import android.graphics.Point;
283 import android.graphics.Rect;
284 import android.location.LocationManager;
285 import android.media.audiofx.AudioEffect;
286 import android.metrics.LogMaker;
287 import android.net.Proxy;
288 import android.net.ProxyInfo;
289 import android.net.Uri;
290 import android.os.BatteryStats;
291 import android.os.Binder;
292 import android.os.Build;
293 import android.os.Bundle;
294 import android.os.Debug;
295 import android.os.DropBoxManager;
296 import android.os.Environment;
297 import android.os.FactoryTest;
298 import android.os.FileObserver;
299 import android.os.FileUtils;
300 import android.os.Handler;
301 import android.os.IBinder;
302 import android.os.IDeviceIdentifiersPolicyService;
303 import android.os.IPermissionController;
304 import android.os.IProcessInfoService;
305 import android.os.IProgressListener;
306 import android.os.LocaleList;
307 import android.os.Looper;
308 import android.os.Message;
309 import android.os.Parcel;
310 import android.os.ParcelFileDescriptor;
311 import android.os.PersistableBundle;
312 import android.os.PowerManager;
313 import android.os.PowerManagerInternal;
314 import android.os.Process;
315 import android.os.RemoteCallbackList;
316 import android.os.RemoteException;
317 import android.os.ResultReceiver;
318 import android.os.ServiceManager;
319 import android.os.ShellCallback;
320 import android.os.StrictMode;
321 import android.os.SystemClock;
322 import android.os.SystemProperties;
323 import android.os.Trace;
324 import android.os.TransactionTooLargeException;
325 import android.os.UpdateLock;
326 import android.os.UserHandle;
327 import android.os.UserManager;
328 import android.os.WorkSource;
329 import android.os.storage.IStorageManager;
330 import android.os.storage.StorageManager;
331 import android.os.storage.StorageManagerInternal;
332 import android.provider.Downloads;
333 import android.provider.Settings;
334 import android.service.voice.IVoiceInteractionSession;
335 import android.service.voice.VoiceInteractionManagerInternal;
336 import android.service.voice.VoiceInteractionSession;
337 import android.telecom.TelecomManager;
338 import android.text.TextUtils;
339 import android.text.format.DateUtils;
340 import android.text.format.Time;
341 import android.text.style.SuggestionSpan;
342 import android.util.ArrayMap;
343 import android.util.ArraySet;
344 import android.util.AtomicFile;
345 import android.util.BootTimingsTraceLog;
346 import android.util.DebugUtils;
347 import android.util.DisplayMetrics;
348 import android.util.EventLog;
349 import android.util.Log;
350 import android.util.Pair;
351 import android.util.PrintWriterPrinter;
352 import android.util.Slog;
353 import android.util.SparseArray;
354 import android.util.SparseIntArray;
355 import android.util.TimeUtils;
356 import android.util.Xml;
357 import android.view.Gravity;
358 import android.view.LayoutInflater;
359 import android.view.View;
360 import android.view.WindowManager;
361
362 import com.android.server.job.JobSchedulerInternal;
363 import com.google.android.collect.Lists;
364 import com.google.android.collect.Maps;
365
366 import com.android.internal.R;
367 import com.android.internal.annotations.GuardedBy;
368 import com.android.internal.annotations.VisibleForTesting;
369 import com.android.internal.app.AssistUtils;
370 import com.android.internal.app.DumpHeapActivity;
371 import com.android.internal.app.IAppOpsCallback;
372 import com.android.internal.app.IAppOpsService;
373 import com.android.internal.app.IVoiceInteractor;
374 import com.android.internal.app.ProcessMap;
375 import com.android.internal.app.SystemUserHomeActivity;
376 import com.android.internal.app.procstats.ProcessStats;
377 import com.android.internal.logging.MetricsLogger;
378 import com.android.internal.logging.nano.MetricsProto.MetricsEvent;
379 import com.android.internal.messages.nano.SystemMessageProto.SystemMessage;
380 import com.android.internal.notification.SystemNotificationChannels;
381 import com.android.internal.os.BackgroundThread;
382 import com.android.internal.os.BatteryStatsImpl;
383 import com.android.internal.os.IResultReceiver;
384 import com.android.internal.os.ProcessCpuTracker;
385 import com.android.internal.os.TransferPipe;
386 import com.android.internal.os.Zygote;
387 import com.android.internal.policy.IKeyguardDismissCallback;
388 import com.android.internal.telephony.TelephonyIntents;
389 import com.android.internal.util.ArrayUtils;
390 import com.android.internal.util.DumpUtils;
391 import com.android.internal.util.FastPrintWriter;
392 import com.android.internal.util.FastXmlSerializer;
393 import com.android.internal.util.MemInfoReader;
394 import com.android.internal.util.Preconditions;
395 import com.android.server.AppOpsService;
396 import com.android.server.AttributeCache;
397 import com.android.server.DeviceIdleController;
398 import com.android.server.IntentResolver;
399 import com.android.server.LocalServices;
400 import com.android.server.LockGuard;
401 import com.android.server.NetworkManagementInternal;
402 import com.android.server.RescueParty;
403 import com.android.server.ServiceThread;
404 import com.android.server.SystemConfig;
405 import com.android.server.SystemService;
406 import com.android.server.SystemServiceManager;
407 import com.android.server.ThreadPriorityBooster;
408 import com.android.server.Watchdog;
409 import com.android.server.am.ActivityStack.ActivityState;
410 import com.android.server.firewall.IntentFirewall;
411 import com.android.server.pm.Installer;
412 import com.android.server.pm.Installer.InstallerException;
413 import com.android.server.statusbar.StatusBarManagerInternal;
414 import com.android.server.vr.VrManagerInternal;
415 import com.android.server.wm.PinnedStackWindowController;
416 import com.android.server.wm.WindowManagerService;
417
418 import org.xmlpull.v1.XmlPullParser;
419 import org.xmlpull.v1.XmlPullParserException;
420 import org.xmlpull.v1.XmlSerializer;
421
422 import java.io.File;
423 import java.io.FileDescriptor;
424 import java.io.FileInputStream;
425 import java.io.FileNotFoundException;
426 import java.io.FileOutputStream;
427 import java.io.IOException;
428 import java.io.InputStreamReader;
429 import java.io.PrintWriter;
430 import java.io.StringWriter;
431 import java.io.UnsupportedEncodingException;
432 import java.lang.ref.WeakReference;
433 import java.nio.charset.StandardCharsets;
434 import java.text.DateFormat;
435 import java.util.ArrayList;
436 import java.util.Arrays;
437 import java.util.Collections;
438 import java.util.Comparator;
439 import java.util.Date;
440 import java.util.HashMap;
441 import java.util.HashSet;
442 import java.util.Iterator;
443 import java.util.List;
444 import java.util.Locale;
445 import java.util.Map;
446 import java.util.Objects;
447 import java.util.Set;
448 import java.util.concurrent.CountDownLatch;
449 import java.util.concurrent.atomic.AtomicBoolean;
450 import java.util.concurrent.atomic.AtomicLong;
451
452 import dalvik.system.VMRuntime;
453 import libcore.io.IoUtils;
454 import libcore.util.EmptyArray;
455
456 public class ActivityManagerService extends IActivityManager.Stub
457         implements Watchdog.Monitor, BatteryStatsImpl.BatteryCallback {
458
459     /**
460      * Priority we boost main thread and RT of top app to.
461      */
462     public static final int TOP_APP_PRIORITY_BOOST = -10;
463
464     private static final String TAG = TAG_WITH_CLASS_NAME ? "ActivityManagerService" : TAG_AM;
465     private static final String TAG_BACKUP = TAG + POSTFIX_BACKUP;
466     private static final String TAG_BROADCAST = TAG + POSTFIX_BROADCAST;
467     private static final String TAG_CLEANUP = TAG + POSTFIX_CLEANUP;
468     private static final String TAG_CONFIGURATION = TAG + POSTFIX_CONFIGURATION;
469     private static final String TAG_FOCUS = TAG + POSTFIX_FOCUS;
470     private static final String TAG_IMMERSIVE = TAG + POSTFIX_IMMERSIVE;
471     private static final String TAG_LOCKSCREEN = TAG + POSTFIX_LOCKSCREEN;
472     private static final String TAG_LOCKTASK = TAG + POSTFIX_LOCKTASK;
473     private static final String TAG_LRU = TAG + POSTFIX_LRU;
474     private static final String TAG_MU = TAG + POSTFIX_MU;
475     private static final String TAG_NETWORK = TAG + POSTFIX_NETWORK;
476     private static final String TAG_OOM_ADJ = TAG + POSTFIX_OOM_ADJ;
477     private static final String TAG_POWER = TAG + POSTFIX_POWER;
478     private static final String TAG_PROCESS_OBSERVERS = TAG + POSTFIX_PROCESS_OBSERVERS;
479     private static final String TAG_PROCESSES = TAG + POSTFIX_PROCESSES;
480     private static final String TAG_PROVIDER = TAG + POSTFIX_PROVIDER;
481     private static final String TAG_PSS = TAG + POSTFIX_PSS;
482     private static final String TAG_RECENTS = TAG + POSTFIX_RECENTS;
483     private static final String TAG_SERVICE = TAG + POSTFIX_SERVICE;
484     private static final String TAG_STACK = TAG + POSTFIX_STACK;
485     private static final String TAG_SWITCH = TAG + POSTFIX_SWITCH;
486     private static final String TAG_UID_OBSERVERS = TAG + POSTFIX_UID_OBSERVERS;
487     private static final String TAG_URI_PERMISSION = TAG + POSTFIX_URI_PERMISSION;
488     private static final String TAG_VISIBILITY = TAG + POSTFIX_VISIBILITY;
489     private static final String TAG_VISIBLE_BEHIND = TAG + POSTFIX_VISIBLE_BEHIND;
490
491     // Mock "pretend we're idle now" broadcast action to the job scheduler; declared
492     // here so that while the job scheduler can depend on AMS, the other way around
493     // need not be the case.
494     public static final String ACTION_TRIGGER_IDLE = "com.android.server.ACTION_TRIGGER_IDLE";
495
496     /** Control over CPU and battery monitoring */
497     // write battery stats every 30 minutes.
498     static final long BATTERY_STATS_TIME = 30 * 60 * 1000;
499     static final boolean MONITOR_CPU_USAGE = true;
500     // don't sample cpu less than every 5 seconds.
501     static final long MONITOR_CPU_MIN_TIME = 5 * 1000;
502     // wait possibly forever for next cpu sample.
503     static final long MONITOR_CPU_MAX_TIME = 0x0fffffff;
504     static final boolean MONITOR_THREAD_CPU_USAGE = false;
505
506     // The flags that are set for all calls we make to the package manager.
507     static final int STOCK_PM_FLAGS = PackageManager.GET_SHARED_LIBRARY_FILES;
508
509     static final String SYSTEM_DEBUGGABLE = "ro.debuggable";
510
511     static final boolean IS_USER_BUILD = "user".equals(Build.TYPE);
512
513     // Amount of time after a call to stopAppSwitches() during which we will
514     // prevent further untrusted switches from happening.
515     static final long APP_SWITCH_DELAY_TIME = 5*1000;
516
517     // How long we wait for a launched process to attach to the activity manager
518     // before we decide it's never going to come up for real.
519     static final int PROC_START_TIMEOUT = 10*1000;
520     // How long we wait for an attached process to publish its content providers
521     // before we decide it must be hung.
522     static final int CONTENT_PROVIDER_PUBLISH_TIMEOUT = 10*1000;
523
524     // How long we wait for a launched process to attach to the activity manager
525     // before we decide it's never going to come up for real, when the process was
526     // started with a wrapper for instrumentation (such as Valgrind) because it
527     // could take much longer than usual.
528     static final int PROC_START_TIMEOUT_WITH_WRAPPER = 1200*1000;
529
530     // How long we allow a receiver to run before giving up on it.
531     static final int BROADCAST_FG_TIMEOUT = 10*1000;
532     static final int BROADCAST_BG_TIMEOUT = 60*1000;
533
534     // How long we wait until we timeout on key dispatching.
535     static final int KEY_DISPATCHING_TIMEOUT = 5*1000;
536
537     // How long we wait until we timeout on key dispatching during instrumentation.
538     static final int INSTRUMENTATION_KEY_DISPATCHING_TIMEOUT = 60*1000;
539
540     // How long to wait in getAssistContextExtras for the activity and foreground services
541     // to respond with the result.
542     static final int PENDING_ASSIST_EXTRAS_TIMEOUT = 500;
543
544     // How long top wait when going through the modern assist (which doesn't need to block
545     // on getting this result before starting to launch its UI).
546     static final int PENDING_ASSIST_EXTRAS_LONG_TIMEOUT = 2000;
547
548     // How long to wait in getAutofillAssistStructure() for the activity to respond with the result.
549     static final int PENDING_AUTOFILL_ASSIST_STRUCTURE_TIMEOUT = 2000;
550
551     // Maximum number of persisted Uri grants a package is allowed
552     static final int MAX_PERSISTED_URI_GRANTS = 128;
553
554     static final int MY_PID = myPid();
555
556     static final String[] EMPTY_STRING_ARRAY = new String[0];
557
558     // How many bytes to write into the dropbox log before truncating
559     static final int DROPBOX_MAX_SIZE = 192 * 1024;
560     // Assumes logcat entries average around 100 bytes; that's not perfect stack traces count
561     // as one line, but close enough for now.
562     static final int RESERVED_BYTES_PER_LOGCAT_LINE = 100;
563
564     // Access modes for handleIncomingUser.
565     static final int ALLOW_NON_FULL = 0;
566     static final int ALLOW_NON_FULL_IN_PROFILE = 1;
567     static final int ALLOW_FULL_ONLY = 2;
568
569     // Necessary ApplicationInfo flags to mark an app as persistent
570     private static final int PERSISTENT_MASK =
571             ApplicationInfo.FLAG_SYSTEM|ApplicationInfo.FLAG_PERSISTENT;
572
573     // Intent sent when remote bugreport collection has been completed
574     private static final String INTENT_REMOTE_BUGREPORT_FINISHED =
575             "com.android.internal.intent.action.REMOTE_BUGREPORT_FINISHED";
576
577     // Used to indicate that an app transition should be animated.
578     static final boolean ANIMATE = true;
579
580     // Determines whether to take full screen screenshots
581     static final boolean TAKE_FULLSCREEN_SCREENSHOTS = true;
582
583     /**
584      * Default value for {@link Settings.Global#NETWORK_ACCESS_TIMEOUT_MS}.
585      */
586     private static final long NETWORK_ACCESS_TIMEOUT_DEFAULT_MS = 200; // 0.2 sec
587
588     /**
589      * State indicating that there is no need for any blocking for network.
590      */
591     @VisibleForTesting
592     static final int NETWORK_STATE_NO_CHANGE = 0;
593
594     /**
595      * State indicating that the main thread needs to be informed about the network wait.
596      */
597     @VisibleForTesting
598     static final int NETWORK_STATE_BLOCK = 1;
599
600     /**
601      * State indicating that any threads waiting for network state to get updated can be unblocked.
602      */
603     @VisibleForTesting
604     static final int NETWORK_STATE_UNBLOCK = 2;
605
606     // Max character limit for a notification title. If the notification title is larger than this
607     // the notification will not be legible to the user.
608     private static final int MAX_BUGREPORT_TITLE_SIZE = 50;
609
610     private static final int NATIVE_DUMP_TIMEOUT_MS = 2000; // 2 seconds;
611
612     /** All system services */
613     SystemServiceManager mSystemServiceManager;
614     AssistUtils mAssistUtils;
615
616     private Installer mInstaller;
617
618     /** Run all ActivityStacks through this */
619     final ActivityStackSupervisor mStackSupervisor;
620     private final KeyguardController mKeyguardController;
621
622     final ActivityStarter mActivityStarter;
623
624     final TaskChangeNotificationController mTaskChangeNotificationController;
625
626     final InstrumentationReporter mInstrumentationReporter = new InstrumentationReporter();
627
628     final ArrayList<ActiveInstrumentation> mActiveInstrumentation = new ArrayList<>();
629
630     public final IntentFirewall mIntentFirewall;
631
632     // Whether we should show our dialogs (ANR, crash, etc) or just perform their
633     // default action automatically.  Important for devices without direct input
634     // devices.
635     private boolean mShowDialogs = true;
636
637     private final VrController mVrController;
638
639     // VR Vr2d Display Id.
640     int mVr2dDisplayId = INVALID_DISPLAY;
641
642     // Whether we should use SCHED_FIFO for UI and RenderThreads.
643     private boolean mUseFifoUiScheduling = false;
644
645     BroadcastQueue mFgBroadcastQueue;
646     BroadcastQueue mBgBroadcastQueue;
647     // Convenient for easy iteration over the queues. Foreground is first
648     // so that dispatch of foreground broadcasts gets precedence.
649     final BroadcastQueue[] mBroadcastQueues = new BroadcastQueue[2];
650
651     BroadcastStats mLastBroadcastStats;
652     BroadcastStats mCurBroadcastStats;
653
654     BroadcastQueue broadcastQueueForIntent(Intent intent) {
655         final boolean isFg = (intent.getFlags() & Intent.FLAG_RECEIVER_FOREGROUND) != 0;
656         if (DEBUG_BROADCAST_BACKGROUND) Slog.i(TAG_BROADCAST,
657                 "Broadcast intent " + intent + " on "
658                 + (isFg ? "foreground" : "background") + " queue");
659         return (isFg) ? mFgBroadcastQueue : mBgBroadcastQueue;
660     }
661
662     /**
663      * The last resumed activity. This is identical to the current resumed activity most
664      * of the time but could be different when we're pausing one activity before we resume
665      * another activity.
666      */
667     private ActivityRecord mLastResumedActivity;
668
669     /**
670      * If non-null, we are tracking the time the user spends in the currently focused app.
671      */
672     private AppTimeTracker mCurAppTimeTracker;
673
674     /**
675      * List of intents that were used to start the most recent tasks.
676      */
677     final RecentTasks mRecentTasks;
678
679     /**
680      * For addAppTask: cached of the last activity component that was added.
681      */
682     ComponentName mLastAddedTaskComponent;
683
684     /**
685      * For addAppTask: cached of the last activity uid that was added.
686      */
687     int mLastAddedTaskUid;
688
689     /**
690      * For addAppTask: cached of the last ActivityInfo that was added.
691      */
692     ActivityInfo mLastAddedTaskActivity;
693
694     /**
695      * List of packages whitelisted by DevicePolicyManager for locktask. Indexed by userId.
696      */
697     SparseArray<String[]> mLockTaskPackages = new SparseArray<>();
698
699     /**
700      * The package name of the DeviceOwner. This package is not permitted to have its data cleared.
701      */
702     String mDeviceOwnerName;
703
704     final UserController mUserController;
705
706     final AppErrors mAppErrors;
707
708     /**
709      * Dump of the activity state at the time of the last ANR. Cleared after
710      * {@link WindowManagerService#LAST_ANR_LIFETIME_DURATION_MSECS}
711      */
712     String mLastANRState;
713
714     /**
715      * Indicates the maximum time spent waiting for the network rules to get updated.
716      */
717     @VisibleForTesting
718     long mWaitForNetworkTimeoutMs;
719
720     public boolean canShowErrorDialogs() {
721         return mShowDialogs && !mSleeping && !mShuttingDown
722                 && !mKeyguardController.isKeyguardShowing()
723                 && !(UserManager.isDeviceInDemoMode(mContext)
724                         && mUserController.getCurrentUser().isDemo());
725     }
726
727     private static ThreadPriorityBooster sThreadPriorityBooster = new ThreadPriorityBooster(
728             THREAD_PRIORITY_FOREGROUND, LockGuard.INDEX_ACTIVITY);
729
730     static void boostPriorityForLockedSection() {
731         sThreadPriorityBooster.boost();
732     }
733
734     static void resetPriorityAfterLockedSection() {
735         sThreadPriorityBooster.reset();
736     }
737
738     public class PendingAssistExtras extends Binder implements Runnable {
739         public final ActivityRecord activity;
740         public boolean isHome;
741         public final Bundle extras;
742         public final Intent intent;
743         public final String hint;
744         public final IResultReceiver receiver;
745         public final int userHandle;
746         public boolean haveResult = false;
747         public Bundle result = null;
748         public AssistStructure structure = null;
749         public AssistContent content = null;
750         public Bundle receiverExtras;
751
752         public PendingAssistExtras(ActivityRecord _activity, Bundle _extras, Intent _intent,
753                 String _hint, IResultReceiver _receiver, Bundle _receiverExtras, int _userHandle) {
754             activity = _activity;
755             extras = _extras;
756             intent = _intent;
757             hint = _hint;
758             receiver = _receiver;
759             receiverExtras = _receiverExtras;
760             userHandle = _userHandle;
761         }
762
763         @Override
764         public void run() {
765             Slog.w(TAG, "getAssistContextExtras failed: timeout retrieving from " + activity);
766             synchronized (this) {
767                 haveResult = true;
768                 notifyAll();
769             }
770             pendingAssistExtrasTimedOut(this);
771         }
772     }
773
774     final ArrayList<PendingAssistExtras> mPendingAssistExtras
775             = new ArrayList<PendingAssistExtras>();
776
777     /**
778      * Process management.
779      */
780     final ProcessList mProcessList = new ProcessList();
781
782     /**
783      * All of the applications we currently have running organized by name.
784      * The keys are strings of the application package name (as
785      * returned by the package manager), and the keys are ApplicationRecord
786      * objects.
787      */
788     final ProcessMap<ProcessRecord> mProcessNames = new ProcessMap<ProcessRecord>();
789
790     /**
791      * Tracking long-term execution of processes to look for abuse and other
792      * bad app behavior.
793      */
794     final ProcessStatsService mProcessStats;
795
796     /**
797      * The currently running isolated processes.
798      */
799     final SparseArray<ProcessRecord> mIsolatedProcesses = new SparseArray<ProcessRecord>();
800
801     /**
802      * Counter for assigning isolated process uids, to avoid frequently reusing the
803      * same ones.
804      */
805     int mNextIsolatedProcessUid = 0;
806
807     /**
808      * The currently running heavy-weight process, if any.
809      */
810     ProcessRecord mHeavyWeightProcess = null;
811
812     /**
813      * Non-persistent appId whitelist for background restrictions
814      */
815     int[] mBackgroundAppIdWhitelist = new int[] {
816             BLUETOOTH_UID
817     };
818
819     /**
820      * Broadcast actions that will always be deliverable to unlaunched/background apps
821      */
822     ArraySet<String> mBackgroundLaunchBroadcasts;
823
824     /**
825      * All of the processes we currently have running organized by pid.
826      * The keys are the pid running the application.
827      *
828      * <p>NOTE: This object is protected by its own lock, NOT the global
829      * activity manager lock!
830      */
831     final SparseArray<ProcessRecord> mPidsSelfLocked = new SparseArray<ProcessRecord>();
832
833     /**
834      * All of the processes that have been forced to be important.  The key
835      * is the pid of the caller who requested it (we hold a death
836      * link on it).
837      */
838     abstract class ImportanceToken implements IBinder.DeathRecipient {
839         final int pid;
840         final IBinder token;
841         final String reason;
842
843         ImportanceToken(int _pid, IBinder _token, String _reason) {
844             pid = _pid;
845             token = _token;
846             reason = _reason;
847         }
848
849         @Override
850         public String toString() {
851             return "ImportanceToken { " + Integer.toHexString(System.identityHashCode(this))
852                     + " " + reason + " " + pid + " " + token + " }";
853         }
854     }
855     final SparseArray<ImportanceToken> mImportantProcesses = new SparseArray<ImportanceToken>();
856
857     /**
858      * List of records for processes that someone had tried to start before the
859      * system was ready.  We don't start them at that point, but ensure they
860      * are started by the time booting is complete.
861      */
862     final ArrayList<ProcessRecord> mProcessesOnHold = new ArrayList<ProcessRecord>();
863
864     /**
865      * List of persistent applications that are in the process
866      * of being started.
867      */
868     final ArrayList<ProcessRecord> mPersistentStartingProcesses = new ArrayList<ProcessRecord>();
869
870     /**
871      * Processes that are being forcibly torn down.
872      */
873     final ArrayList<ProcessRecord> mRemovedProcesses = new ArrayList<ProcessRecord>();
874
875     /**
876      * List of running applications, sorted by recent usage.
877      * The first entry in the list is the least recently used.
878      */
879     final ArrayList<ProcessRecord> mLruProcesses = new ArrayList<ProcessRecord>();
880
881     /**
882      * Where in mLruProcesses that the processes hosting activities start.
883      */
884     int mLruProcessActivityStart = 0;
885
886     /**
887      * Where in mLruProcesses that the processes hosting services start.
888      * This is after (lower index) than mLruProcessesActivityStart.
889      */
890     int mLruProcessServiceStart = 0;
891
892     /**
893      * List of processes that should gc as soon as things are idle.
894      */
895     final ArrayList<ProcessRecord> mProcessesToGc = new ArrayList<ProcessRecord>();
896
897     /**
898      * Processes we want to collect PSS data from.
899      */
900     final ArrayList<ProcessRecord> mPendingPssProcesses = new ArrayList<ProcessRecord>();
901
902     private boolean mBinderTransactionTrackingEnabled = false;
903
904     /**
905      * Last time we requested PSS data of all processes.
906      */
907     long mLastFullPssTime = SystemClock.uptimeMillis();
908
909     /**
910      * If set, the next time we collect PSS data we should do a full collection
911      * with data from native processes and the kernel.
912      */
913     boolean mFullPssPending = false;
914
915     /**
916      * This is the process holding what we currently consider to be
917      * the "home" activity.
918      */
919     ProcessRecord mHomeProcess;
920
921     /**
922      * This is the process holding the activity the user last visited that
923      * is in a different process from the one they are currently in.
924      */
925     ProcessRecord mPreviousProcess;
926
927     /**
928      * The time at which the previous process was last visible.
929      */
930     long mPreviousProcessVisibleTime;
931
932     /**
933      * Track all uids that have actively running processes.
934      */
935     final SparseArray<UidRecord> mActiveUids = new SparseArray<>();
936
937     /**
938      * This is for verifying the UID report flow.
939      */
940     static final boolean VALIDATE_UID_STATES = true;
941     final SparseArray<UidRecord> mValidateUids = new SparseArray<>();
942
943     /**
944      * Packages that the user has asked to have run in screen size
945      * compatibility mode instead of filling the screen.
946      */
947     final CompatModePackages mCompatModePackages;
948
949     /**
950      * Set of IntentSenderRecord objects that are currently active.
951      */
952     final HashMap<PendingIntentRecord.Key, WeakReference<PendingIntentRecord>> mIntentSenderRecords
953             = new HashMap<PendingIntentRecord.Key, WeakReference<PendingIntentRecord>>();
954
955     /**
956      * Fingerprints (hashCode()) of stack traces that we've
957      * already logged DropBox entries for.  Guarded by itself.  If
958      * something (rogue user app) forces this over
959      * MAX_DUP_SUPPRESSED_STACKS entries, the contents are cleared.
960      */
961     private final HashSet<Integer> mAlreadyLoggedViolatedStacks = new HashSet<Integer>();
962     private static final int MAX_DUP_SUPPRESSED_STACKS = 5000;
963
964     /**
965      * Strict Mode background batched logging state.
966      *
967      * The string buffer is guarded by itself, and its lock is also
968      * used to determine if another batched write is already
969      * in-flight.
970      */
971     private final StringBuilder mStrictModeBuffer = new StringBuilder();
972
973     /**
974      * Keeps track of all IIntentReceivers that have been registered for broadcasts.
975      * Hash keys are the receiver IBinder, hash value is a ReceiverList.
976      */
977     final HashMap<IBinder, ReceiverList> mRegisteredReceivers = new HashMap<>();
978
979     /**
980      * Resolver for broadcast intents to registered receivers.
981      * Holds BroadcastFilter (subclass of IntentFilter).
982      */
983     final IntentResolver<BroadcastFilter, BroadcastFilter> mReceiverResolver
984             = new IntentResolver<BroadcastFilter, BroadcastFilter>() {
985         @Override
986         protected boolean allowFilterResult(
987                 BroadcastFilter filter, List<BroadcastFilter> dest) {
988             IBinder target = filter.receiverList.receiver.asBinder();
989             for (int i = dest.size() - 1; i >= 0; i--) {
990                 if (dest.get(i).receiverList.receiver.asBinder() == target) {
991                     return false;
992                 }
993             }
994             return true;
995         }
996
997         @Override
998         protected BroadcastFilter newResult(BroadcastFilter filter, int match, int userId) {
999             if (userId == UserHandle.USER_ALL || filter.owningUserId == UserHandle.USER_ALL
1000                     || userId == filter.owningUserId) {
1001                 return super.newResult(filter, match, userId);
1002             }
1003             return null;
1004         }
1005
1006         @Override
1007         protected BroadcastFilter[] newArray(int size) {
1008             return new BroadcastFilter[size];
1009         }
1010
1011         @Override
1012         protected boolean isPackageForFilter(String packageName, BroadcastFilter filter) {
1013             return packageName.equals(filter.packageName);
1014         }
1015     };
1016
1017     /**
1018      * State of all active sticky broadcasts per user.  Keys are the action of the
1019      * sticky Intent, values are an ArrayList of all broadcasted intents with
1020      * that action (which should usually be one).  The SparseArray is keyed
1021      * by the user ID the sticky is for, and can include UserHandle.USER_ALL
1022      * for stickies that are sent to all users.
1023      */
1024     final SparseArray<ArrayMap<String, ArrayList<Intent>>> mStickyBroadcasts =
1025             new SparseArray<ArrayMap<String, ArrayList<Intent>>>();
1026
1027     final ActiveServices mServices;
1028
1029     final static class Association {
1030         final int mSourceUid;
1031         final String mSourceProcess;
1032         final int mTargetUid;
1033         final ComponentName mTargetComponent;
1034         final String mTargetProcess;
1035
1036         int mCount;
1037         long mTime;
1038
1039         int mNesting;
1040         long mStartTime;
1041
1042         // states of the source process when the bind occurred.
1043         int mLastState = ActivityManager.MAX_PROCESS_STATE + 1;
1044         long mLastStateUptime;
1045         long[] mStateTimes = new long[ActivityManager.MAX_PROCESS_STATE
1046                 - ActivityManager.MIN_PROCESS_STATE+1];
1047
1048         Association(int sourceUid, String sourceProcess, int targetUid,
1049                 ComponentName targetComponent, String targetProcess) {
1050             mSourceUid = sourceUid;
1051             mSourceProcess = sourceProcess;
1052             mTargetUid = targetUid;
1053             mTargetComponent = targetComponent;
1054             mTargetProcess = targetProcess;
1055         }
1056     }
1057
1058     /**
1059      * When service association tracking is enabled, this is all of the associations we
1060      * have seen.  Mapping is target uid -> target component -> source uid -> source process name
1061      * -> association data.
1062      */
1063     final SparseArray<ArrayMap<ComponentName, SparseArray<ArrayMap<String, Association>>>>
1064             mAssociations = new SparseArray<>();
1065     boolean mTrackingAssociations;
1066
1067     /**
1068      * Backup/restore process management
1069      */
1070     String mBackupAppName = null;
1071     BackupRecord mBackupTarget = null;
1072
1073     final ProviderMap mProviderMap;
1074
1075     /**
1076      * List of content providers who have clients waiting for them.  The
1077      * application is currently being launched and the provider will be
1078      * removed from this list once it is published.
1079      */
1080     final ArrayList<ContentProviderRecord> mLaunchingProviders
1081             = new ArrayList<ContentProviderRecord>();
1082
1083     /**
1084      * File storing persisted {@link #mGrantedUriPermissions}.
1085      */
1086     private final AtomicFile mGrantFile;
1087
1088     /** XML constants used in {@link #mGrantFile} */
1089     private static final String TAG_URI_GRANTS = "uri-grants";
1090     private static final String TAG_URI_GRANT = "uri-grant";
1091     private static final String ATTR_USER_HANDLE = "userHandle";
1092     private static final String ATTR_SOURCE_USER_ID = "sourceUserId";
1093     private static final String ATTR_TARGET_USER_ID = "targetUserId";
1094     private static final String ATTR_SOURCE_PKG = "sourcePkg";
1095     private static final String ATTR_TARGET_PKG = "targetPkg";
1096     private static final String ATTR_URI = "uri";
1097     private static final String ATTR_MODE_FLAGS = "modeFlags";
1098     private static final String ATTR_CREATED_TIME = "createdTime";
1099     private static final String ATTR_PREFIX = "prefix";
1100
1101     /**
1102      * Global set of specific {@link Uri} permissions that have been granted.
1103      * This optimized lookup structure maps from {@link UriPermission#targetUid}
1104      * to {@link UriPermission#uri} to {@link UriPermission}.
1105      */
1106     @GuardedBy("this")
1107     private final SparseArray<ArrayMap<GrantUri, UriPermission>>
1108             mGrantedUriPermissions = new SparseArray<ArrayMap<GrantUri, UriPermission>>();
1109
1110     public static class GrantUri {
1111         public final int sourceUserId;
1112         public final Uri uri;
1113         public boolean prefix;
1114
1115         public GrantUri(int sourceUserId, Uri uri, boolean prefix) {
1116             this.sourceUserId = sourceUserId;
1117             this.uri = uri;
1118             this.prefix = prefix;
1119         }
1120
1121         @Override
1122         public int hashCode() {
1123             int hashCode = 1;
1124             hashCode = 31 * hashCode + sourceUserId;
1125             hashCode = 31 * hashCode + uri.hashCode();
1126             hashCode = 31 * hashCode + (prefix ? 1231 : 1237);
1127             return hashCode;
1128         }
1129
1130         @Override
1131         public boolean equals(Object o) {
1132             if (o instanceof GrantUri) {
1133                 GrantUri other = (GrantUri) o;
1134                 return uri.equals(other.uri) && (sourceUserId == other.sourceUserId)
1135                         && prefix == other.prefix;
1136             }
1137             return false;
1138         }
1139
1140         @Override
1141         public String toString() {
1142             String result = uri.toString() + " [user " + sourceUserId + "]";
1143             if (prefix) result += " [prefix]";
1144             return result;
1145         }
1146
1147         public String toSafeString() {
1148             String result = uri.toSafeString() + " [user " + sourceUserId + "]";
1149             if (prefix) result += " [prefix]";
1150             return result;
1151         }
1152
1153         public static GrantUri resolve(int defaultSourceUserHandle, Uri uri) {
1154             return new GrantUri(ContentProvider.getUserIdFromUri(uri, defaultSourceUserHandle),
1155                     ContentProvider.getUriWithoutUserId(uri), false);
1156         }
1157     }
1158
1159     CoreSettingsObserver mCoreSettingsObserver;
1160
1161     FontScaleSettingObserver mFontScaleSettingObserver;
1162
1163     private final class FontScaleSettingObserver extends ContentObserver {
1164         private final Uri mFontScaleUri = Settings.System.getUriFor(FONT_SCALE);
1165
1166         public FontScaleSettingObserver() {
1167             super(mHandler);
1168             ContentResolver resolver = mContext.getContentResolver();
1169             resolver.registerContentObserver(mFontScaleUri, false, this, UserHandle.USER_ALL);
1170         }
1171
1172         @Override
1173         public void onChange(boolean selfChange, Uri uri, @UserIdInt int userId) {
1174             if (mFontScaleUri.equals(uri)) {
1175                 updateFontScaleIfNeeded(userId);
1176             }
1177         }
1178     }
1179
1180     /**
1181      * Thread-local storage used to carry caller permissions over through
1182      * indirect content-provider access.
1183      */
1184     private class Identity {
1185         public final IBinder token;
1186         public final int pid;
1187         public final int uid;
1188
1189         Identity(IBinder _token, int _pid, int _uid) {
1190             token = _token;
1191             pid = _pid;
1192             uid = _uid;
1193         }
1194     }
1195
1196     private static final ThreadLocal<Identity> sCallerIdentity = new ThreadLocal<Identity>();
1197
1198     /**
1199      * All information we have collected about the runtime performance of
1200      * any user id that can impact battery performance.
1201      */
1202     final BatteryStatsService mBatteryStatsService;
1203
1204     /**
1205      * Information about component usage
1206      */
1207     UsageStatsManagerInternal mUsageStatsService;
1208
1209     /**
1210      * Access to DeviceIdleController service.
1211      */
1212     DeviceIdleController.LocalService mLocalDeviceIdleController;
1213
1214     /**
1215      * Set of app ids that are whitelisted for device idle and thus background check.
1216      */
1217     int[] mDeviceIdleWhitelist = new int[0];
1218
1219     /**
1220      * Set of app ids that are temporarily allowed to escape bg check due to high-pri message
1221      */
1222     int[] mDeviceIdleTempWhitelist = new int[0];
1223
1224     static final class PendingTempWhitelist {
1225         final int targetUid;
1226         final long duration;
1227         final String tag;
1228
1229         PendingTempWhitelist(int _targetUid, long _duration, String _tag) {
1230             targetUid = _targetUid;
1231             duration = _duration;
1232             tag = _tag;
1233         }
1234     }
1235
1236     final SparseArray<PendingTempWhitelist> mPendingTempWhitelist = new SparseArray<>();
1237
1238     /**
1239      * Information about and control over application operations
1240      */
1241     final AppOpsService mAppOpsService;
1242
1243     /** Current sequencing integer of the configuration, for skipping old configurations. */
1244     private int mConfigurationSeq;
1245
1246     /**
1247      * Temp object used when global and/or display override configuration is updated. It is also
1248      * sent to outer world instead of {@link #getGlobalConfiguration} because we don't trust
1249      * anyone...
1250      */
1251     private Configuration mTempConfig = new Configuration();
1252
1253     private final UpdateConfigurationResult mTmpUpdateConfigurationResult =
1254             new UpdateConfigurationResult();
1255     private static final class UpdateConfigurationResult {
1256         // Configuration changes that were updated.
1257         int changes;
1258         // If the activity was relaunched to match the new configuration.
1259         boolean activityRelaunched;
1260
1261         void reset() {
1262             changes = 0;
1263             activityRelaunched = false;
1264         }
1265     }
1266
1267     boolean mSuppressResizeConfigChanges;
1268
1269     /**
1270      * Hardware-reported OpenGLES version.
1271      */
1272     final int GL_ES_VERSION;
1273
1274     /**
1275      * List of initialization arguments to pass to all processes when binding applications to them.
1276      * For example, references to the commonly used services.
1277      */
1278     HashMap<String, IBinder> mAppBindArgs;
1279     HashMap<String, IBinder> mIsolatedAppBindArgs;
1280
1281     /**
1282      * Temporary to avoid allocations.  Protected by main lock.
1283      */
1284     final StringBuilder mStringBuilder = new StringBuilder(256);
1285
1286     /**
1287      * Used to control how we initialize the service.
1288      */
1289     ComponentName mTopComponent;
1290     String mTopAction = Intent.ACTION_MAIN;
1291     String mTopData;
1292
1293     volatile boolean mProcessesReady = false;
1294     volatile boolean mSystemReady = false;
1295     volatile boolean mOnBattery = false;
1296     volatile int mFactoryTest;
1297
1298     @GuardedBy("this") boolean mBooting = false;
1299     @GuardedBy("this") boolean mCallFinishBooting = false;
1300     @GuardedBy("this") boolean mBootAnimationComplete = false;
1301     @GuardedBy("this") boolean mLaunchWarningShown = false;
1302     @GuardedBy("this") boolean mCheckedForSetup = false;
1303
1304     final Context mContext;
1305
1306     /**
1307      * This Context is themable and meant for UI display (AlertDialogs, etc.). The theme can
1308      * change at runtime. Use mContext for non-UI purposes.
1309      */
1310     final Context mUiContext;
1311
1312     /**
1313      * The time at which we will allow normal application switches again,
1314      * after a call to {@link #stopAppSwitches()}.
1315      */
1316     long mAppSwitchesAllowedTime;
1317
1318     /**
1319      * This is set to true after the first switch after mAppSwitchesAllowedTime
1320      * is set; any switches after that will clear the time.
1321      */
1322     boolean mDidAppSwitch;
1323
1324     /**
1325      * Last time (in realtime) at which we checked for power usage.
1326      */
1327     long mLastPowerCheckRealtime;
1328
1329     /**
1330      * Last time (in uptime) at which we checked for power usage.
1331      */
1332     long mLastPowerCheckUptime;
1333
1334     /**
1335      * Set while we are wanting to sleep, to prevent any
1336      * activities from being started/resumed.
1337      *
1338      * TODO(b/33594039): Clarify the actual state transitions represented by mSleeping.
1339      *
1340      * Currently mSleeping is set to true when transitioning into the sleep state, and remains true
1341      * while in the sleep state until there is a pending transition out of sleep, in which case
1342      * mSleeping is set to false, and remains false while awake.
1343      *
1344      * Whether mSleeping can quickly toggled between true/false without the device actually
1345      * display changing states is undefined.
1346      */
1347     private boolean mSleeping = false;
1348
1349     /**
1350      * The process state used for processes that are running the top activities.
1351      * This changes between TOP and TOP_SLEEPING to following mSleeping.
1352      */
1353     int mTopProcessState = ActivityManager.PROCESS_STATE_TOP;
1354
1355     /**
1356      * Set while we are running a voice interaction.  This overrides
1357      * sleeping while it is active.
1358      */
1359     private IVoiceInteractionSession mRunningVoice;
1360
1361     /**
1362      * For some direct access we need to power manager.
1363      */
1364     PowerManagerInternal mLocalPowerManager;
1365
1366     /**
1367      * We want to hold a wake lock while running a voice interaction session, since
1368      * this may happen with the screen off and we need to keep the CPU running to
1369      * be able to continue to interact with the user.
1370      */
1371     PowerManager.WakeLock mVoiceWakeLock;
1372
1373     /**
1374      * State of external calls telling us if the device is awake or asleep.
1375      */
1376     private int mWakefulness = PowerManagerInternal.WAKEFULNESS_AWAKE;
1377
1378     /**
1379      * A list of tokens that cause the top activity to be put to sleep.
1380      * They are used by components that may hide and block interaction with underlying
1381      * activities.
1382      */
1383     final ArrayList<SleepToken> mSleepTokens = new ArrayList<SleepToken>();
1384
1385     /**
1386      * Set if we are shutting down the system, similar to sleeping.
1387      */
1388     boolean mShuttingDown = false;
1389
1390     /**
1391      * Current sequence id for oom_adj computation traversal.
1392      */
1393     int mAdjSeq = 0;
1394
1395     /**
1396      * Current sequence id for process LRU updating.
1397      */
1398     int mLruSeq = 0;
1399
1400     /**
1401      * Keep track of the non-cached/empty process we last found, to help
1402      * determine how to distribute cached/empty processes next time.
1403      */
1404     int mNumNonCachedProcs = 0;
1405
1406     /**
1407      * Keep track of the number of cached hidden procs, to balance oom adj
1408      * distribution between those and empty procs.
1409      */
1410     int mNumCachedHiddenProcs = 0;
1411
1412     /**
1413      * Keep track of the number of service processes we last found, to
1414      * determine on the next iteration which should be B services.
1415      */
1416     int mNumServiceProcs = 0;
1417     int mNewNumAServiceProcs = 0;
1418     int mNewNumServiceProcs = 0;
1419
1420     /**
1421      * Allow the current computed overall memory level of the system to go down?
1422      * This is set to false when we are killing processes for reasons other than
1423      * memory management, so that the now smaller process list will not be taken as
1424      * an indication that memory is tighter.
1425      */
1426     boolean mAllowLowerMemLevel = false;
1427
1428     /**
1429      * The last computed memory level, for holding when we are in a state that
1430      * processes are going away for other reasons.
1431      */
1432     int mLastMemoryLevel = ProcessStats.ADJ_MEM_FACTOR_NORMAL;
1433
1434     /**
1435      * The last total number of process we have, to determine if changes actually look
1436      * like a shrinking number of process due to lower RAM.
1437      */
1438     int mLastNumProcesses;
1439
1440     /**
1441      * The uptime of the last time we performed idle maintenance.
1442      */
1443     long mLastIdleTime = SystemClock.uptimeMillis();
1444
1445     /**
1446      * Total time spent with RAM that has been added in the past since the last idle time.
1447      */
1448     long mLowRamTimeSinceLastIdle = 0;
1449
1450     /**
1451      * If RAM is currently low, when that horrible situation started.
1452      */
1453     long mLowRamStartTime = 0;
1454
1455     /**
1456      * For reporting to battery stats the current top application.
1457      */
1458     private String mCurResumedPackage = null;
1459     private int mCurResumedUid = -1;
1460
1461     /**
1462      * For reporting to battery stats the apps currently running foreground
1463      * service.  The ProcessMap is package/uid tuples; each of these contain
1464      * an array of the currently foreground processes.
1465      */
1466     final ProcessMap<ArrayList<ProcessRecord>> mForegroundPackages
1467             = new ProcessMap<ArrayList<ProcessRecord>>();
1468
1469     /**
1470      * Set if the systemServer made a call to enterSafeMode.
1471      */
1472     boolean mSafeMode;
1473
1474     /**
1475      * If true, we are running under a test environment so will sample PSS from processes
1476      * much more rapidly to try to collect better data when the tests are rapidly
1477      * running through apps.
1478      */
1479     boolean mTestPssMode = false;
1480
1481     String mDebugApp = null;
1482     boolean mWaitForDebugger = false;
1483     boolean mDebugTransient = false;
1484     String mOrigDebugApp = null;
1485     boolean mOrigWaitForDebugger = false;
1486     boolean mAlwaysFinishActivities = false;
1487     boolean mForceResizableActivities;
1488     /**
1489      * Flag that indicates if multi-window is enabled.
1490      *
1491      * For any particular form of multi-window to be enabled, generic multi-window must be enabled
1492      * in {@link com.android.internal.R.bool.config_supportsMultiWindow} config or
1493      * {@link Settings.Global#DEVELOPMENT_FORCE_RESIZABLE_ACTIVITIES} development option set.
1494      * At least one of the forms of multi-window must be enabled in order for this flag to be
1495      * initialized to 'true'.
1496      *
1497      * @see #mSupportsSplitScreenMultiWindow
1498      * @see #mSupportsFreeformWindowManagement
1499      * @see #mSupportsPictureInPicture
1500      * @see #mSupportsMultiDisplay
1501      */
1502     boolean mSupportsMultiWindow;
1503     boolean mSupportsSplitScreenMultiWindow;
1504     boolean mSupportsFreeformWindowManagement;
1505     boolean mSupportsPictureInPicture;
1506     boolean mSupportsMultiDisplay;
1507     boolean mSupportsLeanbackOnly;
1508     IActivityController mController = null;
1509     boolean mControllerIsAMonkey = false;
1510     String mProfileApp = null;
1511     ProcessRecord mProfileProc = null;
1512     String mProfileFile;
1513     ParcelFileDescriptor mProfileFd;
1514     int mSamplingInterval = 0;
1515     boolean mAutoStopProfiler = false;
1516     boolean mStreamingOutput = false;
1517     int mProfileType = 0;
1518     final ProcessMap<Pair<Long, String>> mMemWatchProcesses = new ProcessMap<>();
1519     String mMemWatchDumpProcName;
1520     String mMemWatchDumpFile;
1521     int mMemWatchDumpPid;
1522     int mMemWatchDumpUid;
1523     String mTrackAllocationApp = null;
1524     String mNativeDebuggingApp = null;
1525
1526     final long[] mTmpLong = new long[2];
1527
1528     private final ArraySet<BroadcastQueue> mTmpBroadcastQueue = new ArraySet();
1529
1530     /**
1531      * A global counter for generating sequence numbers.
1532      * This value will be used when incrementing sequence numbers in individual uidRecords.
1533      *
1534      * Having a global counter ensures that seq numbers are monotonically increasing for a
1535      * particular uid even when the uidRecord is re-created.
1536      */
1537     @GuardedBy("this")
1538     @VisibleForTesting
1539     long mProcStateSeqCounter = 0;
1540
1541     private final Injector mInjector;
1542
1543     static final class ProcessChangeItem {
1544         static final int CHANGE_ACTIVITIES = 1<<0;
1545         int changes;
1546         int uid;
1547         int pid;
1548         int processState;
1549         boolean foregroundActivities;
1550     }
1551
1552     static final class UidObserverRegistration {
1553         final int uid;
1554         final String pkg;
1555         final int which;
1556         final int cutpoint;
1557
1558         final SparseIntArray lastProcStates;
1559
1560         UidObserverRegistration(int _uid, String _pkg, int _which, int _cutpoint) {
1561             uid = _uid;
1562             pkg = _pkg;
1563             which = _which;
1564             cutpoint = _cutpoint;
1565             if (cutpoint >= ActivityManager.MIN_PROCESS_STATE) {
1566                 lastProcStates = new SparseIntArray();
1567             } else {
1568                 lastProcStates = null;
1569             }
1570         }
1571     }
1572
1573     final RemoteCallbackList<IProcessObserver> mProcessObservers = new RemoteCallbackList<>();
1574     ProcessChangeItem[] mActiveProcessChanges = new ProcessChangeItem[5];
1575
1576     final ArrayList<ProcessChangeItem> mPendingProcessChanges = new ArrayList<>();
1577     final ArrayList<ProcessChangeItem> mAvailProcessChanges = new ArrayList<>();
1578
1579     final RemoteCallbackList<IUidObserver> mUidObservers = new RemoteCallbackList<>();
1580     UidRecord.ChangeItem[] mActiveUidChanges = new UidRecord.ChangeItem[5];
1581
1582     final ArrayList<UidRecord.ChangeItem> mPendingUidChanges = new ArrayList<>();
1583     final ArrayList<UidRecord.ChangeItem> mAvailUidChanges = new ArrayList<>();
1584
1585     /**
1586      * Runtime CPU use collection thread.  This object's lock is used to
1587      * perform synchronization with the thread (notifying it to run).
1588      */
1589     final Thread mProcessCpuThread;
1590
1591     /**
1592      * Used to collect per-process CPU use for ANRs, battery stats, etc.
1593      * Must acquire this object's lock when accessing it.
1594      * NOTE: this lock will be held while doing long operations (trawling
1595      * through all processes in /proc), so it should never be acquired by
1596      * any critical paths such as when holding the main activity manager lock.
1597      */
1598     final ProcessCpuTracker mProcessCpuTracker = new ProcessCpuTracker(
1599             MONITOR_THREAD_CPU_USAGE);
1600     final AtomicLong mLastCpuTime = new AtomicLong(0);
1601     final AtomicBoolean mProcessCpuMutexFree = new AtomicBoolean(true);
1602     final CountDownLatch mProcessCpuInitLatch = new CountDownLatch(1);
1603
1604     long mLastWriteTime = 0;
1605
1606     /**
1607      * Used to retain an update lock when the foreground activity is in
1608      * immersive mode.
1609      */
1610     final UpdateLock mUpdateLock = new UpdateLock("immersive");
1611
1612     /**
1613      * Set to true after the system has finished booting.
1614      */
1615     boolean mBooted = false;
1616
1617     WindowManagerService mWindowManager;
1618     final ActivityThread mSystemThread;
1619
1620     private final class AppDeathRecipient implements IBinder.DeathRecipient {
1621         final ProcessRecord mApp;
1622         final int mPid;
1623         final IApplicationThread mAppThread;
1624
1625         AppDeathRecipient(ProcessRecord app, int pid,
1626                 IApplicationThread thread) {
1627             if (DEBUG_ALL) Slog.v(
1628                 TAG, "New death recipient " + this
1629                 + " for thread " + thread.asBinder());
1630             mApp = app;
1631             mPid = pid;
1632             mAppThread = thread;
1633         }
1634
1635         @Override
1636         public void binderDied() {
1637             if (DEBUG_ALL) Slog.v(
1638                 TAG, "Death received in " + this
1639                 + " for thread " + mAppThread.asBinder());
1640             synchronized(ActivityManagerService.this) {
1641                 appDiedLocked(mApp, mPid, mAppThread, true);
1642             }
1643         }
1644     }
1645
1646     static final int SHOW_ERROR_UI_MSG = 1;
1647     static final int SHOW_NOT_RESPONDING_UI_MSG = 2;
1648     static final int SHOW_FACTORY_ERROR_UI_MSG = 3;
1649     static final int UPDATE_CONFIGURATION_MSG = 4;
1650     static final int GC_BACKGROUND_PROCESSES_MSG = 5;
1651     static final int WAIT_FOR_DEBUGGER_UI_MSG = 6;
1652     static final int SERVICE_TIMEOUT_MSG = 12;
1653     static final int UPDATE_TIME_ZONE = 13;
1654     static final int SHOW_UID_ERROR_UI_MSG = 14;
1655     static final int SHOW_FINGERPRINT_ERROR_UI_MSG = 15;
1656     static final int PROC_START_TIMEOUT_MSG = 20;
1657     static final int DO_PENDING_ACTIVITY_LAUNCHES_MSG = 21;
1658     static final int KILL_APPLICATION_MSG = 22;
1659     static final int FINALIZE_PENDING_INTENT_MSG = 23;
1660     static final int POST_HEAVY_NOTIFICATION_MSG = 24;
1661     static final int CANCEL_HEAVY_NOTIFICATION_MSG = 25;
1662     static final int SHOW_STRICT_MODE_VIOLATION_UI_MSG = 26;
1663     static final int CHECK_EXCESSIVE_WAKE_LOCKS_MSG = 27;
1664     static final int CLEAR_DNS_CACHE_MSG = 28;
1665     static final int UPDATE_HTTP_PROXY_MSG = 29;
1666     static final int SHOW_COMPAT_MODE_DIALOG_UI_MSG = 30;
1667     static final int DISPATCH_PROCESSES_CHANGED_UI_MSG = 31;
1668     static final int DISPATCH_PROCESS_DIED_UI_MSG = 32;
1669     static final int REPORT_MEM_USAGE_MSG = 33;
1670     static final int REPORT_USER_SWITCH_MSG = 34;
1671     static final int CONTINUE_USER_SWITCH_MSG = 35;
1672     static final int USER_SWITCH_TIMEOUT_MSG = 36;
1673     static final int IMMERSIVE_MODE_LOCK_MSG = 37;
1674     static final int PERSIST_URI_GRANTS_MSG = 38;
1675     static final int REQUEST_ALL_PSS_MSG = 39;
1676     static final int START_PROFILES_MSG = 40;
1677     static final int UPDATE_TIME_PREFERENCE_MSG = 41;
1678     static final int SYSTEM_USER_START_MSG = 42;
1679     static final int SYSTEM_USER_CURRENT_MSG = 43;
1680     static final int ENTER_ANIMATION_COMPLETE_MSG = 44;
1681     static final int FINISH_BOOTING_MSG = 45;
1682     static final int START_USER_SWITCH_UI_MSG = 46;
1683     static final int SEND_LOCALE_TO_MOUNT_DAEMON_MSG = 47;
1684     static final int DISMISS_DIALOG_UI_MSG = 48;
1685     static final int NOTIFY_CLEARTEXT_NETWORK_MSG = 49;
1686     static final int POST_DUMP_HEAP_NOTIFICATION_MSG = 50;
1687     static final int DELETE_DUMPHEAP_MSG = 51;
1688     static final int FOREGROUND_PROFILE_CHANGED_MSG = 52;
1689     static final int DISPATCH_UIDS_CHANGED_UI_MSG = 53;
1690     static final int REPORT_TIME_TRACKER_MSG = 54;
1691     static final int REPORT_USER_SWITCH_COMPLETE_MSG = 55;
1692     static final int SHUTDOWN_UI_AUTOMATION_CONNECTION_MSG = 56;
1693     static final int CONTENT_PROVIDER_PUBLISH_TIMEOUT_MSG = 57;
1694     static final int IDLE_UIDS_MSG = 58;
1695     static final int SYSTEM_USER_UNLOCK_MSG = 59;
1696     static final int LOG_STACK_STATE = 60;
1697     static final int VR_MODE_CHANGE_MSG = 61;
1698     static final int SHOW_UNSUPPORTED_DISPLAY_SIZE_DIALOG_MSG = 62;
1699     static final int HANDLE_TRUST_STORAGE_UPDATE_MSG = 63;
1700     static final int REPORT_LOCKED_BOOT_COMPLETE_MSG = 64;
1701     static final int NOTIFY_VR_SLEEPING_MSG = 65;
1702     static final int SERVICE_FOREGROUND_TIMEOUT_MSG = 66;
1703     static final int DISPATCH_PENDING_INTENT_CANCEL_MSG = 67;
1704     static final int PUSH_TEMP_WHITELIST_UI_MSG = 68;
1705     static final int SERVICE_FOREGROUND_CRASH_MSG = 69;
1706     static final int START_USER_SWITCH_FG_MSG = 712;
1707
1708     static final int FIRST_ACTIVITY_STACK_MSG = 100;
1709     static final int FIRST_BROADCAST_QUEUE_MSG = 200;
1710     static final int FIRST_COMPAT_MODE_MSG = 300;
1711     static final int FIRST_SUPERVISOR_STACK_MSG = 100;
1712
1713     static ServiceThread sKillThread = null;
1714     static KillHandler sKillHandler = null;
1715
1716     CompatModeDialog mCompatModeDialog;
1717     UnsupportedDisplaySizeDialog mUnsupportedDisplaySizeDialog;
1718     long mLastMemUsageReportTime = 0;
1719
1720     /**
1721      * Flag whether the current user is a "monkey", i.e. whether
1722      * the UI is driven by a UI automation tool.
1723      */
1724     private boolean mUserIsMonkey;
1725
1726     /** Flag whether the device has a Recents UI */
1727     boolean mHasRecents;
1728
1729     /** The dimensions of the thumbnails in the Recents UI. */
1730     int mThumbnailWidth;
1731     int mThumbnailHeight;
1732     float mFullscreenThumbnailScale;
1733
1734     final ServiceThread mHandlerThread;
1735     final MainHandler mHandler;
1736     final Handler mUiHandler;
1737
1738     final ActivityManagerConstants mConstants;
1739
1740     PackageManagerInternal mPackageManagerInt;
1741
1742     // VoiceInteraction session ID that changes for each new request except when
1743     // being called for multiwindow assist in a single session.
1744     private int mViSessionId = 1000;
1745
1746     final boolean mPermissionReviewRequired;
1747
1748     /**
1749      * Current global configuration information. Contains general settings for the entire system,
1750      * also corresponds to the merged configuration of the default display.
1751      */
1752     Configuration getGlobalConfiguration() {
1753         return mStackSupervisor.getConfiguration();
1754     }
1755
1756     final class KillHandler extends Handler {
1757         static final int KILL_PROCESS_GROUP_MSG = 4000;
1758
1759         public KillHandler(Looper looper) {
1760             super(looper, null, true);
1761         }
1762
1763         @Override
1764         public void handleMessage(Message msg) {
1765             switch (msg.what) {
1766                 case KILL_PROCESS_GROUP_MSG:
1767                 {
1768                     Trace.traceBegin(Trace.TRACE_TAG_ACTIVITY_MANAGER, "killProcessGroup");
1769                     Process.killProcessGroup(msg.arg1 /* uid */, msg.arg2 /* pid */);
1770                     Trace.traceEnd(Trace.TRACE_TAG_ACTIVITY_MANAGER);
1771                 }
1772                 break;
1773
1774                 default:
1775                     super.handleMessage(msg);
1776             }
1777         }
1778     }
1779
1780     final class UiHandler extends Handler {
1781         public UiHandler() {
1782             super(com.android.server.UiThread.get().getLooper(), null, true);
1783         }
1784
1785         @Override
1786         public void handleMessage(Message msg) {
1787             switch (msg.what) {
1788             case SHOW_ERROR_UI_MSG: {
1789                 mAppErrors.handleShowAppErrorUi(msg);
1790                 ensureBootCompleted();
1791             } break;
1792             case SHOW_NOT_RESPONDING_UI_MSG: {
1793                 mAppErrors.handleShowAnrUi(msg);
1794                 ensureBootCompleted();
1795             } break;
1796             case SHOW_STRICT_MODE_VIOLATION_UI_MSG: {
1797                 HashMap<String, Object> data = (HashMap<String, Object>) msg.obj;
1798                 synchronized (ActivityManagerService.this) {
1799                     ProcessRecord proc = (ProcessRecord) data.get("app");
1800                     if (proc == null) {
1801                         Slog.e(TAG, "App not found when showing strict mode dialog.");
1802                         break;
1803                     }
1804                     if (proc.crashDialog != null) {
1805                         Slog.e(TAG, "App already has strict mode dialog: " + proc);
1806                         return;
1807                     }
1808                     AppErrorResult res = (AppErrorResult) data.get("result");
1809                     if (mShowDialogs && !mSleeping && !mShuttingDown) {
1810                         Dialog d = new StrictModeViolationDialog(mUiContext,
1811                                 ActivityManagerService.this, res, proc);
1812                         d.show();
1813                         proc.crashDialog = d;
1814                     } else {
1815                         // The device is asleep, so just pretend that the user
1816                         // saw a crash dialog and hit "force quit".
1817                         res.set(0);
1818                     }
1819                 }
1820                 ensureBootCompleted();
1821             } break;
1822             case SHOW_FACTORY_ERROR_UI_MSG: {
1823                 Dialog d = new FactoryErrorDialog(
1824                         mUiContext, msg.getData().getCharSequence("msg"));
1825                 d.show();
1826                 ensureBootCompleted();
1827             } break;
1828             case WAIT_FOR_DEBUGGER_UI_MSG: {
1829                 synchronized (ActivityManagerService.this) {
1830                     ProcessRecord app = (ProcessRecord)msg.obj;
1831                     if (msg.arg1 != 0) {
1832                         if (!app.waitedForDebugger) {
1833                             Dialog d = new AppWaitingForDebuggerDialog(
1834                                     ActivityManagerService.this,
1835                                     mUiContext, app);
1836                             app.waitDialog = d;
1837                             app.waitedForDebugger = true;
1838                             d.show();
1839                         }
1840                     } else {
1841                         if (app.waitDialog != null) {
1842                             app.waitDialog.dismiss();
1843                             app.waitDialog = null;
1844                         }
1845                     }
1846                 }
1847             } break;
1848             case SHOW_UID_ERROR_UI_MSG: {
1849                 if (mShowDialogs) {
1850                     AlertDialog d = new BaseErrorDialog(mUiContext);
1851                     d.getWindow().setType(WindowManager.LayoutParams.TYPE_SYSTEM_ERROR);
1852                     d.setCancelable(false);
1853                     d.setTitle(mUiContext.getText(R.string.android_system_label));
1854                     d.setMessage(mUiContext.getText(R.string.system_error_wipe_data));
1855                     d.setButton(DialogInterface.BUTTON_POSITIVE, mUiContext.getText(R.string.ok),
1856                             obtainMessage(DISMISS_DIALOG_UI_MSG, d));
1857                     d.show();
1858                 }
1859             } break;
1860             case SHOW_FINGERPRINT_ERROR_UI_MSG: {
1861                 if (mShowDialogs) {
1862                     AlertDialog d = new BaseErrorDialog(mUiContext);
1863                     d.getWindow().setType(WindowManager.LayoutParams.TYPE_SYSTEM_ERROR);
1864                     d.setCancelable(false);
1865                     d.setTitle(mUiContext.getText(R.string.android_system_label));
1866                     d.setMessage(mUiContext.getText(R.string.system_error_manufacturer));
1867                     d.setButton(DialogInterface.BUTTON_POSITIVE, mUiContext.getText(R.string.ok),
1868                             obtainMessage(DISMISS_DIALOG_UI_MSG, d));
1869                     d.show();
1870                 }
1871             } break;
1872             case SHOW_COMPAT_MODE_DIALOG_UI_MSG: {
1873                 synchronized (ActivityManagerService.this) {
1874                     ActivityRecord ar = (ActivityRecord) msg.obj;
1875                     if (mCompatModeDialog != null) {
1876                         if (mCompatModeDialog.mAppInfo.packageName.equals(
1877                                 ar.info.applicationInfo.packageName)) {
1878                             return;
1879                         }
1880                         mCompatModeDialog.dismiss();
1881                         mCompatModeDialog = null;
1882                     }
1883                     if (ar != null && false) {
1884                         if (mCompatModePackages.getPackageAskCompatModeLocked(
1885                                 ar.packageName)) {
1886                             int mode = mCompatModePackages.computeCompatModeLocked(
1887                                     ar.info.applicationInfo);
1888                             if (mode == ActivityManager.COMPAT_MODE_DISABLED
1889                                     || mode == ActivityManager.COMPAT_MODE_ENABLED) {
1890                                 mCompatModeDialog = new CompatModeDialog(
1891                                         ActivityManagerService.this, mUiContext,
1892                                         ar.info.applicationInfo);
1893                                 mCompatModeDialog.show();
1894                             }
1895                         }
1896                     }
1897                 }
1898                 break;
1899             }
1900             case SHOW_UNSUPPORTED_DISPLAY_SIZE_DIALOG_MSG: {
1901                 synchronized (ActivityManagerService.this) {
1902                     final ActivityRecord ar = (ActivityRecord) msg.obj;
1903                     if (mUnsupportedDisplaySizeDialog != null) {
1904                         mUnsupportedDisplaySizeDialog.dismiss();
1905                         mUnsupportedDisplaySizeDialog = null;
1906                     }
1907                     if (ar != null && mCompatModePackages.getPackageNotifyUnsupportedZoomLocked(
1908                             ar.packageName)) {
1909                         // TODO(multi-display): Show dialog on appropriate display.
1910                         mUnsupportedDisplaySizeDialog = new UnsupportedDisplaySizeDialog(
1911                                 ActivityManagerService.this, mUiContext, ar.info.applicationInfo);
1912                         mUnsupportedDisplaySizeDialog.show();
1913                     }
1914                 }
1915                 break;
1916             }
1917             case START_USER_SWITCH_UI_MSG: {
1918                 mUserController.showUserSwitchDialog((Pair<UserInfo, UserInfo>) msg.obj);
1919                 break;
1920             }
1921             case DISMISS_DIALOG_UI_MSG: {
1922                 final Dialog d = (Dialog) msg.obj;
1923                 d.dismiss();
1924                 break;
1925             }
1926             case DISPATCH_PROCESSES_CHANGED_UI_MSG: {
1927                 dispatchProcessesChanged();
1928                 break;
1929             }
1930             case DISPATCH_PROCESS_DIED_UI_MSG: {
1931                 final int pid = msg.arg1;
1932                 final int uid = msg.arg2;
1933                 dispatchProcessDied(pid, uid);
1934                 break;
1935             }
1936             case DISPATCH_UIDS_CHANGED_UI_MSG: {
1937                 dispatchUidsChanged();
1938             } break;
1939             case PUSH_TEMP_WHITELIST_UI_MSG: {
1940                 pushTempWhitelist();
1941             } break;
1942             }
1943         }
1944     }
1945
1946     final class MainHandler extends Handler {
1947         public MainHandler(Looper looper) {
1948             super(looper, null, true);
1949         }
1950
1951         @Override
1952         public void handleMessage(Message msg) {
1953             switch (msg.what) {
1954             case UPDATE_CONFIGURATION_MSG: {
1955                 final ContentResolver resolver = mContext.getContentResolver();
1956                 Settings.System.putConfigurationForUser(resolver, (Configuration) msg.obj,
1957                         msg.arg1);
1958             } break;
1959             case GC_BACKGROUND_PROCESSES_MSG: {
1960                 synchronized (ActivityManagerService.this) {
1961                     performAppGcsIfAppropriateLocked();
1962                 }
1963             } break;
1964             case SERVICE_TIMEOUT_MSG: {
1965                 mServices.serviceTimeout((ProcessRecord)msg.obj);
1966             } break;
1967             case SERVICE_FOREGROUND_TIMEOUT_MSG: {
1968                 mServices.serviceForegroundTimeout((ServiceRecord)msg.obj);
1969             } break;
1970             case SERVICE_FOREGROUND_CRASH_MSG: {
1971                 mServices.serviceForegroundCrash((ProcessRecord)msg.obj);
1972             } break;
1973             case DISPATCH_PENDING_INTENT_CANCEL_MSG: {
1974                 RemoteCallbackList<IResultReceiver> callbacks
1975                         = (RemoteCallbackList<IResultReceiver>)msg.obj;
1976                 int N = callbacks.beginBroadcast();
1977                 for (int i = 0; i < N; i++) {
1978                     try {
1979                         callbacks.getBroadcastItem(i).send(Activity.RESULT_CANCELED, null);
1980                     } catch (RemoteException e) {
1981                     }
1982                 }
1983                 callbacks.finishBroadcast();
1984             } break;
1985             case UPDATE_TIME_ZONE: {
1986                 synchronized (ActivityManagerService.this) {
1987                     for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) {
1988                         ProcessRecord r = mLruProcesses.get(i);
1989                         if (r.thread != null) {
1990                             try {
1991                                 r.thread.updateTimeZone();
1992                             } catch (RemoteException ex) {
1993                                 Slog.w(TAG, "Failed to update time zone for: " + r.info.processName);
1994                             }
1995                         }
1996                     }
1997                 }
1998             } break;
1999             case CLEAR_DNS_CACHE_MSG: {
2000                 synchronized (ActivityManagerService.this) {
2001                     for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) {
2002                         ProcessRecord r = mLruProcesses.get(i);
2003                         if (r.thread != null) {
2004                             try {
2005                                 r.thread.clearDnsCache();
2006                             } catch (RemoteException ex) {
2007                                 Slog.w(TAG, "Failed to clear dns cache for: " + r.info.processName);
2008                             }
2009                         }
2010                     }
2011                 }
2012             } break;
2013             case UPDATE_HTTP_PROXY_MSG: {
2014                 ProxyInfo proxy = (ProxyInfo)msg.obj;
2015                 String host = "";
2016                 String port = "";
2017                 String exclList = "";
2018                 Uri pacFileUrl = Uri.EMPTY;
2019                 if (proxy != null) {
2020                     host = proxy.getHost();
2021                     port = Integer.toString(proxy.getPort());
2022                     exclList = proxy.getExclusionListAsString();
2023                     pacFileUrl = proxy.getPacFileUrl();
2024                 }
2025                 synchronized (ActivityManagerService.this) {
2026                     for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) {
2027                         ProcessRecord r = mLruProcesses.get(i);
2028                         if (r.thread != null) {
2029                             try {
2030                                 r.thread.setHttpProxy(host, port, exclList, pacFileUrl);
2031                             } catch (RemoteException ex) {
2032                                 Slog.w(TAG, "Failed to update http proxy for: " +
2033                                         r.info.processName);
2034                             }
2035                         }
2036                     }
2037                 }
2038             } break;
2039             case PROC_START_TIMEOUT_MSG: {
2040                 ProcessRecord app = (ProcessRecord)msg.obj;
2041                 synchronized (ActivityManagerService.this) {
2042                     processStartTimedOutLocked(app);
2043                 }
2044             } break;
2045             case CONTENT_PROVIDER_PUBLISH_TIMEOUT_MSG: {
2046                 ProcessRecord app = (ProcessRecord)msg.obj;
2047                 synchronized (ActivityManagerService.this) {
2048                     processContentProviderPublishTimedOutLocked(app);
2049                 }
2050             } break;
2051             case DO_PENDING_ACTIVITY_LAUNCHES_MSG: {
2052                 synchronized (ActivityManagerService.this) {
2053                     mActivityStarter.doPendingActivityLaunchesLocked(true);
2054                 }
2055             } break;
2056             case KILL_APPLICATION_MSG: {
2057                 synchronized (ActivityManagerService.this) {
2058                     final int appId = msg.arg1;
2059                     final int userId = msg.arg2;
2060                     Bundle bundle = (Bundle)msg.obj;
2061                     String pkg = bundle.getString("pkg");
2062                     String reason = bundle.getString("reason");
2063                     forceStopPackageLocked(pkg, appId, false, false, true, false,
2064                             false, userId, reason);
2065                 }
2066             } break;
2067             case FINALIZE_PENDING_INTENT_MSG: {
2068                 ((PendingIntentRecord)msg.obj).completeFinalize();
2069             } break;
2070             case POST_HEAVY_NOTIFICATION_MSG: {
2071                 INotificationManager inm = NotificationManager.getService();
2072                 if (inm == null) {
2073                     return;
2074                 }
2075
2076                 ActivityRecord root = (ActivityRecord)msg.obj;
2077                 ProcessRecord process = root.app;
2078                 if (process == null) {
2079                     return;
2080                 }
2081
2082                 try {
2083                     Context context = mContext.createPackageContext(process.info.packageName, 0);
2084                     String text = mContext.getString(R.string.heavy_weight_notification,
2085                             context.getApplicationInfo().loadLabel(context.getPackageManager()));
2086                     Notification notification =
2087                             new Notification.Builder(context, SystemNotificationChannels.DEVELOPER)
2088                             .setSmallIcon(com.android.internal.R.drawable.stat_sys_adb)
2089                             .setWhen(0)
2090                             .setOngoing(true)
2091                             .setTicker(text)
2092                             .setColor(mContext.getColor(
2093                                     com.android.internal.R.color.system_notification_accent_color))
2094                             .setContentTitle(text)
2095                             .setContentText(
2096                                     mContext.getText(R.string.heavy_weight_notification_detail))
2097                             .setContentIntent(PendingIntent.getActivityAsUser(mContext, 0,
2098                                     root.intent, PendingIntent.FLAG_CANCEL_CURRENT, null,
2099                                     new UserHandle(root.userId)))
2100                             .build();
2101                     try {
2102                         inm.enqueueNotificationWithTag("android", "android", null,
2103                                 SystemMessage.NOTE_HEAVY_WEIGHT_NOTIFICATION,
2104                                 notification, root.userId);
2105                     } catch (RuntimeException e) {
2106                         Slog.w(ActivityManagerService.TAG,
2107                                 "Error showing notification for heavy-weight app", e);
2108                     } catch (RemoteException e) {
2109                     }
2110                 } catch (NameNotFoundException e) {
2111                     Slog.w(TAG, "Unable to create context for heavy notification", e);
2112                 }
2113             } break;
2114             case CANCEL_HEAVY_NOTIFICATION_MSG: {
2115                 INotificationManager inm = NotificationManager.getService();
2116                 if (inm == null) {
2117                     return;
2118                 }
2119                 try {
2120                     inm.cancelNotificationWithTag("android", null,
2121                             SystemMessage.NOTE_HEAVY_WEIGHT_NOTIFICATION,  msg.arg1);
2122                 } catch (RuntimeException e) {
2123                     Slog.w(ActivityManagerService.TAG,
2124                             "Error canceling notification for service", e);
2125                 } catch (RemoteException e) {
2126                 }
2127             } break;
2128             case CHECK_EXCESSIVE_WAKE_LOCKS_MSG: {
2129                 synchronized (ActivityManagerService.this) {
2130                     checkExcessivePowerUsageLocked(true);
2131                     removeMessages(CHECK_EXCESSIVE_WAKE_LOCKS_MSG);
2132                     Message nmsg = obtainMessage(CHECK_EXCESSIVE_WAKE_LOCKS_MSG);
2133                     sendMessageDelayed(nmsg, mConstants.POWER_CHECK_DELAY);
2134                 }
2135             } break;
2136             case REPORT_MEM_USAGE_MSG: {
2137                 final ArrayList<ProcessMemInfo> memInfos = (ArrayList<ProcessMemInfo>)msg.obj;
2138                 Thread thread = new Thread() {
2139                     @Override public void run() {
2140                         reportMemUsage(memInfos);
2141                     }
2142                 };
2143                 thread.start();
2144                 break;
2145             }
2146             case START_USER_SWITCH_FG_MSG: {
2147                 mUserController.startUserInForeground(msg.arg1);
2148                 break;
2149             }
2150             case REPORT_USER_SWITCH_MSG: {
2151                 mUserController.dispatchUserSwitch((UserState) msg.obj, msg.arg1, msg.arg2);
2152                 break;
2153             }
2154             case CONTINUE_USER_SWITCH_MSG: {
2155                 mUserController.continueUserSwitch((UserState) msg.obj, msg.arg1, msg.arg2);
2156                 break;
2157             }
2158             case USER_SWITCH_TIMEOUT_MSG: {
2159                 mUserController.timeoutUserSwitch((UserState) msg.obj, msg.arg1, msg.arg2);
2160                 break;
2161             }
2162             case IMMERSIVE_MODE_LOCK_MSG: {
2163                 final boolean nextState = (msg.arg1 != 0);
2164                 if (mUpdateLock.isHeld() != nextState) {
2165                     if (DEBUG_IMMERSIVE) Slog.d(TAG_IMMERSIVE,
2166                             "Applying new update lock state '" + nextState
2167                             + "' for " + (ActivityRecord)msg.obj);
2168                     if (nextState) {
2169                         mUpdateLock.acquire();
2170                     } else {
2171                         mUpdateLock.release();
2172                     }
2173                 }
2174                 break;
2175             }
2176             case PERSIST_URI_GRANTS_MSG: {
2177                 writeGrantedUriPermissions();
2178                 break;
2179             }
2180             case REQUEST_ALL_PSS_MSG: {
2181                 synchronized (ActivityManagerService.this) {
2182                     requestPssAllProcsLocked(SystemClock.uptimeMillis(), true, false);
2183                 }
2184                 break;
2185             }
2186             case START_PROFILES_MSG: {
2187                 synchronized (ActivityManagerService.this) {
2188                     mUserController.startProfilesLocked();
2189                 }
2190                 break;
2191             }
2192             case UPDATE_TIME_PREFERENCE_MSG: {
2193                 // The user's time format preference might have changed.
2194                 // For convenience we re-use the Intent extra values.
2195                 synchronized (ActivityManagerService.this) {
2196                     for (int i = mLruProcesses.size() - 1; i >= 0; i--) {
2197                         ProcessRecord r = mLruProcesses.get(i);
2198                         if (r.thread != null) {
2199                             try {
2200                                 r.thread.updateTimePrefs(msg.arg1);
2201                             } catch (RemoteException ex) {
2202                                 Slog.w(TAG, "Failed to update preferences for: "
2203                                         + r.info.processName);
2204                             }
2205                         }
2206                     }
2207                 }
2208                 break;
2209             }
2210             case SYSTEM_USER_START_MSG: {
2211                 mBatteryStatsService.noteEvent(BatteryStats.HistoryItem.EVENT_USER_RUNNING_START,
2212                         Integer.toString(msg.arg1), msg.arg1);
2213                 mSystemServiceManager.startUser(msg.arg1);
2214                 break;
2215             }
2216             case SYSTEM_USER_UNLOCK_MSG: {
2217                 final int userId = msg.arg1;
2218                 mSystemServiceManager.unlockUser(userId);
2219                 synchronized (ActivityManagerService.this) {
2220                     mRecentTasks.loadUserRecentsLocked(userId);
2221                 }
2222                 if (userId == UserHandle.USER_SYSTEM) {
2223                     startPersistentApps(PackageManager.MATCH_DIRECT_BOOT_UNAWARE);
2224                 }
2225                 installEncryptionUnawareProviders(userId);
2226                 mUserController.finishUserUnlocked((UserState) msg.obj);
2227                 break;
2228             }
2229             case SYSTEM_USER_CURRENT_MSG: {
2230                 mBatteryStatsService.noteEvent(
2231                         BatteryStats.HistoryItem.EVENT_USER_FOREGROUND_FINISH,
2232                         Integer.toString(msg.arg2), msg.arg2);
2233                 mBatteryStatsService.noteEvent(
2234                         BatteryStats.HistoryItem.EVENT_USER_FOREGROUND_START,
2235                         Integer.toString(msg.arg1), msg.arg1);
2236                 mSystemServiceManager.switchUser(msg.arg1);
2237                 break;
2238             }
2239             case ENTER_ANIMATION_COMPLETE_MSG: {
2240                 synchronized (ActivityManagerService.this) {
2241                     ActivityRecord r = ActivityRecord.forTokenLocked((IBinder) msg.obj);
2242                     if (r != null && r.app != null && r.app.thread != null) {
2243                         try {
2244                             r.app.thread.scheduleEnterAnimationComplete(r.appToken);
2245                         } catch (RemoteException e) {
2246                         }
2247                     }
2248                 }
2249                 break;
2250             }
2251             case FINISH_BOOTING_MSG: {
2252                 if (msg.arg1 != 0) {
2253                     Trace.traceBegin(Trace.TRACE_TAG_ACTIVITY_MANAGER, "FinishBooting");
2254                     finishBooting();
2255                     Trace.traceEnd(Trace.TRACE_TAG_ACTIVITY_MANAGER);
2256                 }
2257                 if (msg.arg2 != 0) {
2258                     enableScreenAfterBoot();
2259                 }
2260                 break;
2261             }
2262             case SEND_LOCALE_TO_MOUNT_DAEMON_MSG: {
2263                 try {
2264                     Locale l = (Locale) msg.obj;
2265                     IBinder service = ServiceManager.getService("mount");
2266                     IStorageManager storageManager = IStorageManager.Stub.asInterface(service);
2267                     Log.d(TAG, "Storing locale " + l.toLanguageTag() + " for decryption UI");
2268                     storageManager.setField(StorageManager.SYSTEM_LOCALE_KEY, l.toLanguageTag());
2269                 } catch (RemoteException e) {
2270                     Log.e(TAG, "Error storing locale for decryption UI", e);
2271                 }
2272                 break;
2273             }
2274             case NOTIFY_CLEARTEXT_NETWORK_MSG: {
2275                 final int uid = msg.arg1;
2276                 final byte[] firstPacket = (byte[]) msg.obj;
2277
2278                 synchronized (mPidsSelfLocked) {
2279                     for (int i = 0; i < mPidsSelfLocked.size(); i++) {
2280                         final ProcessRecord p = mPidsSelfLocked.valueAt(i);
2281                         if (p.uid == uid) {
2282                             try {
2283                                 p.thread.notifyCleartextNetwork(firstPacket);
2284                             } catch (RemoteException ignored) {
2285                             }
2286                         }
2287                     }
2288                 }
2289                 break;
2290             }
2291             case POST_DUMP_HEAP_NOTIFICATION_MSG: {
2292                 final String procName;
2293                 final int uid;
2294                 final long memLimit;
2295                 final String reportPackage;
2296                 synchronized (ActivityManagerService.this) {
2297                     procName = mMemWatchDumpProcName;
2298                     uid = mMemWatchDumpUid;
2299                     Pair<Long, String> val = mMemWatchProcesses.get(procName, uid);
2300                     if (val == null) {
2301                         val = mMemWatchProcesses.get(procName, 0);
2302                     }
2303                     if (val != null) {
2304                         memLimit = val.first;
2305                         reportPackage = val.second;
2306                     } else {
2307                         memLimit = 0;
2308                         reportPackage = null;
2309                     }
2310                 }
2311                 if (procName == null) {
2312                     return;
2313                 }
2314
2315                 if (DEBUG_PSS) Slog.d(TAG_PSS,
2316                         "Showing dump heap notification from " + procName + "/" + uid);
2317
2318                 INotificationManager inm = NotificationManager.getService();
2319                 if (inm == null) {
2320                     return;
2321                 }
2322
2323                 String text = mContext.getString(R.string.dump_heap_notification, procName);
2324
2325
2326                 Intent deleteIntent = new Intent();
2327                 deleteIntent.setAction(DumpHeapActivity.ACTION_DELETE_DUMPHEAP);
2328                 Intent intent = new Intent();
2329                 intent.setClassName("android", DumpHeapActivity.class.getName());
2330                 intent.putExtra(DumpHeapActivity.KEY_PROCESS, procName);
2331                 intent.putExtra(DumpHeapActivity.KEY_SIZE, memLimit);
2332                 if (reportPackage != null) {
2333                     intent.putExtra(DumpHeapActivity.KEY_DIRECT_LAUNCH, reportPackage);
2334                 }
2335                 int userId = UserHandle.getUserId(uid);
2336                 Notification notification =
2337                         new Notification.Builder(mContext, SystemNotificationChannels.DEVELOPER)
2338                         .setSmallIcon(com.android.internal.R.drawable.stat_sys_adb)
2339                         .setWhen(0)
2340                         .setOngoing(true)
2341                         .setAutoCancel(true)
2342                         .setTicker(text)
2343                         .setColor(mContext.getColor(
2344                                 com.android.internal.R.color.system_notification_accent_color))
2345                         .setContentTitle(text)
2346                         .setContentText(
2347                                 mContext.getText(R.string.dump_heap_notification_detail))
2348                         .setContentIntent(PendingIntent.getActivityAsUser(mContext, 0,
2349                                 intent, PendingIntent.FLAG_CANCEL_CURRENT, null,
2350                                 new UserHandle(userId)))
2351                         .setDeleteIntent(PendingIntent.getBroadcastAsUser(mContext, 0,
2352                                 deleteIntent, 0, UserHandle.SYSTEM))
2353                         .build();
2354
2355                 try {
2356                     inm.enqueueNotificationWithTag("android", "android", null,
2357                             SystemMessage.NOTE_DUMP_HEAP_NOTIFICATION,
2358                             notification, userId);
2359                 } catch (RuntimeException e) {
2360                     Slog.w(ActivityManagerService.TAG,
2361                             "Error showing notification for dump heap", e);
2362                 } catch (RemoteException e) {
2363                 }
2364             } break;
2365             case DELETE_DUMPHEAP_MSG: {
2366                 revokeUriPermission(ActivityThread.currentActivityThread().getApplicationThread(),
2367                         null, DumpHeapActivity.JAVA_URI,
2368                         Intent.FLAG_GRANT_READ_URI_PERMISSION
2369                                 | Intent.FLAG_GRANT_WRITE_URI_PERMISSION,
2370                         UserHandle.myUserId());
2371                 synchronized (ActivityManagerService.this) {
2372                     mMemWatchDumpFile = null;
2373                     mMemWatchDumpProcName = null;
2374                     mMemWatchDumpPid = -1;
2375                     mMemWatchDumpUid = -1;
2376                 }
2377             } break;
2378             case FOREGROUND_PROFILE_CHANGED_MSG: {
2379                 mUserController.dispatchForegroundProfileChanged(msg.arg1);
2380             } break;
2381             case REPORT_TIME_TRACKER_MSG: {
2382                 AppTimeTracker tracker = (AppTimeTracker)msg.obj;
2383                 tracker.deliverResult(mContext);
2384             } break;
2385             case REPORT_USER_SWITCH_COMPLETE_MSG: {
2386                 mUserController.dispatchUserSwitchComplete(msg.arg1);
2387             } break;
2388             case REPORT_LOCKED_BOOT_COMPLETE_MSG: {
2389                 mUserController.dispatchLockedBootComplete(msg.arg1);
2390             } break;
2391             case SHUTDOWN_UI_AUTOMATION_CONNECTION_MSG: {
2392                 IUiAutomationConnection connection = (IUiAutomationConnection) msg.obj;
2393                 try {
2394                     connection.shutdown();
2395                 } catch (RemoteException e) {
2396                     Slog.w(TAG, "Error shutting down UiAutomationConnection");
2397                 }
2398                 // Only a UiAutomation can set this flag and now that
2399                 // it is finished we make sure it is reset to its default.
2400                 mUserIsMonkey = false;
2401             } break;
2402             case IDLE_UIDS_MSG: {
2403                 idleUids();
2404             } break;
2405             case VR_MODE_CHANGE_MSG: {
2406                 if (!mVrController.onVrModeChanged((ActivityRecord) msg.obj)) {
2407                     return;
2408                 }
2409                 synchronized (ActivityManagerService.this) {
2410                     final boolean disableNonVrUi = mVrController.shouldDisableNonVrUiLocked();
2411                     mWindowManager.disableNonVrUi(disableNonVrUi);
2412                     if (disableNonVrUi) {
2413                         // If we are in a VR mode where Picture-in-Picture mode is unsupported,
2414                         // then remove the pinned stack.
2415                         final PinnedActivityStack pinnedStack = mStackSupervisor.getStack(
2416                                 PINNED_STACK_ID);
2417                         if (pinnedStack != null) {
2418                             mStackSupervisor.removeStackLocked(PINNED_STACK_ID);
2419                         }
2420                     }
2421                 }
2422             } break;
2423             case NOTIFY_VR_SLEEPING_MSG: {
2424                 notifyVrManagerOfSleepState(msg.arg1 != 0);
2425             } break;
2426             case HANDLE_TRUST_STORAGE_UPDATE_MSG: {
2427                 synchronized (ActivityManagerService.this) {
2428                     for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) {
2429                         ProcessRecord r = mLruProcesses.get(i);
2430                         if (r.thread != null) {
2431                             try {
2432                                 r.thread.handleTrustStorageUpdate();
2433                             } catch (RemoteException ex) {
2434                                 Slog.w(TAG, "Failed to handle trust storage update for: " +
2435                                         r.info.processName);
2436                             }
2437                         }
2438                     }
2439                 }
2440             } break;
2441             }
2442         }
2443     };
2444
2445     static final int COLLECT_PSS_BG_MSG = 1;
2446
2447     final Handler mBgHandler = new Handler(BackgroundThread.getHandler().getLooper()) {
2448         @Override
2449         public void handleMessage(Message msg) {
2450             switch (msg.what) {
2451             case COLLECT_PSS_BG_MSG: {
2452                 long start = SystemClock.uptimeMillis();
2453                 MemInfoReader memInfo = null;
2454                 synchronized (ActivityManagerService.this) {
2455                     if (mFullPssPending) {
2456                         mFullPssPending = false;
2457                         memInfo = new MemInfoReader();
2458                     }
2459                 }
2460                 if (memInfo != null) {
2461                     updateCpuStatsNow();
2462                     long nativeTotalPss = 0;
2463                     final List<ProcessCpuTracker.Stats> stats;
2464                     synchronized (mProcessCpuTracker) {
2465                         stats = mProcessCpuTracker.getStats( (st)-> {
2466                             return st.vsize > 0 && st.uid < FIRST_APPLICATION_UID;
2467                         });
2468                     }
2469                     final int N = stats.size();
2470                     for (int j = 0; j < N; j++) {
2471                         synchronized (mPidsSelfLocked) {
2472                             if (mPidsSelfLocked.indexOfKey(stats.get(j).pid) >= 0) {
2473                                 // This is one of our own processes; skip it.
2474                                 continue;
2475                             }
2476                         }
2477                         nativeTotalPss += Debug.getPss(stats.get(j).pid, null, null);
2478                     }
2479                     memInfo.readMemInfo();
2480                     synchronized (ActivityManagerService.this) {
2481                         if (DEBUG_PSS) Slog.d(TAG_PSS, "Collected native and kernel memory in "
2482                                 + (SystemClock.uptimeMillis()-start) + "ms");
2483                         final long cachedKb = memInfo.getCachedSizeKb();
2484                         final long freeKb = memInfo.getFreeSizeKb();
2485                         final long zramKb = memInfo.getZramTotalSizeKb();
2486                         final long kernelKb = memInfo.getKernelUsedSizeKb();
2487                         EventLogTags.writeAmMeminfo(cachedKb*1024, freeKb*1024, zramKb*1024,
2488                                 kernelKb*1024, nativeTotalPss*1024);
2489                         mProcessStats.addSysMemUsageLocked(cachedKb, freeKb, zramKb, kernelKb,
2490                                 nativeTotalPss);
2491                     }
2492                 }
2493
2494                 int num = 0;
2495                 long[] tmp = new long[2];
2496                 do {
2497                     ProcessRecord proc;
2498                     int procState;
2499                     int pid;
2500                     long lastPssTime;
2501                     synchronized (ActivityManagerService.this) {
2502                         if (mPendingPssProcesses.size() <= 0) {
2503                             if (mTestPssMode || DEBUG_PSS) Slog.d(TAG_PSS,
2504                                     "Collected PSS of " + num + " processes in "
2505                                     + (SystemClock.uptimeMillis() - start) + "ms");
2506                             mPendingPssProcesses.clear();
2507                             return;
2508                         }
2509                         proc = mPendingPssProcesses.remove(0);
2510                         procState = proc.pssProcState;
2511                         lastPssTime = proc.lastPssTime;
2512                         if (proc.thread != null && procState == proc.setProcState
2513                                 && (lastPssTime+ProcessList.PSS_SAFE_TIME_FROM_STATE_CHANGE)
2514                                         < SystemClock.uptimeMillis()) {
2515                             pid = proc.pid;
2516                         } else {
2517                             proc = null;
2518                             pid = 0;
2519                         }
2520                     }
2521                     if (proc != null) {
2522                         long pss = Debug.getPss(pid, tmp, null);
2523                         synchronized (ActivityManagerService.this) {
2524                             if (pss != 0 && proc.thread != null && proc.setProcState == procState
2525                                     && proc.pid == pid && proc.lastPssTime == lastPssTime) {
2526                                 num++;
2527                                 recordPssSampleLocked(proc, procState, pss, tmp[0], tmp[1],
2528                                         SystemClock.uptimeMillis());
2529                             }
2530                         }
2531                     }
2532                 } while (true);
2533             }
2534             }
2535         }
2536     };
2537
2538     public void setSystemProcess() {
2539         try {
2540             ServiceManager.addService(Context.ACTIVITY_SERVICE, this, true);
2541             ServiceManager.addService(ProcessStats.SERVICE_NAME, mProcessStats);
2542             ServiceManager.addService("meminfo", new MemBinder(this));
2543             ServiceManager.addService("gfxinfo", new GraphicsBinder(this));
2544             ServiceManager.addService("dbinfo", new DbBinder(this));
2545             if (MONITOR_CPU_USAGE) {
2546                 ServiceManager.addService("cpuinfo", new CpuBinder(this));
2547             }
2548             ServiceManager.addService("permission", new PermissionController(this));
2549             ServiceManager.addService("processinfo", new ProcessInfoService(this));
2550
2551             ApplicationInfo info = mContext.getPackageManager().getApplicationInfo(
2552                     "android", STOCK_PM_FLAGS | MATCH_SYSTEM_ONLY);
2553             mSystemThread.installSystemApplicationInfo(info, getClass().getClassLoader());
2554
2555             synchronized (this) {
2556                 ProcessRecord app = newProcessRecordLocked(info, info.processName, false, 0);
2557                 app.persistent = true;
2558                 app.pid = MY_PID;
2559                 app.maxAdj = ProcessList.SYSTEM_ADJ;
2560                 app.makeActive(mSystemThread.getApplicationThread(), mProcessStats);
2561                 synchronized (mPidsSelfLocked) {
2562                     mPidsSelfLocked.put(app.pid, app);
2563                 }
2564                 updateLruProcessLocked(app, false, null);
2565                 updateOomAdjLocked();
2566             }
2567         } catch (PackageManager.NameNotFoundException e) {
2568             throw new RuntimeException(
2569                     "Unable to find android system package", e);
2570         }
2571     }
2572
2573     public void setWindowManager(WindowManagerService wm) {
2574         mWindowManager = wm;
2575         mStackSupervisor.setWindowManager(wm);
2576         mActivityStarter.setWindowManager(wm);
2577     }
2578
2579     public void setUsageStatsManager(UsageStatsManagerInternal usageStatsManager) {
2580         mUsageStatsService = usageStatsManager;
2581     }
2582
2583     public void startObservingNativeCrashes() {
2584         final NativeCrashListener ncl = new NativeCrashListener(this);
2585         ncl.start();
2586     }
2587
2588     public IAppOpsService getAppOpsService() {
2589         return mAppOpsService;
2590     }
2591
2592     static class MemBinder extends Binder {
2593         ActivityManagerService mActivityManagerService;
2594         MemBinder(ActivityManagerService activityManagerService) {
2595             mActivityManagerService = activityManagerService;
2596         }
2597
2598         @Override
2599         protected void dump(FileDescriptor fd, PrintWriter pw, String[] args) {
2600             if (!DumpUtils.checkDumpAndUsageStatsPermission(mActivityManagerService.mContext,
2601                     "meminfo", pw)) return;
2602             mActivityManagerService.dumpApplicationMemoryUsage(fd, pw, "  ", args, false, null);
2603         }
2604     }
2605
2606     static class GraphicsBinder extends Binder {
2607         ActivityManagerService mActivityManagerService;
2608         GraphicsBinder(ActivityManagerService activityManagerService) {
2609             mActivityManagerService = activityManagerService;
2610         }
2611
2612         @Override
2613         protected void dump(FileDescriptor fd, PrintWriter pw, String[] args) {
2614             if (!DumpUtils.checkDumpAndUsageStatsPermission(mActivityManagerService.mContext,
2615                     "gfxinfo", pw)) return;
2616             mActivityManagerService.dumpGraphicsHardwareUsage(fd, pw, args);
2617         }
2618     }
2619
2620     static class DbBinder extends Binder {
2621         ActivityManagerService mActivityManagerService;
2622         DbBinder(ActivityManagerService activityManagerService) {
2623             mActivityManagerService = activityManagerService;
2624         }
2625
2626         @Override
2627         protected void dump(FileDescriptor fd, PrintWriter pw, String[] args) {
2628             if (!DumpUtils.checkDumpAndUsageStatsPermission(mActivityManagerService.mContext,
2629                     "dbinfo", pw)) return;
2630             mActivityManagerService.dumpDbInfo(fd, pw, args);
2631         }
2632     }
2633
2634     static class CpuBinder extends Binder {
2635         ActivityManagerService mActivityManagerService;
2636         CpuBinder(ActivityManagerService activityManagerService) {
2637             mActivityManagerService = activityManagerService;
2638         }
2639
2640         @Override
2641         protected void dump(FileDescriptor fd, PrintWriter pw, String[] args) {
2642             if (!DumpUtils.checkDumpAndUsageStatsPermission(mActivityManagerService.mContext,
2643                     "cpuinfo", pw)) return;
2644             synchronized (mActivityManagerService.mProcessCpuTracker) {
2645                 pw.print(mActivityManagerService.mProcessCpuTracker.printCurrentLoad());
2646                 pw.print(mActivityManagerService.mProcessCpuTracker.printCurrentState(
2647                         SystemClock.uptimeMillis()));
2648             }
2649         }
2650     }
2651
2652     public static final class Lifecycle extends SystemService {
2653         private final ActivityManagerService mService;
2654
2655         public Lifecycle(Context context) {
2656             super(context);
2657             mService = new ActivityManagerService(context);
2658         }
2659
2660         @Override
2661         public void onStart() {
2662             mService.start();
2663         }
2664
2665         public ActivityManagerService getService() {
2666             return mService;
2667         }
2668     }
2669
2670     @VisibleForTesting
2671     public ActivityManagerService(Injector injector) {
2672         mInjector = injector;
2673         mContext = mInjector.getContext();
2674         mUiContext = null;
2675         GL_ES_VERSION = 0;
2676         mActivityStarter = null;
2677         mAppErrors = null;
2678         mAppOpsService = mInjector.getAppOpsService(null, null);
2679         mBatteryStatsService = null;
2680         mCompatModePackages = null;
2681         mConstants = null;
2682         mGrantFile = null;
2683         mHandler = null;
2684         mHandlerThread = null;
2685         mIntentFirewall = null;
2686         mKeyguardController = null;
2687         mPermissionReviewRequired = false;
2688         mProcessCpuThread = null;
2689         mProcessStats = null;
2690         mProviderMap = null;
2691         mRecentTasks = null;
2692         mServices = null;
2693         mStackSupervisor = null;
2694         mSystemThread = null;
2695         mTaskChangeNotificationController = null;
2696         mUiHandler = injector.getUiHandler(null);
2697         mUserController = null;
2698         mVrController = null;
2699     }
2700
2701     // Note: This method is invoked on the main thread but may need to attach various
2702     // handlers to other threads.  So take care to be explicit about the looper.
2703     public ActivityManagerService(Context systemContext) {
2704         LockGuard.installLock(this, LockGuard.INDEX_ACTIVITY);
2705         mInjector = new Injector();
2706         mContext = systemContext;
2707
2708         mFactoryTest = FactoryTest.getMode();
2709         mSystemThread = ActivityThread.currentActivityThread();
2710         mUiContext = mSystemThread.getSystemUiContext();
2711
2712         Slog.i(TAG, "Memory class: " + ActivityManager.staticGetMemoryClass());
2713
2714         mPermissionReviewRequired = mContext.getResources().getBoolean(
2715                 com.android.internal.R.bool.config_permissionReviewRequired);
2716
2717         mHandlerThread = new ServiceThread(TAG,
2718                 THREAD_PRIORITY_FOREGROUND, false /*allowIo*/);
2719         mHandlerThread.start();
2720         mHandler = new MainHandler(mHandlerThread.getLooper());
2721         mUiHandler = mInjector.getUiHandler(this);
2722
2723         mConstants = new ActivityManagerConstants(this, mHandler);
2724
2725         /* static; one-time init here */
2726         if (sKillHandler == null) {
2727             sKillThread = new ServiceThread(TAG + ":kill",
2728                     THREAD_PRIORITY_BACKGROUND, true /* allowIo */);
2729             sKillThread.start();
2730             sKillHandler = new KillHandler(sKillThread.getLooper());
2731         }
2732
2733         mFgBroadcastQueue = new BroadcastQueue(this, mHandler,
2734                 "foreground", BROADCAST_FG_TIMEOUT, false);
2735         mBgBroadcastQueue = new BroadcastQueue(this, mHandler,
2736                 "background", BROADCAST_BG_TIMEOUT, true);
2737         mBroadcastQueues[0] = mFgBroadcastQueue;
2738         mBroadcastQueues[1] = mBgBroadcastQueue;
2739
2740         mServices = new ActiveServices(this);
2741         mProviderMap = new ProviderMap(this);
2742         mAppErrors = new AppErrors(mUiContext, this);
2743
2744         // TODO: Move creation of battery stats service outside of activity manager service.
2745         File dataDir = Environment.getDataDirectory();
2746         File systemDir = new File(dataDir, "system");
2747         systemDir.mkdirs();
2748         mBatteryStatsService = new BatteryStatsService(systemDir, mHandler);
2749         mBatteryStatsService.getActiveStatistics().readLocked();
2750         mBatteryStatsService.scheduleWriteToDisk();
2751         mOnBattery = DEBUG_POWER ? true
2752                 : mBatteryStatsService.getActiveStatistics().getIsOnBattery();
2753         mBatteryStatsService.getActiveStatistics().setCallback(this);
2754
2755         mProcessStats = new ProcessStatsService(this, new File(systemDir, "procstats"));
2756
2757         mAppOpsService = mInjector.getAppOpsService(new File(systemDir, "appops.xml"), mHandler);
2758         mAppOpsService.startWatchingMode(AppOpsManager.OP_RUN_IN_BACKGROUND, null,
2759                 new IAppOpsCallback.Stub() {
2760                     @Override public void opChanged(int op, int uid, String packageName) {
2761                         if (op == AppOpsManager.OP_RUN_IN_BACKGROUND && packageName != null) {
2762                             if (mAppOpsService.checkOperation(op, uid, packageName)
2763                                     != AppOpsManager.MODE_ALLOWED) {
2764                                 runInBackgroundDisabled(uid);
2765                             }
2766                         }
2767                     }
2768                 });
2769
2770         mGrantFile = new AtomicFile(new File(systemDir, "urigrants.xml"));
2771
2772         mUserController = new UserController(this);
2773
2774         mVrController = new VrController(this);
2775
2776         GL_ES_VERSION = SystemProperties.getInt("ro.opengles.version",
2777             ConfigurationInfo.GL_ES_VERSION_UNDEFINED);
2778
2779         if (SystemProperties.getInt("sys.use_fifo_ui", 0) != 0) {
2780             mUseFifoUiScheduling = true;
2781         }
2782
2783         mTrackingAssociations = "1".equals(SystemProperties.get("debug.track-associations"));
2784         mTempConfig.setToDefaults();
2785         mTempConfig.setLocales(LocaleList.getDefault());
2786         mConfigurationSeq = mTempConfig.seq = 1;
2787         mStackSupervisor = createStackSupervisor();
2788         mStackSupervisor.onConfigurationChanged(mTempConfig);
2789         mKeyguardController = mStackSupervisor.mKeyguardController;
2790         mCompatModePackages = new CompatModePackages(this, systemDir, mHandler);
2791         mIntentFirewall = new IntentFirewall(new IntentFirewallInterface(), mHandler);
2792         mTaskChangeNotificationController =
2793                 new TaskChangeNotificationController(this, mStackSupervisor, mHandler);
2794         mActivityStarter = new ActivityStarter(this, mStackSupervisor);
2795         mRecentTasks = new RecentTasks(this, mStackSupervisor);
2796
2797         mProcessCpuThread = new Thread("CpuTracker") {
2798             @Override
2799             public void run() {
2800                 synchronized (mProcessCpuTracker) {
2801                     mProcessCpuInitLatch.countDown();
2802                     mProcessCpuTracker.init();
2803                 }
2804                 while (true) {
2805                     try {
2806                         try {
2807                             synchronized(this) {
2808                                 final long now = SystemClock.uptimeMillis();
2809                                 long nextCpuDelay = (mLastCpuTime.get()+MONITOR_CPU_MAX_TIME)-now;
2810                                 long nextWriteDelay = (mLastWriteTime+BATTERY_STATS_TIME)-now;
2811                                 //Slog.i(TAG, "Cpu delay=" + nextCpuDelay
2812                                 //        + ", write delay=" + nextWriteDelay);
2813                                 if (nextWriteDelay < nextCpuDelay) {
2814                                     nextCpuDelay = nextWriteDelay;
2815                                 }
2816                                 if (nextCpuDelay > 0) {
2817                                     mProcessCpuMutexFree.set(true);
2818                                     this.wait(nextCpuDelay);
2819                                 }
2820                             }
2821                         } catch (InterruptedException e) {
2822                         }
2823                         updateCpuStatsNow();
2824                     } catch (Exception e) {
2825                         Slog.e(TAG, "Unexpected exception collecting process stats", e);
2826                     }
2827                 }
2828             }
2829         };
2830
2831         Watchdog.getInstance().addMonitor(this);
2832         Watchdog.getInstance().addThread(mHandler);
2833     }
2834
2835     protected ActivityStackSupervisor createStackSupervisor() {
2836         return new ActivityStackSupervisor(this, mHandler.getLooper());
2837     }
2838
2839     public void setSystemServiceManager(SystemServiceManager mgr) {
2840         mSystemServiceManager = mgr;
2841     }
2842
2843     public void setInstaller(Installer installer) {
2844         mInstaller = installer;
2845     }
2846
2847     private void start() {
2848         removeAllProcessGroups();
2849         mProcessCpuThread.start();
2850
2851         mBatteryStatsService.publish(mContext);
2852         mAppOpsService.publish(mContext);
2853         Slog.d("AppOps", "AppOpsService published");
2854         LocalServices.addService(ActivityManagerInternal.class, new LocalService());
2855         // Wait for the synchronized block started in mProcessCpuThread,
2856         // so that any other acccess to mProcessCpuTracker from main thread
2857         // will be blocked during mProcessCpuTracker initialization.
2858         try {
2859             mProcessCpuInitLatch.await();
2860         } catch (InterruptedException e) {
2861             Slog.wtf(TAG, "Interrupted wait during start", e);
2862             Thread.currentThread().interrupt();
2863             throw new IllegalStateException("Interrupted wait during start");
2864         }
2865     }
2866
2867     void onUserStoppedLocked(int userId) {
2868         mRecentTasks.unloadUserDataFromMemoryLocked(userId);
2869     }
2870
2871     public void initPowerManagement() {
2872         mStackSupervisor.initPowerManagement();
2873         mBatteryStatsService.initPowerManagement();
2874         mLocalPowerManager = LocalServices.getService(PowerManagerInternal.class);
2875         PowerManager pm = (PowerManager)mContext.getSystemService(Context.POWER_SERVICE);
2876         mVoiceWakeLock = pm.newWakeLock(PowerManager.PARTIAL_WAKE_LOCK, "*voice*");
2877         mVoiceWakeLock.setReferenceCounted(false);
2878     }
2879
2880     private ArraySet<String> getBackgroundLaunchBroadcasts() {
2881         if (mBackgroundLaunchBroadcasts == null) {
2882             mBackgroundLaunchBroadcasts = SystemConfig.getInstance().getAllowImplicitBroadcasts();
2883         }
2884         return mBackgroundLaunchBroadcasts;
2885     }
2886
2887     @Override
2888     public boolean onTransact(int code, Parcel data, Parcel reply, int flags)
2889             throws RemoteException {
2890         if (code == SYSPROPS_TRANSACTION) {
2891             // We need to tell all apps about the system property change.
2892             ArrayList<IBinder> procs = new ArrayList<IBinder>();
2893             synchronized(this) {
2894                 final int NP = mProcessNames.getMap().size();
2895                 for (int ip=0; ip<NP; ip++) {
2896                     SparseArray<ProcessRecord> apps = mProcessNames.getMap().valueAt(ip);
2897                     final int NA = apps.size();
2898                     for (int ia=0; ia<NA; ia++) {
2899                         ProcessRecord app = apps.valueAt(ia);
2900                         if (app.thread != null) {
2901                             procs.add(app.thread.asBinder());
2902                         }
2903                     }
2904                 }
2905             }
2906
2907             int N = procs.size();
2908             for (int i=0; i<N; i++) {
2909                 Parcel data2 = Parcel.obtain();
2910                 try {
2911                     procs.get(i).transact(IBinder.SYSPROPS_TRANSACTION, data2, null,
2912                             Binder.FLAG_ONEWAY);
2913                 } catch (RemoteException e) {
2914                 }
2915                 data2.recycle();
2916             }
2917         }
2918         try {
2919             return super.onTransact(code, data, reply, flags);
2920         } catch (RuntimeException e) {
2921             // The activity manager only throws security exceptions, so let's
2922             // log all others.
2923             if (!(e instanceof SecurityException)) {
2924                 Slog.wtf(TAG, "Activity Manager Crash."
2925                         + " UID:" + Binder.getCallingUid()
2926                         + " PID:" + Binder.getCallingPid()
2927                         + " TRANS:" + code, e);
2928             }
2929             throw e;
2930         }
2931     }
2932
2933     void updateCpuStats() {
2934         final long now = SystemClock.uptimeMillis();
2935         if (mLastCpuTime.get() >= now - MONITOR_CPU_MIN_TIME) {
2936             return;
2937         }
2938         if (mProcessCpuMutexFree.compareAndSet(true, false)) {
2939             synchronized (mProcessCpuThread) {
2940                 mProcessCpuThread.notify();
2941             }
2942         }
2943     }
2944
2945     void updateCpuStatsNow() {
2946         synchronized (mProcessCpuTracker) {
2947             mProcessCpuMutexFree.set(false);
2948             final long now = SystemClock.uptimeMillis();
2949             boolean haveNewCpuStats = false;
2950
2951             if (MONITOR_CPU_USAGE &&
2952                     mLastCpuTime.get() < (now-MONITOR_CPU_MIN_TIME)) {
2953                 mLastCpuTime.set(now);
2954                 mProcessCpuTracker.update();
2955                 if (mProcessCpuTracker.hasGoodLastStats()) {
2956                     haveNewCpuStats = true;
2957                     //Slog.i(TAG, mProcessCpu.printCurrentState());
2958                     //Slog.i(TAG, "Total CPU usage: "
2959                     //        + mProcessCpu.getTotalCpuPercent() + "%");
2960
2961                     // Slog the cpu usage if the property is set.
2962                     if ("true".equals(SystemProperties.get("events.cpu"))) {
2963                         int user = mProcessCpuTracker.getLastUserTime();
2964                         int system = mProcessCpuTracker.getLastSystemTime();
2965                         int iowait = mProcessCpuTracker.getLastIoWaitTime();
2966                         int irq = mProcessCpuTracker.getLastIrqTime();
2967                         int softIrq = mProcessCpuTracker.getLastSoftIrqTime();
2968                         int idle = mProcessCpuTracker.getLastIdleTime();
2969
2970                         int total = user + system + iowait + irq + softIrq + idle;
2971                         if (total == 0) total = 1;
2972
2973                         EventLog.writeEvent(EventLogTags.CPU,
2974                                 ((user+system+iowait+irq+softIrq) * 100) / total,
2975                                 (user * 100) / total,
2976                                 (system * 100) / total,
2977                                 (iowait * 100) / total,
2978                                 (irq * 100) / total,
2979                                 (softIrq * 100) / total);
2980                     }
2981                 }
2982             }
2983
2984             final BatteryStatsImpl bstats = mBatteryStatsService.getActiveStatistics();
2985             synchronized(bstats) {
2986                 synchronized(mPidsSelfLocked) {
2987                     if (haveNewCpuStats) {
2988                         if (bstats.startAddingCpuLocked()) {
2989                             int totalUTime = 0;
2990                             int totalSTime = 0;
2991                             final int N = mProcessCpuTracker.countStats();
2992                             for (int i=0; i<N; i++) {
2993                                 ProcessCpuTracker.Stats st = mProcessCpuTracker.getStats(i);
2994                                 if (!st.working) {
2995                                     continue;
2996                                 }
2997                                 ProcessRecord pr = mPidsSelfLocked.get(st.pid);
2998                                 totalUTime += st.rel_utime;
2999                                 totalSTime += st.rel_stime;
3000                                 if (pr != null) {
3001                                     BatteryStatsImpl.Uid.Proc ps = pr.curProcBatteryStats;
3002                                     if (ps == null || !ps.isActive()) {
3003                                         pr.curProcBatteryStats = ps = bstats.getProcessStatsLocked(
3004                                                 pr.info.uid, pr.processName);
3005                                     }
3006                                     ps.addCpuTimeLocked(st.rel_utime, st.rel_stime);
3007                                     pr.curCpuTime += st.rel_utime + st.rel_stime;
3008                                 } else {
3009                                     BatteryStatsImpl.Uid.Proc ps = st.batteryStats;
3010                                     if (ps == null || !ps.isActive()) {
3011                                         st.batteryStats = ps = bstats.getProcessStatsLocked(
3012                                                 bstats.mapUid(st.uid), st.name);
3013                                     }
3014                                     ps.addCpuTimeLocked(st.rel_utime, st.rel_stime);
3015                                 }
3016                             }
3017                             final int userTime = mProcessCpuTracker.getLastUserTime();
3018                             final int systemTime = mProcessCpuTracker.getLastSystemTime();
3019                             final int iowaitTime = mProcessCpuTracker.getLastIoWaitTime();
3020                             final int irqTime = mProcessCpuTracker.getLastIrqTime();
3021                             final int softIrqTime = mProcessCpuTracker.getLastSoftIrqTime();
3022                             final int idleTime = mProcessCpuTracker.getLastIdleTime();
3023                             bstats.finishAddingCpuLocked(totalUTime, totalSTime, userTime,
3024                                     systemTime, iowaitTime, irqTime, softIrqTime, idleTime);
3025                         }
3026                     }
3027                 }
3028
3029                 if (mLastWriteTime < (now-BATTERY_STATS_TIME)) {
3030                     mLastWriteTime = now;
3031                     mBatteryStatsService.scheduleWriteToDisk();
3032                 }
3033             }
3034         }
3035     }
3036
3037     @Override
3038     public void batteryNeedsCpuUpdate() {
3039         updateCpuStatsNow();
3040     }
3041
3042     @Override
3043     public void batteryPowerChanged(boolean onBattery) {
3044         // When plugging in, update the CPU stats first before changing
3045         // the plug state.
3046         updateCpuStatsNow();
3047         synchronized (this) {
3048             synchronized(mPidsSelfLocked) {
3049                 mOnBattery = DEBUG_POWER ? true : onBattery;
3050             }
3051         }
3052     }
3053
3054     @Override
3055     public void batterySendBroadcast(Intent intent) {
3056         synchronized (this) {
3057             broadcastIntentLocked(null, null, intent, null, null, 0, null, null, null,
3058                     AppOpsManager.OP_NONE, null, false, false,
3059                     -1, SYSTEM_UID, UserHandle.USER_ALL);
3060         }
3061     }
3062
3063     /**
3064      * Initialize the application bind args. These are passed to each
3065      * process when the bindApplication() IPC is sent to the process. They're
3066      * lazily setup to make sure the services are running when they're asked for.
3067      */
3068     private HashMap<String, IBinder> getCommonServicesLocked(boolean isolated) {
3069         // Isolated processes won't get this optimization, so that we don't
3070         // violate the rules about which services they have access to.
3071         if (isolated) {
3072             if (mIsolatedAppBindArgs == null) {
3073                 mIsolatedAppBindArgs = new HashMap<>();
3074                 mIsolatedAppBindArgs.put("package", ServiceManager.getService("package"));
3075             }
3076             return mIsolatedAppBindArgs;
3077         }
3078
3079         if (mAppBindArgs == null) {
3080             mAppBindArgs = new HashMap<>();
3081
3082             // Setup the application init args
3083             mAppBindArgs.put("package", ServiceManager.getService("package"));
3084             mAppBindArgs.put("window", ServiceManager.getService("window"));
3085             mAppBindArgs.put(Context.ALARM_SERVICE,
3086                     ServiceManager.getService(Context.ALARM_SERVICE));
3087         }
3088         return mAppBindArgs;
3089     }
3090
3091     /**
3092      * Update AMS states when an activity is resumed. This should only be called by
3093      * {@link ActivityStack#setResumedActivityLocked} when an activity is resumed.
3094      */
3095     void setResumedActivityUncheckLocked(ActivityRecord r, String reason) {
3096         final TaskRecord task = r.getTask();
3097         if (task.isApplicationTask()) {
3098             if (mCurAppTimeTracker != r.appTimeTracker) {
3099                 // We are switching app tracking.  Complete the current one.
3100                 if (mCurAppTimeTracker != null) {
3101                     mCurAppTimeTracker.stop();
3102                     mHandler.obtainMessage(
3103                             REPORT_TIME_TRACKER_MSG, mCurAppTimeTracker).sendToTarget();
3104                     mStackSupervisor.clearOtherAppTimeTrackers(r.appTimeTracker);
3105                     mCurAppTimeTracker = null;
3106                 }
3107                 if (r.appTimeTracker != null) {
3108                     mCurAppTimeTracker = r.appTimeTracker;
3109                     startTimeTrackingFocusedActivityLocked();
3110                 }
3111             } else {
3112                 startTimeTrackingFocusedActivityLocked();
3113             }
3114         } else {
3115             r.appTimeTracker = null;
3116         }
3117         // TODO: VI Maybe r.task.voiceInteractor || r.voiceInteractor != null
3118         // TODO: Probably not, because we don't want to resume voice on switching
3119         // back to this activity
3120         if (task.voiceInteractor != null) {
3121             startRunningVoiceLocked(task.voiceSession, r.info.applicationInfo.uid);
3122         } else {
3123             finishRunningVoiceLocked();
3124
3125             if (mLastResumedActivity != null) {
3126                 final IVoiceInteractionSession session;
3127
3128                 final TaskRecord lastResumedActivityTask = mLastResumedActivity.getTask();
3129                 if (lastResumedActivityTask != null
3130                         && lastResumedActivityTask.voiceSession != null) {
3131                     session = lastResumedActivityTask.voiceSession;
3132                 } else {
3133                     session = mLastResumedActivity.voiceSession;
3134                 }
3135
3136                 if (session != null) {
3137                     // We had been in a voice interaction session, but now focused has
3138                     // move to something different.  Just finish the session, we can't
3139                     // return to it and retain the proper state and synchronization with
3140                     // the voice interaction service.
3141                     finishVoiceTask(session);
3142                 }
3143             }
3144         }
3145
3146         if (mLastResumedActivity != null && r.userId != mLastResumedActivity.userId) {
3147             mHandler.removeMessages(FOREGROUND_PROFILE_CHANGED_MSG);
3148             mHandler.obtainMessage(
3149                     FOREGROUND_PROFILE_CHANGED_MSG, r.userId, 0).sendToTarget();
3150         }
3151         mLastResumedActivity = r;
3152
3153         mWindowManager.setFocusedApp(r.appToken, true);
3154
3155         applyUpdateLockStateLocked(r);
3156         applyUpdateVrModeLocked(r);
3157
3158         EventLogTags.writeAmSetResumedActivity(
3159                 r == null ? -1 : r.userId,
3160                 r == null ? "NULL" : r.shortComponentName,
3161                 reason);
3162     }
3163
3164     @Override
3165     public void setFocusedStack(int stackId) {
3166         enforceCallingPermission(MANAGE_ACTIVITY_STACKS, "setFocusedStack()");
3167         if (DEBUG_FOCUS) Slog.d(TAG_FOCUS, "setFocusedStack: stackId=" + stackId);
3168         final long callingId = Binder.clearCallingIdentity();
3169         try {
3170             synchronized (this) {
3171                 final ActivityStack stack = mStackSupervisor.getStack(stackId);
3172                 if (stack == null) {
3173                     return;
3174                 }
3175                 final ActivityRecord r = stack.topRunningActivityLocked();
3176                 if (mStackSupervisor.moveFocusableActivityStackToFrontLocked(r, "setFocusedStack")) {
3177                     mStackSupervisor.resumeFocusedStackTopActivityLocked();
3178                 }
3179             }
3180         } finally {
3181             Binder.restoreCallingIdentity(callingId);
3182         }
3183     }
3184
3185     @Override
3186     public void setFocusedTask(int taskId) {
3187         enforceCallingPermission(MANAGE_ACTIVITY_STACKS, "setFocusedTask()");
3188         if (DEBUG_FOCUS) Slog.d(TAG_FOCUS, "setFocusedTask: taskId=" + taskId);
3189         final long callingId = Binder.clearCallingIdentity();
3190         try {
3191             synchronized (this) {
3192                 final TaskRecord task = mStackSupervisor.anyTaskForIdLocked(taskId);
3193                 if (task == null) {
3194                     return;
3195                 }
3196                 final ActivityRecord r = task.topRunningActivityLocked();
3197                 if (mStackSupervisor.moveFocusableActivityStackToFrontLocked(r, "setFocusedTask")) {
3198                     mStackSupervisor.resumeFocusedStackTopActivityLocked();
3199                 }
3200             }
3201         } finally {
3202             Binder.restoreCallingIdentity(callingId);
3203         }
3204     }
3205
3206     /** Sets the task stack listener that gets callbacks when a task stack changes. */
3207     @Override
3208     public void registerTaskStackListener(ITaskStackListener listener) throws RemoteException {
3209         enforceCallingPermission(MANAGE_ACTIVITY_STACKS, "registerTaskStackListener()");
3210         mTaskChangeNotificationController.registerTaskStackListener(listener);
3211     }
3212
3213     /**
3214      * Unregister a task stack listener so that it stops receiving callbacks.
3215      */
3216     @Override
3217     public void unregisterTaskStackListener(ITaskStackListener listener) throws RemoteException {
3218          enforceCallingPermission(MANAGE_ACTIVITY_STACKS, "unregisterTaskStackListener()");
3219          mTaskChangeNotificationController.unregisterTaskStackListener(listener);
3220      }
3221
3222     @Override
3223     public void notifyActivityDrawn(IBinder token) {
3224         if (DEBUG_VISIBILITY) Slog.d(TAG_VISIBILITY, "notifyActivityDrawn: token=" + token);
3225         synchronized (this) {
3226             ActivityRecord r = mStackSupervisor.isInAnyStackLocked(token);
3227             if (r != null) {
3228                 r.getStack().notifyActivityDrawnLocked(r);
3229             }
3230         }
3231     }
3232
3233     final void applyUpdateLockStateLocked(ActivityRecord r) {
3234         // Modifications to the UpdateLock state are done on our handler, outside
3235         // the activity manager's locks.  The new state is determined based on the
3236         // state *now* of the relevant activity record.  The object is passed to
3237         // the handler solely for logging detail, not to be consulted/modified.
3238         final boolean nextState = r != null && r.immersive;
3239         mHandler.sendMessage(
3240                 mHandler.obtainMessage(IMMERSIVE_MODE_LOCK_MSG, (nextState) ? 1 : 0, 0, r));
3241     }
3242
3243     final void applyUpdateVrModeLocked(ActivityRecord r) {
3244         mHandler.sendMessage(
3245                 mHandler.obtainMessage(VR_MODE_CHANGE_MSG, 0, 0, r));
3246     }
3247
3248     private void sendNotifyVrManagerOfSleepState(boolean isSleeping) {
3249         mHandler.sendMessage(
3250                 mHandler.obtainMessage(NOTIFY_VR_SLEEPING_MSG, isSleeping ? 1 : 0, 0));
3251     }
3252
3253     private void notifyVrManagerOfSleepState(boolean isSleeping) {
3254         final VrManagerInternal vrService = LocalServices.getService(VrManagerInternal.class);
3255         if (vrService == null) {
3256             return;
3257         }
3258         vrService.onSleepStateChanged(isSleeping);
3259     }
3260
3261     final void showAskCompatModeDialogLocked(ActivityRecord r) {
3262         Message msg = Message.obtain();
3263         msg.what = SHOW_COMPAT_MODE_DIALOG_UI_MSG;
3264         msg.obj = r.getTask().askedCompatMode ? null : r;
3265         mUiHandler.sendMessage(msg);
3266     }
3267
3268     final void showUnsupportedZoomDialogIfNeededLocked(ActivityRecord r) {
3269         final Configuration globalConfig = getGlobalConfiguration();
3270         if (globalConfig.densityDpi != DisplayMetrics.DENSITY_DEVICE_STABLE
3271                 && r.appInfo.requiresSmallestWidthDp > globalConfig.smallestScreenWidthDp) {
3272             final Message msg = Message.obtain();
3273             msg.what = SHOW_UNSUPPORTED_DISPLAY_SIZE_DIALOG_MSG;
3274             msg.obj = r;
3275             mUiHandler.sendMessage(msg);
3276         }
3277     }
3278
3279     private int updateLruProcessInternalLocked(ProcessRecord app, long now, int index,
3280             String what, Object obj, ProcessRecord srcApp) {
3281         app.lastActivityTime = now;
3282
3283         if (app.activities.size() > 0) {
3284             // Don't want to touch dependent processes that are hosting activities.
3285             return index;
3286         }
3287
3288         int lrui = mLruProcesses.lastIndexOf(app);
3289         if (lrui < 0) {
3290             Slog.wtf(TAG, "Adding dependent process " + app + " not on LRU list: "
3291                     + what + " " + obj + " from " + srcApp);
3292             return index;
3293         }
3294
3295         if (lrui >= index) {
3296             // Don't want to cause this to move dependent processes *back* in the
3297             // list as if they were less frequently used.
3298             return index;
3299         }
3300
3301         if (lrui >= mLruProcessActivityStart) {
3302             // Don't want to touch dependent processes that are hosting activities.
3303             return index;
3304         }
3305
3306         mLruProcesses.remove(lrui);
3307         if (index > 0) {
3308             index--;
3309         }
3310         if (DEBUG_LRU) Slog.d(TAG_LRU, "Moving dep from " + lrui + " to " + index
3311                 + " in LRU list: " + app);
3312         mLruProcesses.add(index, app);
3313         return index;
3314     }
3315
3316     static void killProcessGroup(int uid, int pid) {
3317         if (sKillHandler != null) {
3318             sKillHandler.sendMessage(
3319                     sKillHandler.obtainMessage(KillHandler.KILL_PROCESS_GROUP_MSG, uid, pid));
3320         } else {
3321             Slog.w(TAG, "Asked to kill process group before system bringup!");
3322             Process.killProcessGroup(uid, pid);
3323         }
3324     }
3325
3326     final void removeLruProcessLocked(ProcessRecord app) {
3327         int lrui = mLruProcesses.lastIndexOf(app);
3328         if (lrui >= 0) {
3329             if (!app.killed) {
3330                 Slog.wtfStack(TAG, "Removing process that hasn't been killed: " + app);
3331                 killProcessQuiet(app.pid);
3332                 killProcessGroup(app.uid, app.pid);
3333             }
3334             if (lrui <= mLruProcessActivityStart) {
3335                 mLruProcessActivityStart--;
3336             }
3337             if (lrui <= mLruProcessServiceStart) {
3338                 mLruProcessServiceStart--;
3339             }
3340             mLruProcesses.remove(lrui);
3341         }
3342     }
3343
3344     final void updateLruProcessLocked(ProcessRecord app, boolean activityChange,
3345             ProcessRecord client) {
3346         final boolean hasActivity = app.activities.size() > 0 || app.hasClientActivities
3347                 || app.treatLikeActivity;
3348         final boolean hasService = false; // not impl yet. app.services.size() > 0;
3349         if (!activityChange && hasActivity) {
3350             // The process has activities, so we are only allowing activity-based adjustments
3351             // to move it.  It should be kept in the front of the list with other
3352             // processes that have activities, and we don't want those to change their
3353             // order except due to activity operations.
3354             return;
3355         }
3356
3357         mLruSeq++;
3358         final long now = SystemClock.uptimeMillis();
3359         app.lastActivityTime = now;
3360
3361         // First a quick reject: if the app is already at the position we will
3362         // put it, then there is nothing to do.
3363         if (hasActivity) {
3364             final int N = mLruProcesses.size();
3365             if (N > 0 && mLruProcesses.get(N-1) == app) {
3366                 if (DEBUG_LRU) Slog.d(TAG_LRU, "Not moving, already top activity: " + app);
3367                 return;
3368             }
3369         } else {
3370             if (mLruProcessServiceStart > 0
3371                     && mLruProcesses.get(mLruProcessServiceStart-1) == app) {
3372                 if (DEBUG_LRU) Slog.d(TAG_LRU, "Not moving, already top other: " + app);
3373                 return;
3374             }
3375         }
3376
3377         int lrui = mLruProcesses.lastIndexOf(app);
3378
3379         if (app.persistent && lrui >= 0) {
3380             // We don't care about the position of persistent processes, as long as
3381             // they are in the list.
3382             if (DEBUG_LRU) Slog.d(TAG_LRU, "Not moving, persistent: " + app);
3383             return;
3384         }
3385
3386         /* In progress: compute new position first, so we can avoid doing work
3387            if the process is not actually going to move.  Not yet working.
3388         int addIndex;
3389         int nextIndex;
3390         boolean inActivity = false, inService = false;
3391         if (hasActivity) {
3392             // Process has activities, put it at the very tipsy-top.
3393             addIndex = mLruProcesses.size();
3394             nextIndex = mLruProcessServiceStart;
3395             inActivity = true;
3396         } else if (hasService) {
3397             // Process has services, put it at the top of the service list.
3398             addIndex = mLruProcessActivityStart;
3399             nextIndex = mLruProcessServiceStart;
3400             inActivity = true;
3401             inService = true;
3402         } else  {
3403             // Process not otherwise of interest, it goes to the top of the non-service area.
3404             addIndex = mLruProcessServiceStart;
3405             if (client != null) {
3406                 int clientIndex = mLruProcesses.lastIndexOf(client);
3407                 if (clientIndex < 0) Slog.d(TAG, "Unknown client " + client + " when updating "
3408                         + app);
3409                 if (clientIndex >= 0 && addIndex > clientIndex) {
3410                     addIndex = clientIndex;
3411                 }
3412             }
3413             nextIndex = addIndex > 0 ? addIndex-1 : addIndex;
3414         }
3415
3416         Slog.d(TAG, "Update LRU at " + lrui + " to " + addIndex + " (act="
3417                 + mLruProcessActivityStart + "): " + app);
3418         */
3419
3420         if (lrui >= 0) {
3421             if (lrui < mLruProcessActivityStart) {
3422                 mLruProcessActivityStart--;
3423             }
3424             if (lrui < mLruProcessServiceStart) {
3425                 mLruProcessServiceStart--;
3426             }
3427             /*
3428             if (addIndex > lrui) {
3429                 addIndex--;
3430             }
3431             if (nextIndex > lrui) {
3432                 nextIndex--;
3433             }
3434             */
3435             mLruProcesses.remove(lrui);
3436         }
3437
3438         /*
3439         mLruProcesses.add(addIndex, app);
3440         if (inActivity) {
3441             mLruProcessActivityStart++;
3442         }
3443         if (inService) {
3444             mLruProcessActivityStart++;
3445         }
3446         */
3447
3448         int nextIndex;
3449         if (hasActivity) {
3450             final int N = mLruProcesses.size();
3451             if (app.activities.size() == 0 && mLruProcessActivityStart < (N - 1)) {
3452                 // Process doesn't have activities, but has clients with
3453                 // activities...  move it up, but one below the top (the top
3454                 // should always have a real activity).
3455                 if (DEBUG_LRU) Slog.d(TAG_LRU,
3456                         "Adding to second-top of LRU activity list: " + app);
3457                 mLruProcesses.add(N - 1, app);
3458                 // To keep it from spamming the LRU list (by making a bunch of clients),
3459                 // we will push down any other entries owned by the app.
3460                 final int uid = app.info.uid;
3461                 for (int i = N - 2; i > mLruProcessActivityStart; i--) {
3462                     ProcessRecord subProc = mLruProcesses.get(i);
3463                     if (subProc.info.uid == uid) {
3464                         // We want to push this one down the list.  If the process after
3465                         // it is for the same uid, however, don't do so, because we don't
3466                         // want them internally to be re-ordered.
3467                         if (mLruProcesses.get(i - 1).info.uid != uid) {
3468                             if (DEBUG_LRU) Slog.d(TAG_LRU,
3469                                     "Pushing uid " + uid + " swapping at " + i + ": "
3470                                     + mLruProcesses.get(i) + " : " + mLruProcesses.get(i - 1));
3471                             ProcessRecord tmp = mLruProcesses.get(i);
3472                             mLruProcesses.set(i, mLruProcesses.get(i - 1));
3473                             mLruProcesses.set(i - 1, tmp);
3474                             i--;
3475                         }
3476                     } else {
3477                         // A gap, we can stop here.
3478                         break;
3479                     }
3480                 }
3481             } else {
3482                 // Process has activities, put it at the very tipsy-top.
3483                 if (DEBUG_LRU) Slog.d(TAG_LRU, "Adding to top of LRU activity list: " + app);
3484                 mLruProcesses.add(app);
3485             }
3486             nextIndex = mLruProcessServiceStart;
3487         } else if (hasService) {
3488             // Process has services, put it at the top of the service list.
3489             if (DEBUG_LRU) Slog.d(TAG_LRU, "Adding to top of LRU service list: " + app);
3490             mLruProcesses.add(mLruProcessActivityStart, app);
3491             nextIndex = mLruProcessServiceStart;
3492             mLruProcessActivityStart++;
3493         } else  {
3494             // Process not otherwise of interest, it goes to the top of the non-service area.
3495             int index = mLruProcessServiceStart;
3496             if (client != null) {
3497                 // If there is a client, don't allow the process to be moved up higher
3498                 // in the list than that client.
3499                 int clientIndex = mLruProcesses.lastIndexOf(client);
3500                 if (DEBUG_LRU && clientIndex < 0) Slog.d(TAG_LRU, "Unknown client " + client
3501                         + " when updating " + app);
3502                 if (clientIndex <= lrui) {
3503                     // Don't allow the client index restriction to push it down farther in the
3504                     // list than it already is.
3505                     clientIndex = lrui;
3506                 }
3507                 if (clientIndex >= 0 && index > clientIndex) {
3508                     index = clientIndex;
3509                 }
3510             }
3511             if (DEBUG_LRU) Slog.d(TAG_LRU, "Adding at " + index + " of LRU list: " + app);
3512             mLruProcesses.add(index, app);
3513             nextIndex = index-1;
3514             mLruProcessActivityStart++;
3515             mLruProcessServiceStart++;
3516         }
3517
3518         // If the app is currently using a content provider or service,
3519         // bump those processes as well.
3520         for (int j=app.connections.size()-1; j>=0; j--) {
3521             ConnectionRecord cr = app.connections.valueAt(j);
3522             if (cr.binding != null && !cr.serviceDead && cr.binding.service != null
3523                     && cr.binding.service.app != null
3524                     && cr.binding.service.app.lruSeq != mLruSeq
3525                     && !cr.binding.service.app.persistent) {
3526                 nextIndex = updateLruProcessInternalLocked(cr.binding.service.app, now, nextIndex,
3527                         "service connection", cr, app);
3528             }
3529         }
3530         for (int j=app.conProviders.size()-1; j>=0; j--) {
3531             ContentProviderRecord cpr = app.conProviders.get(j).provider;
3532             if (cpr.proc != null && cpr.proc.lruSeq != mLruSeq && !cpr.proc.persistent) {
3533                 nextIndex = updateLruProcessInternalLocked(cpr.proc, now, nextIndex,
3534                         "provider reference", cpr, app);
3535             }
3536         }
3537     }
3538
3539     final ProcessRecord getProcessRecordLocked(String processName, int uid, boolean keepIfLarge) {
3540         if (uid == SYSTEM_UID) {
3541             // The system gets to run in any process.  If there are multiple
3542             // processes with the same uid, just pick the first (this
3543             // should never happen).
3544             SparseArray<ProcessRecord> procs = mProcessNames.getMap().get(processName);
3545             if (procs == null) return null;
3546             final int procCount = procs.size();
3547             for (int i = 0; i < procCount; i++) {
3548                 final int procUid = procs.keyAt(i);
3549                 if (UserHandle.isApp(procUid) || !UserHandle.isSameUser(procUid, uid)) {
3550                     // Don't use an app process or different user process for system component.
3551                     continue;
3552                 }
3553                 return procs.valueAt(i);
3554             }
3555         }
3556         ProcessRecord proc = mProcessNames.get(processName, uid);
3557         if (false && proc != null && !keepIfLarge
3558                 && proc.setProcState >= ActivityManager.PROCESS_STATE_CACHED_EMPTY
3559                 && proc.lastCachedPss >= 4000) {
3560             // Turn this condition on to cause killing to happen regularly, for testing.
3561             if (proc.baseProcessTracker != null) {
3562                 proc.baseProcessTracker.reportCachedKill(proc.pkgList, proc.lastCachedPss);
3563             }
3564             proc.kill(Long.toString(proc.lastCachedPss) + "k from cached", true);
3565         } else if (proc != null && !keepIfLarge
3566                 && mLastMemoryLevel > ProcessStats.ADJ_MEM_FACTOR_NORMAL
3567                 && proc.setProcState >= ActivityManager.PROCESS_STATE_CACHED_EMPTY) {
3568             if (DEBUG_PSS) Slog.d(TAG_PSS, "May not keep " + proc + ": pss=" + proc.lastCachedPss);
3569             if (proc.lastCachedPss >= mProcessList.getCachedRestoreThresholdKb()) {
3570                 if (proc.baseProcessTracker != null) {
3571                     proc.baseProcessTracker.reportCachedKill(proc.pkgList, proc.lastCachedPss);
3572                 }
3573                 proc.kill(Long.toString(proc.lastCachedPss) + "k from cached", true);
3574             }
3575         }
3576         return proc;
3577     }
3578
3579     void notifyPackageUse(String packageName, int reason) {
3580         IPackageManager pm = AppGlobals.getPackageManager();
3581         try {
3582             pm.notifyPackageUse(packageName, reason);
3583         } catch (RemoteException e) {
3584         }
3585     }
3586
3587     boolean isNextTransitionForward() {
3588         int transit = mWindowManager.getPendingAppTransition();
3589         return transit == TRANSIT_ACTIVITY_OPEN
3590                 || transit == TRANSIT_TASK_OPEN
3591                 || transit == TRANSIT_TASK_TO_FRONT;
3592     }
3593
3594     int startIsolatedProcess(String entryPoint, String[] entryPointArgs,
3595             String processName, String abiOverride, int uid, Runnable crashHandler) {
3596         synchronized(this) {
3597             ApplicationInfo info = new ApplicationInfo();
3598             // In general the ApplicationInfo.uid isn't neccesarily equal to ProcessRecord.uid.
3599             // For isolated processes, the former contains the parent's uid and the latter the
3600             // actual uid of the isolated process.
3601             // In the special case introduced by this method (which is, starting an isolated
3602             // process directly from the SystemServer without an actual parent app process) the
3603             // closest thing to a parent's uid is SYSTEM_UID.
3604             // The only important thing here is to keep AI.uid != PR.uid, in order to trigger
3605             // the |isolated| logic in the ProcessRecord constructor.
3606             info.uid = SYSTEM_UID;
3607             info.processName = processName;
3608             info.className = entryPoint;
3609             info.packageName = "android";
3610             info.seInfoUser = SELinuxUtil.COMPLETE_STR;
3611             ProcessRecord proc = startProcessLocked(processName, info /* info */,
3612                     false /* knownToBeDead */, 0 /* intentFlags */, ""  /* hostingType */,
3613                     null /* hostingName */, true /* allowWhileBooting */, true /* isolated */,
3614                     uid, true /* keepIfLarge */, abiOverride, entryPoint, entryPointArgs,
3615                     crashHandler);
3616             return proc != null ? proc.pid : 0;
3617         }
3618     }
3619
3620     final ProcessRecord startProcessLocked(String processName,
3621             ApplicationInfo info, boolean knownToBeDead, int intentFlags,
3622             String hostingType, ComponentName hostingName, boolean allowWhileBooting,
3623             boolean isolated, boolean keepIfLarge) {
3624         return startProcessLocked(processName, info, knownToBeDead, intentFlags, hostingType,
3625                 hostingName, allowWhileBooting, isolated, 0 /* isolatedUid */, keepIfLarge,
3626                 null /* ABI override */, null /* entryPoint */, null /* entryPointArgs */,
3627                 null /* crashHandler */);
3628     }
3629
3630     final ProcessRecord startProcessLocked(String processName, ApplicationInfo info,
3631             boolean knownToBeDead, int intentFlags, String hostingType, ComponentName hostingName,
3632             boolean allowWhileBooting, boolean isolated, int isolatedUid, boolean keepIfLarge,
3633             String abiOverride, String entryPoint, String[] entryPointArgs, Runnable crashHandler) {
3634         long startTime = SystemClock.elapsedRealtime();
3635         ProcessRecord app;
3636         if (!isolated) {
3637             app = getProcessRecordLocked(processName, info.uid, keepIfLarge);
3638             checkTime(startTime, "startProcess: after getProcessRecord");
3639
3640             if ((intentFlags & Intent.FLAG_FROM_BACKGROUND) != 0) {
3641                 // If we are in the background, then check to see if this process
3642                 // is bad.  If so, we will just silently fail.
3643                 if (mAppErrors.isBadProcessLocked(info)) {
3644                     if (DEBUG_PROCESSES) Slog.v(TAG, "Bad process: " + info.uid
3645                             + "/" + info.processName);
3646                     return null;
3647                 }
3648             } else {
3649                 // When the user is explicitly starting a process, then clear its
3650                 // crash count so that we won't make it bad until they see at
3651                 // least one crash dialog again, and make the process good again
3652                 // if it had been bad.
3653                 if (DEBUG_PROCESSES) Slog.v(TAG, "Clearing bad process: " + info.uid
3654                         + "/" + info.processName);
3655                 mAppErrors.resetProcessCrashTimeLocked(info);
3656                 if (mAppErrors.isBadProcessLocked(info)) {
3657                     EventLog.writeEvent(EventLogTags.AM_PROC_GOOD,
3658                             UserHandle.getUserId(info.uid), info.uid,
3659                             info.processName);
3660                     mAppErrors.clearBadProcessLocked(info);
3661                     if (app != null) {
3662                         app.bad = false;
3663                     }
3664                 }
3665             }
3666         } else {
3667             // If this is an isolated process, it can't re-use an existing process.
3668             app = null;
3669         }
3670
3671         // We don't have to do anything more if:
3672         // (1) There is an existing application record; and
3673         // (2) The caller doesn't think it is dead, OR there is no thread
3674         //     object attached to it so we know it couldn't have crashed; and
3675         // (3) There is a pid assigned to it, so it is either starting or
3676         //     already running.
3677         if (DEBUG_PROCESSES) Slog.v(TAG_PROCESSES, "startProcess: name=" + processName
3678                 + " app=" + app + " knownToBeDead=" + knownToBeDead
3679                 + " thread=" + (app != null ? app.thread : null)
3680                 + " pid=" + (app != null ? app.pid : -1));
3681         if (app != null && app.pid > 0) {
3682             if ((!knownToBeDead && !app.killed) || app.thread == null) {
3683                 // We already have the app running, or are waiting for it to
3684                 // come up (we have a pid but not yet its thread), so keep it.
3685                 if (DEBUG_PROCESSES) Slog.v(TAG_PROCESSES, "App already running: " + app);
3686                 // If this is a new package in the process, add the package to the list
3687                 app.addPackage(info.packageName, info.versionCode, mProcessStats);
3688                 checkTime(startTime, "startProcess: done, added package to proc");
3689                 return app;
3690             }
3691
3692             // An application record is attached to a previous process,
3693             // clean it up now.
3694             if (DEBUG_PROCESSES || DEBUG_CLEANUP) Slog.v(TAG_PROCESSES, "App died: " + app);
3695             checkTime(startTime, "startProcess: bad proc running, killing");
3696             killProcessGroup(app.uid, app.pid);
3697             handleAppDiedLocked(app, true, true);
3698             checkTime(startTime, "startProcess: done killing old proc");
3699         }
3700
3701         String hostingNameStr = hostingName != null
3702                 ? hostingName.flattenToShortString() : null;
3703
3704         if (app == null) {
3705             checkTime(startTime, "startProcess: creating new process record");
3706             app = newProcessRecordLocked(info, processName, isolated, isolatedUid);
3707             if (app == null) {
3708                 Slog.w(TAG, "Failed making new process record for "
3709                         + processName + "/" + info.uid + " isolated=" + isolated);
3710                 return null;
3711             }
3712             app.crashHandler = crashHandler;
3713             checkTime(startTime, "startProcess: done creating new process record");
3714         } else {
3715             // If this is a new package in the process, add the package to the list
3716             app.addPackage(info.packageName, info.versionCode, mProcessStats);
3717             checkTime(startTime, "startProcess: added package to existing proc");
3718         }
3719
3720         // If the system is not ready yet, then hold off on starting this
3721         // process until it is.
3722         if (!mProcessesReady
3723                 && !isAllowedWhileBooting(info)
3724                 && !allowWhileBooting) {
3725             if (!mProcessesOnHold.contains(app)) {
3726                 mProcessesOnHold.add(app);
3727             }
3728             if (DEBUG_PROCESSES) Slog.v(TAG_PROCESSES,
3729                     "System not ready, putting on hold: " + app);
3730             checkTime(startTime, "startProcess: returning with proc on hold");
3731             return app;
3732         }
3733
3734         checkTime(startTime, "startProcess: stepping in to startProcess");
3735         startProcessLocked(
3736                 app, hostingType, hostingNameStr, abiOverride, entryPoint, entryPointArgs);
3737         checkTime(startTime, "startProcess: done starting proc!");
3738         return (app.pid != 0) ? app : null;
3739     }
3740
3741     boolean isAllowedWhileBooting(ApplicationInfo ai) {
3742         return (ai.flags&ApplicationInfo.FLAG_PERSISTENT) != 0;
3743     }
3744
3745     private final void startProcessLocked(ProcessRecord app,
3746             String hostingType, String hostingNameStr) {
3747         startProcessLocked(app, hostingType, hostingNameStr, null /* abiOverride */,
3748                 null /* entryPoint */, null /* entryPointArgs */);
3749     }
3750
3751     private final void startProcessLocked(ProcessRecord app, String hostingType,
3752             String hostingNameStr, String abiOverride, String entryPoint, String[] entryPointArgs) {
3753         long startTime = SystemClock.elapsedRealtime();
3754         if (app.pid > 0 && app.pid != MY_PID) {
3755             checkTime(startTime, "startProcess: removing from pids map");
3756             synchronized (mPidsSelfLocked) {
3757                 mPidsSelfLocked.remove(app.pid);
3758                 mHandler.removeMessages(PROC_START_TIMEOUT_MSG, app);
3759             }
3760             checkTime(startTime, "startProcess: done removing from pids map");
3761             app.setPid(0);
3762         }
3763
3764         if (DEBUG_PROCESSES && mProcessesOnHold.contains(app)) Slog.v(TAG_PROCESSES,
3765                 "startProcessLocked removing on hold: " + app);
3766         mProcessesOnHold.remove(app);
3767
3768         checkTime(startTime, "startProcess: starting to update cpu stats");
3769         updateCpuStats();
3770         checkTime(startTime, "startProcess: done updating cpu stats");
3771
3772         try {
3773             try {
3774                 final int userId = UserHandle.getUserId(app.uid);
3775                 AppGlobals.getPackageManager().checkPackageStartable(app.info.packageName, userId);
3776             } catch (RemoteException e) {
3777                 throw e.rethrowAsRuntimeException();
3778             }
3779
3780             int uid = app.uid;
3781             int[] gids = null;
3782             int mountExternal = Zygote.MOUNT_EXTERNAL_NONE;
3783             if (!app.isolated) {
3784                 int[] permGids = null;
3785                 try {
3786                     checkTime(startTime, "startProcess: getting gids from package manager");
3787                     final IPackageManager pm = AppGlobals.getPackageManager();
3788                     permGids = pm.getPackageGids(app.info.packageName,
3789                             MATCH_DEBUG_TRIAGED_MISSING, app.userId);
3790                     StorageManagerInternal storageManagerInternal = LocalServices.getService(
3791                             StorageManagerInternal.class);
3792                     mountExternal = storageManagerInternal.getExternalStorageMountMode(uid,
3793                             app.info.packageName);
3794                 } catch (RemoteException e) {
3795                     throw e.rethrowAsRuntimeException();
3796                 }
3797
3798                 /*
3799                  * Add shared application and profile GIDs so applications can share some
3800                  * resources like shared libraries and access user-wide resources
3801                  */
3802                 if (ArrayUtils.isEmpty(permGids)) {
3803                     gids = new int[3];
3804                 } else {
3805                     gids = new int[permGids.length + 3];
3806                     System.arraycopy(permGids, 0, gids, 3, permGids.length);
3807                 }
3808                 gids[0] = UserHandle.getSharedAppGid(UserHandle.getAppId(uid));
3809                 gids[1] = UserHandle.getCacheAppGid(UserHandle.getAppId(uid));
3810                 gids[2] = UserHandle.getUserGid(UserHandle.getUserId(uid));
3811             }
3812             checkTime(startTime, "startProcess: building args");
3813             if (mFactoryTest != FactoryTest.FACTORY_TEST_OFF) {
3814                 if (mFactoryTest == FactoryTest.FACTORY_TEST_LOW_LEVEL
3815                         && mTopComponent != null
3816                         && app.processName.equals(mTopComponent.getPackageName())) {
3817                     uid = 0;
3818                 }
3819                 if (mFactoryTest == FactoryTest.FACTORY_TEST_HIGH_LEVEL
3820                         && (app.info.flags&ApplicationInfo.FLAG_FACTORY_TEST) != 0) {
3821                     uid = 0;
3822                 }
3823             }
3824             int debugFlags = 0;
3825             if ((app.info.flags & ApplicationInfo.FLAG_DEBUGGABLE) != 0) {
3826                 debugFlags |= Zygote.DEBUG_ENABLE_JDWP;
3827                 debugFlags |= Zygote.DEBUG_JAVA_DEBUGGABLE;
3828                 // Also turn on CheckJNI for debuggable apps. It's quite
3829                 // awkward to turn on otherwise.
3830                 debugFlags |= Zygote.DEBUG_ENABLE_CHECKJNI;
3831             }
3832             // Run the app in safe mode if its manifest requests so or the
3833             // system is booted in safe mode.
3834             if ((app.info.flags & ApplicationInfo.FLAG_VM_SAFE_MODE) != 0 ||
3835                 mSafeMode == true) {
3836                 debugFlags |= Zygote.DEBUG_ENABLE_SAFEMODE;
3837             }
3838             if ("1".equals(SystemProperties.get("debug.checkjni"))) {
3839                 debugFlags |= Zygote.DEBUG_ENABLE_CHECKJNI;
3840             }
3841             String genDebugInfoProperty = SystemProperties.get("debug.generate-debug-info");
3842             if ("true".equals(genDebugInfoProperty)) {
3843                 debugFlags |= Zygote.DEBUG_GENERATE_DEBUG_INFO;
3844             }
3845             if ("1".equals(SystemProperties.get("debug.jni.logging"))) {
3846                 debugFlags |= Zygote.DEBUG_ENABLE_JNI_LOGGING;
3847             }
3848             if ("1".equals(SystemProperties.get("debug.assert"))) {
3849                 debugFlags |= Zygote.DEBUG_ENABLE_ASSERT;
3850             }
3851             if (mNativeDebuggingApp != null && mNativeDebuggingApp.equals(app.processName)) {
3852                 // Enable all debug flags required by the native debugger.
3853                 debugFlags |= Zygote.DEBUG_ALWAYS_JIT;          // Don't interpret anything
3854                 debugFlags |= Zygote.DEBUG_GENERATE_DEBUG_INFO; // Generate debug info
3855                 debugFlags |= Zygote.DEBUG_NATIVE_DEBUGGABLE;   // Disbale optimizations
3856                 mNativeDebuggingApp = null;
3857             }
3858
3859             String invokeWith = null;
3860             if ((app.info.flags & ApplicationInfo.FLAG_DEBUGGABLE) != 0) {
3861                 // Debuggable apps may include a wrapper script with their library directory.
3862                 String wrapperFileName = app.info.nativeLibraryDir + "/wrap.sh";
3863                 StrictMode.ThreadPolicy oldPolicy = StrictMode.allowThreadDiskReads();
3864                 try {
3865                     if (new File(wrapperFileName).exists()) {
3866                         invokeWith = "/system/bin/logwrapper " + wrapperFileName;
3867                     }
3868                 } finally {
3869                     StrictMode.setThreadPolicy(oldPolicy);
3870                 }
3871             }
3872
3873             String requiredAbi = (abiOverride != null) ? abiOverride : app.info.primaryCpuAbi;
3874             if (requiredAbi == null) {
3875                 requiredAbi = Build.SUPPORTED_ABIS[0];
3876             }
3877
3878             String instructionSet = null;
3879             if (app.info.primaryCpuAbi != null) {
3880                 instructionSet = VMRuntime.getInstructionSet(app.info.primaryCpuAbi);
3881             }
3882
3883             app.gids = gids;
3884             app.requiredAbi = requiredAbi;
3885             app.instructionSet = instructionSet;
3886
3887             // the per-user SELinux context must be set
3888             if (TextUtils.isEmpty(app.info.seInfoUser)) {
3889                 Slog.wtf(TAG, "SELinux tag not defined",
3890                         new IllegalStateException("SELinux tag not defined for "
3891                         + app.info.packageName + " (uid " + app.uid + ")"));
3892             }
3893             final String seInfo = app.info.seInfo
3894                     + (TextUtils.isEmpty(app.info.seInfoUser) ? "" : app.info.seInfoUser);
3895             // Start the process.  It will either succeed and return a result containing
3896             // the PID of the new process, or else throw a RuntimeException.
3897             boolean isActivityProcess = (entryPoint == null);
3898             if (entryPoint == null) entryPoint = "android.app.ActivityThread";
3899             Trace.traceBegin(Trace.TRACE_TAG_ACTIVITY_MANAGER, "Start proc: " +
3900                     app.processName);
3901             checkTime(startTime, "startProcess: asking zygote to start proc");
3902             ProcessStartResult startResult;
3903             if (hostingType.equals("webview_service")) {
3904                 startResult = startWebView(entryPoint,
3905                         app.processName, uid, uid, gids, debugFlags, mountExternal,
3906                         app.info.targetSdkVersion, seInfo, requiredAbi, instructionSet,
3907                         app.info.dataDir, null, entryPointArgs);
3908             } else {
3909                 startResult = Process.start(entryPoint,
3910                         app.processName, uid, uid, gids, debugFlags, mountExternal,
3911                         app.info.targetSdkVersion, seInfo, requiredAbi, instructionSet,
3912                         app.info.dataDir, invokeWith, entryPointArgs);
3913             }
3914             checkTime(startTime, "startProcess: returned from zygote!");
3915             Trace.traceEnd(Trace.TRACE_TAG_ACTIVITY_MANAGER);
3916
3917             mBatteryStatsService.noteProcessStart(app.processName, app.info.uid);
3918             checkTime(startTime, "startProcess: done updating battery stats");
3919
3920             EventLog.writeEvent(EventLogTags.AM_PROC_START,
3921                     UserHandle.getUserId(uid), startResult.pid, uid,
3922                     app.processName, hostingType,
3923                     hostingNameStr != null ? hostingNameStr : "");
3924
3925             try {
3926                 AppGlobals.getPackageManager().logAppProcessStartIfNeeded(app.processName, app.uid,
3927                         seInfo, app.info.sourceDir, startResult.pid);
3928             } catch (RemoteException ex) {
3929                 // Ignore
3930             }
3931
3932             if (app.persistent) {
3933                 Watchdog.getInstance().processStarted(app.processName, startResult.pid);
3934             }
3935
3936             checkTime(startTime, "startProcess: building log message");
3937             StringBuilder buf = mStringBuilder;
3938             buf.setLength(0);
3939             buf.append("Start proc ");
3940             buf.append(startResult.pid);
3941             buf.append(':');
3942             buf.append(app.processName);
3943             buf.append('/');
3944             UserHandle.formatUid(buf, uid);
3945             if (!isActivityProcess) {
3946                 buf.append(" [");
3947                 buf.append(entryPoint);
3948                 buf.append("]");
3949             }
3950             buf.append(" for ");
3951             buf.append(hostingType);
3952             if (hostingNameStr != null) {
3953                 buf.append(" ");
3954                 buf.append(hostingNameStr);
3955             }
3956             Slog.i(TAG, buf.toString());
3957             app.setPid(startResult.pid);
3958             app.usingWrapper = startResult.usingWrapper;
3959             app.removed = false;
3960             app.killed = false;
3961             app.killedByAm = false;
3962             checkTime(startTime, "startProcess: starting to update pids map");
3963             ProcessRecord oldApp;
3964             synchronized (mPidsSelfLocked) {
3965                 oldApp = mPidsSelfLocked.get(startResult.pid);
3966             }
3967             // If there is already an app occupying that pid that hasn't been cleaned up
3968             if (oldApp != null && !app.isolated) {
3969                 // Clean up anything relating to this pid first
3970                 Slog.w(TAG, "Reusing pid " + startResult.pid
3971                         + " while app is still mapped to it");
3972                 cleanUpApplicationRecordLocked(oldApp, false, false, -1,
3973                         true /*replacingPid*/);
3974             }
3975             synchronized (mPidsSelfLocked) {
3976                 this.mPidsSelfLocked.put(startResult.pid, app);
3977                 if (isActivityProcess) {
3978                     Message msg = mHandler.obtainMessage(PROC_START_TIMEOUT_MSG);
3979                     msg.obj = app;
3980                     mHandler.sendMessageDelayed(msg, startResult.usingWrapper
3981                             ? PROC_START_TIMEOUT_WITH_WRAPPER : PROC_START_TIMEOUT);
3982                 }
3983             }
3984             checkTime(startTime, "startProcess: done updating pids map");
3985         } catch (RuntimeException e) {
3986             Slog.e(TAG, "Failure starting process " + app.processName, e);
3987
3988             // Something went very wrong while trying to start this process; one
3989             // common case is when the package is frozen due to an active
3990             // upgrade. To recover, clean up any active bookkeeping related to
3991             // starting this process. (We already invoked this method once when
3992             // the package was initially frozen through KILL_APPLICATION_MSG, so
3993             // it doesn't hurt to use it again.)
3994             forceStopPackageLocked(app.info.packageName, UserHandle.getAppId(app.uid), false,
3995                     false, true, false, false, UserHandle.getUserId(app.userId), "start failure");
3996         }
3997     }
3998
3999     void updateUsageStats(ActivityRecord component, boolean resumed) {
4000         if (DEBUG_SWITCH) Slog.d(TAG_SWITCH,
4001                 "updateUsageStats: comp=" + component + "res=" + resumed);
4002         final BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
4003         if (resumed) {
4004             if (mUsageStatsService != null) {
4005                 mUsageStatsService.reportEvent(component.realActivity, component.userId,
4006                         UsageEvents.Event.MOVE_TO_FOREGROUND);
4007             }
4008             synchronized (stats) {
4009                 stats.noteActivityResumedLocked(component.app.uid);
4010             }
4011         } else {
4012             if (mUsageStatsService != null) {
4013                 mUsageStatsService.reportEvent(component.realActivity, component.userId,
4014                         UsageEvents.Event.MOVE_TO_BACKGROUND);
4015             }
4016             synchronized (stats) {
4017                 stats.noteActivityPausedLocked(component.app.uid);
4018             }
4019         }
4020     }
4021
4022     Intent getHomeIntent() {
4023         Intent intent = new Intent(mTopAction, mTopData != null ? Uri.parse(mTopData) : null);
4024         intent.setComponent(mTopComponent);
4025         intent.addFlags(Intent.FLAG_DEBUG_TRIAGED_MISSING);
4026         if (mFactoryTest != FactoryTest.FACTORY_TEST_LOW_LEVEL) {
4027             intent.addCategory(Intent.CATEGORY_HOME);
4028         }
4029         return intent;
4030     }
4031
4032     boolean startHomeActivityLocked(int userId, String reason) {
4033         if (mFactoryTest == FactoryTest.FACTORY_TEST_LOW_LEVEL
4034                 && mTopAction == null) {
4035             // We are running in factory test mode, but unable to find
4036             // the factory test app, so just sit around displaying the
4037             // error message and don't try to start anything.
4038             return false;
4039         }
4040         Intent intent = getHomeIntent();
4041         ActivityInfo aInfo = resolveActivityInfo(intent, STOCK_PM_FLAGS, userId);
4042         if (aInfo != null) {
4043             intent.setComponent(new ComponentName(aInfo.applicationInfo.packageName, aInfo.name));
4044             // Don't do this if the home app is currently being
4045             // instrumented.
4046             aInfo = new ActivityInfo(aInfo);
4047             aInfo.applicationInfo = getAppInfoForUser(aInfo.applicationInfo, userId);
4048             ProcessRecord app = getProcessRecordLocked(aInfo.processName,
4049                     aInfo.applicationInfo.uid, true);
4050             if (app == null || app.instr == null) {
4051                 intent.setFlags(intent.getFlags() | Intent.FLAG_ACTIVITY_NEW_TASK);
4052                 final int resolvedUserId = UserHandle.getUserId(aInfo.applicationInfo.uid);
4053                 // For ANR debugging to verify if the user activity is the one that actually
4054                 // launched.
4055                 final String myReason = reason + ":" + userId + ":" + resolvedUserId;
4056                 mActivityStarter.startHomeActivityLocked(intent, aInfo, myReason);
4057             }
4058         } else {
4059             Slog.wtf(TAG, "No home screen found for " + intent, new Throwable());
4060         }
4061
4062         return true;
4063     }
4064
4065     private ActivityInfo resolveActivityInfo(Intent intent, int flags, int userId) {
4066         ActivityInfo ai = null;
4067         ComponentName comp = intent.getComponent();
4068         try {
4069             if (comp != null) {
4070                 // Factory test.
4071                 ai = AppGlobals.getPackageManager().getActivityInfo(comp, flags, userId);
4072             } else {
4073                 ResolveInfo info = AppGlobals.getPackageManager().resolveIntent(
4074                         intent,
4075                         intent.resolveTypeIfNeeded(mContext.getContentResolver()),
4076                         flags, userId);
4077
4078                 if (info != null) {
4079                     ai = info.activityInfo;
4080                 }
4081             }
4082         } catch (RemoteException e) {
4083             // ignore
4084         }
4085
4086         return ai;
4087     }
4088
4089     /**
4090      * Starts the "new version setup screen" if appropriate.
4091      */
4092     void startSetupActivityLocked() {
4093         // Only do this once per boot.
4094         if (mCheckedForSetup) {
4095             return;
4096         }
4097
4098         // We will show this screen if the current one is a different
4099         // version than the last one shown, and we are not running in
4100         // low-level factory test mode.
4101         final ContentResolver resolver = mContext.getContentResolver();
4102         if (mFactoryTest != FactoryTest.FACTORY_TEST_LOW_LEVEL &&
4103                 Settings.Global.getInt(resolver,
4104                         Settings.Global.DEVICE_PROVISIONED, 0) != 0) {
4105             mCheckedForSetup = true;
4106
4107             // See if we should be showing the platform update setup UI.
4108             final Intent intent = new Intent(Intent.ACTION_UPGRADE_SETUP);
4109             final List<ResolveInfo> ris = mContext.getPackageManager().queryIntentActivities(intent,
4110                     PackageManager.MATCH_SYSTEM_ONLY | PackageManager.GET_META_DATA);
4111             if (!ris.isEmpty()) {
4112                 final ResolveInfo ri = ris.get(0);
4113                 String vers = ri.activityInfo.metaData != null
4114                         ? ri.activityInfo.metaData.getString(Intent.METADATA_SETUP_VERSION)
4115                         : null;
4116                 if (vers == null && ri.activityInfo.applicationInfo.metaData != null) {
4117                     vers = ri.activityInfo.applicationInfo.metaData.getString(
4118                             Intent.METADATA_SETUP_VERSION);
4119                 }
4120                 String lastVers = Settings.Secure.getString(
4121                         resolver, Settings.Secure.LAST_SETUP_SHOWN);
4122                 if (vers != null && !vers.equals(lastVers)) {
4123                     intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
4124                     intent.setComponent(new ComponentName(
4125                             ri.activityInfo.packageName, ri.activityInfo.name));
4126                     mActivityStarter.startActivityLocked(null, intent, null /*ephemeralIntent*/,
4127                             null, ri.activityInfo, null /*rInfo*/, null, null, null, null, 0, 0, 0,
4128                             null, 0, 0, 0, null, false, false, null, null, null,
4129                             "startSetupActivity");
4130                 }
4131             }
4132         }
4133     }
4134
4135     CompatibilityInfo compatibilityInfoForPackageLocked(ApplicationInfo ai) {
4136         return mCompatModePackages.compatibilityInfoForPackageLocked(ai);
4137     }
4138
4139     void enforceNotIsolatedCaller(String caller) {
4140         if (UserHandle.isIsolated(Binder.getCallingUid())) {
4141             throw new SecurityException("Isolated process not allowed to call " + caller);
4142         }
4143     }
4144
4145     void enforceShellRestriction(String restriction, int userHandle) {
4146         if (Binder.getCallingUid() == SHELL_UID) {
4147             if (userHandle < 0 || mUserController.hasUserRestriction(restriction, userHandle)) {
4148                 throw new SecurityException("Shell does not have permission to access user "
4149                         + userHandle);
4150             }
4151         }
4152     }
4153
4154     @Override
4155     public int getFrontActivityScreenCompatMode() {
4156         enforceNotIsolatedCaller("getFrontActivityScreenCompatMode");
4157         synchronized (this) {
4158             return mCompatModePackages.getFrontActivityScreenCompatModeLocked();
4159         }
4160     }
4161
4162     @Override
4163     public void setFrontActivityScreenCompatMode(int mode) {
4164         enforceCallingPermission(android.Manifest.permission.SET_SCREEN_COMPATIBILITY,
4165                 "setFrontActivityScreenCompatMode");
4166         synchronized (this) {
4167             mCompatModePackages.setFrontActivityScreenCompatModeLocked(mode);
4168         }
4169     }
4170
4171     @Override
4172     public int getPackageScreenCompatMode(String packageName) {
4173         enforceNotIsolatedCaller("getPackageScreenCompatMode");
4174         synchronized (this) {
4175             return mCompatModePackages.getPackageScreenCompatModeLocked(packageName);
4176         }
4177     }
4178
4179     @Override
4180     public void setPackageScreenCompatMode(String packageName, int mode) {
4181         enforceCallingPermission(android.Manifest.permission.SET_SCREEN_COMPATIBILITY,
4182                 "setPackageScreenCompatMode");
4183         synchronized (this) {
4184             mCompatModePackages.setPackageScreenCompatModeLocked(packageName, mode);
4185         }
4186     }
4187
4188     @Override
4189     public boolean getPackageAskScreenCompat(String packageName) {
4190         enforceNotIsolatedCaller("getPackageAskScreenCompat");
4191         synchronized (this) {
4192             return mCompatModePackages.getPackageAskCompatModeLocked(packageName);
4193         }
4194     }
4195
4196     @Override
4197     public void setPackageAskScreenCompat(String packageName, boolean ask) {
4198         enforceCallingPermission(android.Manifest.permission.SET_SCREEN_COMPATIBILITY,
4199                 "setPackageAskScreenCompat");
4200         synchronized (this) {
4201             mCompatModePackages.setPackageAskCompatModeLocked(packageName, ask);
4202         }
4203     }
4204
4205     private boolean hasUsageStatsPermission(String callingPackage) {
4206         final int mode = mAppOpsService.checkOperation(AppOpsManager.OP_GET_USAGE_STATS,
4207                 Binder.getCallingUid(), callingPackage);
4208         if (mode == AppOpsManager.MODE_DEFAULT) {
4209             return checkCallingPermission(Manifest.permission.PACKAGE_USAGE_STATS)
4210                     == PackageManager.PERMISSION_GRANTED;
4211         }
4212         return mode == AppOpsManager.MODE_ALLOWED;
4213     }
4214
4215     @Override
4216     public int getPackageProcessState(String packageName, String callingPackage) {
4217         if (!hasUsageStatsPermission(callingPackage)) {
4218             enforceCallingPermission(android.Manifest.permission.PACKAGE_USAGE_STATS,
4219                     "getPackageProcessState");
4220         }
4221
4222         int procState = ActivityManager.PROCESS_STATE_NONEXISTENT;
4223         synchronized (this) {
4224             for (int i=mLruProcesses.size()-1; i>=0; i--) {
4225                 final ProcessRecord proc = mLruProcesses.get(i);
4226                 if (procState > proc.setProcState) {
4227                     if (proc.pkgList.containsKey(packageName) ||
4228                             (proc.pkgDeps != null && proc.pkgDeps.contains(packageName))) {
4229                         procState = proc.setProcState;
4230                     }
4231                 }
4232             }
4233         }
4234         return procState;
4235     }
4236
4237     @Override
4238     public boolean setProcessMemoryTrimLevel(String process, int userId, int level)
4239             throws RemoteException {
4240         synchronized (this) {
4241             final ProcessRecord app = findProcessLocked(process, userId, "setProcessMemoryTrimLevel");
4242             if (app == null) {
4243                 throw new IllegalArgumentException("Unknown process: " + process);
4244             }
4245             if (app.thread == null) {
4246                 throw new IllegalArgumentException("Process has no app thread");
4247             }
4248             if (app.trimMemoryLevel >= level) {
4249                 throw new IllegalArgumentException(
4250                         "Unable to set a higher trim level than current level");
4251             }
4252             if (!(level < ComponentCallbacks2.TRIM_MEMORY_UI_HIDDEN ||
4253                     app.curProcState > ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND)) {
4254                 throw new IllegalArgumentException("Unable to set a background trim level "
4255                     + "on a foreground process");
4256             }
4257             app.thread.scheduleTrimMemory(level);
4258             app.trimMemoryLevel = level;
4259             return true;
4260         }
4261     }
4262
4263     private void dispatchProcessesChanged() {
4264         int N;
4265         synchronized (this) {
4266             N = mPendingProcessChanges.size();
4267             if (mActiveProcessChanges.length < N) {
4268                 mActiveProcessChanges = new ProcessChangeItem[N];
4269             }
4270             mPendingProcessChanges.toArray(mActiveProcessChanges);
4271             mPendingProcessChanges.clear();
4272             if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG_PROCESS_OBSERVERS,
4273                     "*** Delivering " + N + " process changes");
4274         }
4275
4276         int i = mProcessObservers.beginBroadcast();
4277         while (i > 0) {
4278             i--;
4279             final IProcessObserver observer = mProcessObservers.getBroadcastItem(i);
4280             if (observer != null) {
4281                 try {
4282                     for (int j=0; j<N; j++) {
4283                         ProcessChangeItem item = mActiveProcessChanges[j];
4284                         if ((item.changes&ProcessChangeItem.CHANGE_ACTIVITIES) != 0) {
4285                             if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG_PROCESS_OBSERVERS,
4286                                     "ACTIVITIES CHANGED pid=" + item.pid + " uid="
4287                                     + item.uid + ": " + item.foregroundActivities);
4288                             observer.onForegroundActivitiesChanged(item.pid, item.uid,
4289                                     item.foregroundActivities);
4290                         }
4291                     }
4292                 } catch (RemoteException e) {
4293                 }
4294             }
4295         }
4296         mProcessObservers.finishBroadcast();
4297
4298         synchronized (this) {
4299             for (int j=0; j<N; j++) {
4300                 mAvailProcessChanges.add(mActiveProcessChanges[j]);
4301             }
4302         }
4303     }
4304
4305     private void dispatchProcessDied(int pid, int uid) {
4306         int i = mProcessObservers.beginBroadcast();
4307         while (i > 0) {
4308             i--;
4309             final IProcessObserver observer = mProcessObservers.getBroadcastItem(i);
4310             if (observer != null) {
4311                 try {
4312                     observer.onProcessDied(pid, uid);
4313                 } catch (RemoteException e) {
4314                 }
4315             }
4316         }
4317         mProcessObservers.finishBroadcast();
4318     }
4319
4320     @VisibleForTesting
4321     void dispatchUidsChanged() {
4322         int N;
4323         synchronized (this) {
4324             N = mPendingUidChanges.size();
4325             if (mActiveUidChanges.length < N) {
4326                 mActiveUidChanges = new UidRecord.ChangeItem[N];
4327             }
4328             for (int i=0; i<N; i++) {
4329                 final UidRecord.ChangeItem change = mPendingUidChanges.get(i);
4330                 mActiveUidChanges[i] = change;
4331                 if (change.uidRecord != null) {
4332                     change.uidRecord.pendingChange = null;
4333                     change.uidRecord = null;
4334                 }
4335             }
4336             mPendingUidChanges.clear();
4337             if (DEBUG_UID_OBSERVERS) Slog.i(TAG_UID_OBSERVERS,
4338                     "*** Delivering " + N + " uid changes");
4339         }
4340
4341         int i = mUidObservers.beginBroadcast();
4342         while (i > 0) {
4343             i--;
4344             dispatchUidsChangedForObserver(mUidObservers.getBroadcastItem(i),
4345                     (UidObserverRegistration) mUidObservers.getBroadcastCookie(i), N);
4346         }
4347         mUidObservers.finishBroadcast();
4348
4349         if (VALIDATE_UID_STATES && mUidObservers.getRegisteredCallbackCount() > 0) {
4350             for (int j = 0; j < N; ++j) {
4351                 final UidRecord.ChangeItem item = mActiveUidChanges[j];
4352                 if (item.change == UidRecord.CHANGE_GONE
4353                         || item.change == UidRecord.CHANGE_GONE_IDLE) {
4354                     mValidateUids.remove(item.uid);
4355                 } else {
4356                     UidRecord validateUid = mValidateUids.get(item.uid);
4357                     if (validateUid == null) {
4358                         validateUid = new UidRecord(item.uid);
4359                         mValidateUids.put(item.uid, validateUid);
4360                     }
4361                     if (item.change == UidRecord.CHANGE_IDLE) {
4362                         validateUid.idle = true;
4363                     } else if (item.change == UidRecord.CHANGE_ACTIVE) {
4364                         validateUid.idle = false;
4365                     }
4366                     validateUid.curProcState = validateUid.setProcState = item.processState;
4367                     validateUid.lastDispatchedProcStateSeq = item.procStateSeq;
4368                 }
4369             }
4370         }
4371
4372         synchronized (this) {
4373             for (int j = 0; j < N; j++) {
4374                 mAvailUidChanges.add(mActiveUidChanges[j]);
4375             }
4376         }
4377     }
4378
4379     private void dispatchUidsChangedForObserver(IUidObserver observer,
4380             UidObserverRegistration reg, int changesSize) {
4381         if (observer == null) {
4382             return;
4383         }
4384         try {
4385             for (int j = 0; j < changesSize; j++) {
4386                 UidRecord.ChangeItem item = mActiveUidChanges[j];
4387                 final int change = item.change;
4388                 if (change == UidRecord.CHANGE_IDLE
4389                         || change == UidRecord.CHANGE_GONE_IDLE) {
4390                     if ((reg.which & ActivityManager.UID_OBSERVER_IDLE) != 0) {
4391                         if (DEBUG_UID_OBSERVERS) Slog.i(TAG_UID_OBSERVERS,
4392                                 "UID idle uid=" + item.uid);
4393                         observer.onUidIdle(item.uid, item.ephemeral);
4394                     }
4395                 } else if (change == UidRecord.CHANGE_ACTIVE) {
4396                     if ((reg.which & ActivityManager.UID_OBSERVER_ACTIVE) != 0) {
4397                         if (DEBUG_UID_OBSERVERS) Slog.i(TAG_UID_OBSERVERS,
4398                                 "UID active uid=" + item.uid);
4399                         observer.onUidActive(item.uid);
4400                     }
4401                 }
4402                 if (change == UidRecord.CHANGE_GONE
4403                         || change == UidRecord.CHANGE_GONE_IDLE) {
4404                     if ((reg.which & ActivityManager.UID_OBSERVER_GONE) != 0) {
4405                         if (DEBUG_UID_OBSERVERS) Slog.i(TAG_UID_OBSERVERS,
4406                                 "UID gone uid=" + item.uid);
4407                         observer.onUidGone(item.uid, item.ephemeral);
4408                     }
4409                     if (reg.lastProcStates != null) {
4410                         reg.lastProcStates.delete(item.uid);
4411                     }
4412                 } else {
4413                     if ((reg.which & ActivityManager.UID_OBSERVER_PROCSTATE) != 0) {
4414                         if (DEBUG_UID_OBSERVERS) Slog.i(TAG_UID_OBSERVERS,
4415                                 "UID CHANGED uid=" + item.uid
4416                                         + ": " + item.processState);
4417                         boolean doReport = true;
4418                         if (reg.cutpoint >= ActivityManager.MIN_PROCESS_STATE) {
4419                             final int lastState = reg.lastProcStates.get(item.uid,
4420                                     ActivityManager.PROCESS_STATE_UNKNOWN);
4421                             if (lastState != ActivityManager.PROCESS_STATE_UNKNOWN) {
4422                                 final boolean lastAboveCut = lastState <= reg.cutpoint;
4423                                 final boolean newAboveCut = item.processState <= reg.cutpoint;
4424                                 doReport = lastAboveCut != newAboveCut;
4425                             } else {
4426                                 doReport = item.processState
4427                                         != ActivityManager.PROCESS_STATE_NONEXISTENT;
4428                             }
4429                         }
4430                         if (doReport) {
4431                             if (reg.lastProcStates != null) {
4432                                 reg.lastProcStates.put(item.uid, item.processState);
4433                             }
4434                             observer.onUidStateChanged(item.uid, item.processState,
4435                                     item.procStateSeq);
4436                         }
4437                     }
4438                 }
4439             }
4440         } catch (RemoteException e) {
4441         }
4442     }
4443
4444     @Override
4445     public final int startActivity(IApplicationThread caller, String callingPackage,
4446             Intent intent, String resolvedType, IBinder resultTo, String resultWho, int requestCode,
4447             int startFlags, ProfilerInfo profilerInfo, Bundle bOptions) {
4448         return startActivityAsUser(caller, callingPackage, intent, resolvedType, resultTo,
4449                 resultWho, requestCode, startFlags, profilerInfo, bOptions,
4450                 UserHandle.getCallingUserId());
4451     }
4452
4453     final int startActivity(Intent intent, ActivityStackSupervisor.ActivityContainer container) {
4454         enforceNotIsolatedCaller("ActivityContainer.startActivity");
4455         final int userId = mUserController.handleIncomingUser(Binder.getCallingPid(),
4456                 Binder.getCallingUid(), mStackSupervisor.mCurrentUser, false,
4457                 ActivityManagerService.ALLOW_FULL_ONLY, "ActivityContainer", null);
4458
4459         // TODO: Switch to user app stacks here.
4460         String mimeType = intent.getType();
4461         final Uri data = intent.getData();
4462         if (mimeType == null && data != null && "content".equals(data.getScheme())) {
4463             mimeType = getProviderMimeType(data, userId);
4464         }
4465         container.checkEmbeddedAllowedInner(userId, intent, mimeType);
4466
4467         intent.addFlags(FORCE_NEW_TASK_FLAGS);
4468         return mActivityStarter.startActivityMayWait(null, -1, null, intent, mimeType, null, null,
4469                 null, null, 0, 0, null, null, null, null, false, userId, container, null,
4470                 "startActivity");
4471     }
4472
4473     @Override
4474     public final int startActivityAsUser(IApplicationThread caller, String callingPackage,
4475             Intent intent, String resolvedType, IBinder resultTo, String resultWho, int requestCode,
4476             int startFlags, ProfilerInfo profilerInfo, Bundle bOptions, int userId) {
4477         enforceNotIsolatedCaller("startActivity");
4478         userId = mUserController.handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(),
4479                 userId, false, ALLOW_FULL_ONLY, "startActivity", null);
4480         // TODO: Switch to user app stacks here.
4481         return mActivityStarter.startActivityMayWait(caller, -1, callingPackage, intent,
4482                 resolvedType, null, null, resultTo, resultWho, requestCode, startFlags,
4483                 profilerInfo, null, null, bOptions, false, userId, null, null,
4484                 "startActivityAsUser");
4485     }
4486
4487     @Override
4488     public final int startActivityAsCaller(IApplicationThread caller, String callingPackage,
4489             Intent intent, String resolvedType, IBinder resultTo, String resultWho, int requestCode,
4490             int startFlags, ProfilerInfo profilerInfo, Bundle bOptions, boolean ignoreTargetSecurity,
4491             int userId) {
4492
4493         // This is very dangerous -- it allows you to perform a start activity (including
4494         // permission grants) as any app that may launch one of your own activities.  So
4495         // we will only allow this to be done from activities that are part of the core framework,
4496         // and then only when they are running as the system.
4497         final ActivityRecord sourceRecord;
4498         final int targetUid;
4499         final String targetPackage;
4500         synchronized (this) {
4501             if (resultTo == null) {
4502                 throw new SecurityException("Must be called from an activity");
4503             }
4504             sourceRecord = mStackSupervisor.isInAnyStackLocked(resultTo);
4505             if (sourceRecord == null) {
4506                 throw new SecurityException("Called with bad activity token: " + resultTo);
4507             }
4508             if (!sourceRecord.info.packageName.equals("android")) {
4509                 throw new SecurityException(
4510                         "Must be called from an activity that is declared in the android package");
4511             }
4512             if (sourceRecord.app == null) {
4513                 throw new SecurityException("Called without a process attached to activity");
4514             }
4515             if (UserHandle.getAppId(sourceRecord.app.uid) != SYSTEM_UID) {
4516                 // This is still okay, as long as this activity is running under the
4517                 // uid of the original calling activity.
4518                 if (sourceRecord.app.uid != sourceRecord.launchedFromUid) {
4519                     throw new SecurityException(
4520                             "Calling activity in uid " + sourceRecord.app.uid
4521                                     + " must be system uid or original calling uid "
4522                                     + sourceRecord.launchedFromUid);
4523                 }
4524             }
4525             if (ignoreTargetSecurity) {
4526                 if (intent.getComponent() == null) {
4527                     throw new SecurityException(
4528                             "Component must be specified with ignoreTargetSecurity");
4529                 }
4530                 if (intent.getSelector() != null) {
4531                     throw new SecurityException(
4532                             "Selector not allowed with ignoreTargetSecurity");
4533                 }
4534             }
4535             targetUid = sourceRecord.launchedFromUid;
4536             targetPackage = sourceRecord.launchedFromPackage;
4537         }
4538
4539         if (userId == UserHandle.USER_NULL) {
4540             userId = UserHandle.getUserId(sourceRecord.app.uid);
4541         }
4542
4543         // TODO: Switch to user app stacks here.
4544         try {
4545             int ret = mActivityStarter.startActivityMayWait(null, targetUid, targetPackage, intent,
4546                     resolvedType, null, null, resultTo, resultWho, requestCode, startFlags, null,
4547                     null, null, bOptions, ignoreTargetSecurity, userId, null, null,
4548                     "startActivityAsCaller");
4549             return ret;
4550         } catch (SecurityException e) {
4551             // XXX need to figure out how to propagate to original app.
4552             // A SecurityException here is generally actually a fault of the original
4553             // calling activity (such as a fairly granting permissions), so propagate it
4554             // back to them.
4555             /*
4556             StringBuilder msg = new StringBuilder();
4557             msg.append("While launching");
4558             msg.append(intent.toString());
4559             msg.append(": ");
4560             msg.append(e.getMessage());
4561             */
4562             throw e;
4563         }
4564     }
4565
4566     @Override
4567     public final WaitResult startActivityAndWait(IApplicationThread caller, String callingPackage,
4568             Intent intent, String resolvedType, IBinder resultTo, String resultWho, int requestCode,
4569             int startFlags, ProfilerInfo profilerInfo, Bundle bOptions, int userId) {
4570         enforceNotIsolatedCaller("startActivityAndWait");
4571         userId = mUserController.handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(),
4572                 userId, false, ALLOW_FULL_ONLY, "startActivityAndWait", null);
4573         WaitResult res = new WaitResult();
4574         // TODO: Switch to user app stacks here.
4575         mActivityStarter.startActivityMayWait(caller, -1, callingPackage, intent, resolvedType,
4576                 null, null, resultTo, resultWho, requestCode, startFlags, profilerInfo, res, null,
4577                 bOptions, false, userId, null, null, "startActivityAndWait");
4578         return res;
4579     }
4580
4581     @Override
4582     public final int startActivityWithConfig(IApplicationThread caller, String callingPackage,
4583             Intent intent, String resolvedType, IBinder resultTo, String resultWho, int requestCode,
4584             int startFlags, Configuration config, Bundle bOptions, int userId) {
4585         enforceNotIsolatedCaller("startActivityWithConfig");
4586         userId = mUserController.handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(),
4587                 userId, false, ALLOW_FULL_ONLY, "startActivityWithConfig", null);
4588         // TODO: Switch to user app stacks here.
4589         int ret = mActivityStarter.startActivityMayWait(caller, -1, callingPackage, intent,
4590                 resolvedType, null, null, resultTo, resultWho, requestCode, startFlags,
4591                 null, null, config, bOptions, false, userId, null, null, "startActivityWithConfig");
4592         return ret;
4593     }
4594
4595     @Override
4596     public int startActivityIntentSender(IApplicationThread caller, IIntentSender target,
4597             IBinder whitelistToken, Intent fillInIntent, String resolvedType, IBinder resultTo,
4598             String resultWho, int requestCode, int flagsMask, int flagsValues, Bundle bOptions)
4599             throws TransactionTooLargeException {
4600         enforceNotIsolatedCaller("startActivityIntentSender");
4601         // Refuse possible leaked file descriptors
4602         if (fillInIntent != null && fillInIntent.hasFileDescriptors()) {
4603             throw new IllegalArgumentException("File descriptors passed in Intent");
4604         }
4605
4606         if (!(target instanceof PendingIntentRecord)) {
4607             throw new IllegalArgumentException("Bad PendingIntent object");
4608         }
4609
4610         PendingIntentRecord pir = (PendingIntentRecord)target;
4611
4612         synchronized (this) {
4613             // If this is coming from the currently resumed activity, it is
4614             // effectively saying that app switches are allowed at this point.
4615             final ActivityStack stack = getFocusedStack();
4616             if (stack.mResumedActivity != null &&
4617                     stack.mResumedActivity.info.applicationInfo.uid == Binder.getCallingUid()) {
4618                 mAppSwitchesAllowedTime = 0;
4619             }
4620         }
4621         int ret = pir.sendInner(0, fillInIntent, resolvedType, whitelistToken, null, null,
4622                 resultTo, resultWho, requestCode, flagsMask, flagsValues, bOptions, null);
4623         return ret;
4624     }
4625
4626     @Override
4627     public int startVoiceActivity(String callingPackage, int callingPid, int callingUid,
4628             Intent intent, String resolvedType, IVoiceInteractionSession session,
4629             IVoiceInteractor interactor, int startFlags, ProfilerInfo profilerInfo,
4630             Bundle bOptions, int userId) {
4631         if (checkCallingPermission(Manifest.permission.BIND_VOICE_INTERACTION)
4632                 != PackageManager.PERMISSION_GRANTED) {
4633             String msg = "Permission Denial: startVoiceActivity() from pid="
4634                     + Binder.getCallingPid()
4635                     + ", uid=" + Binder.getCallingUid()
4636                     + " requires " + android.Manifest.permission.BIND_VOICE_INTERACTION;
4637             Slog.w(TAG, msg);
4638             throw new SecurityException(msg);
4639         }
4640         if (session == null || interactor == null) {
4641             throw new NullPointerException("null session or interactor");
4642         }
4643         userId = mUserController.handleIncomingUser(callingPid, callingUid, userId, false,
4644                 ALLOW_FULL_ONLY, "startVoiceActivity", null);
4645         // TODO: Switch to user app stacks here.
4646         return mActivityStarter.startActivityMayWait(null, callingUid, callingPackage, intent,
4647                 resolvedType, session, interactor, null, null, 0, startFlags, profilerInfo, null,
4648                 null, bOptions, false, userId, null, null, "startVoiceActivity");
4649     }
4650
4651     @Override
4652     public int startAssistantActivity(String callingPackage, int callingPid, int callingUid,
4653             Intent intent, String resolvedType, Bundle bOptions, int userId) {
4654         if (checkCallingPermission(Manifest.permission.BIND_VOICE_INTERACTION)
4655                 != PackageManager.PERMISSION_GRANTED) {
4656             final String msg = "Permission Denial: startAssistantActivity() from pid="
4657                     + Binder.getCallingPid()
4658                     + ", uid=" + Binder.getCallingUid()
4659                     + " requires " + Manifest.permission.BIND_VOICE_INTERACTION;
4660             Slog.w(TAG, msg);
4661             throw new SecurityException(msg);
4662         }
4663         userId = mUserController.handleIncomingUser(callingPid, callingUid, userId, false,
4664                 ALLOW_FULL_ONLY, "startAssistantActivity", null);
4665         return mActivityStarter.startActivityMayWait(null, callingUid, callingPackage, intent,
4666                 resolvedType, null, null, null, null, 0, 0, null, null, null, bOptions, false,
4667                 userId, null, null, "startAssistantActivity");
4668     }
4669
4670     @Override
4671     public void startLocalVoiceInteraction(IBinder callingActivity, Bundle options)
4672             throws RemoteException {
4673         Slog.i(TAG, "Activity tried to startVoiceInteraction");
4674         synchronized (this) {
4675             ActivityRecord activity = getFocusedStack().topActivity();
4676             if (ActivityRecord.forTokenLocked(callingActivity) != activity) {
4677                 throw new SecurityException("Only focused activity can call startVoiceInteraction");
4678             }
4679             if (mRunningVoice != null || activity.getTask().voiceSession != null
4680                     || activity.voiceSession != null) {
4681                 Slog.w(TAG, "Already in a voice interaction, cannot start new voice interaction");
4682                 return;
4683             }
4684             if (activity.pendingVoiceInteractionStart) {
4685                 Slog.w(TAG, "Pending start of voice interaction already.");
4686                 return;
4687             }
4688             activity.pendingVoiceInteractionStart = true;
4689         }
4690         LocalServices.getService(VoiceInteractionManagerInternal.class)
4691                 .startLocalVoiceInteraction(callingActivity, options);
4692     }
4693
4694     @Override
4695     public void stopLocalVoiceInteraction(IBinder callingActivity) throws RemoteException {
4696         LocalServices.getService(VoiceInteractionManagerInternal.class)
4697                 .stopLocalVoiceInteraction(callingActivity);
4698     }
4699
4700     @Override
4701     public boolean supportsLocalVoiceInteraction() throws RemoteException {
4702         return LocalServices.getService(VoiceInteractionManagerInternal.class)
4703                 .supportsLocalVoiceInteraction();
4704     }
4705
4706     void onLocalVoiceInteractionStartedLocked(IBinder activity,
4707             IVoiceInteractionSession voiceSession, IVoiceInteractor voiceInteractor) {
4708         ActivityRecord activityToCallback = ActivityRecord.forTokenLocked(activity);
4709         if (activityToCallback == null) return;
4710         activityToCallback.setVoiceSessionLocked(voiceSession);
4711
4712         // Inform the activity
4713         try {
4714             activityToCallback.app.thread.scheduleLocalVoiceInteractionStarted(activity,
4715                     voiceInteractor);
4716             long token = Binder.clearCallingIdentity();
4717             try {
4718                 startRunningVoiceLocked(voiceSession, activityToCallback.appInfo.uid);
4719             } finally {
4720                 Binder.restoreCallingIdentity(token);
4721             }
4722             // TODO: VI Should we cache the activity so that it's easier to find later
4723             // rather than scan through all the stacks and activities?
4724         } catch (RemoteException re) {
4725             activityToCallback.clearVoiceSessionLocked();
4726             // TODO: VI Should this terminate the voice session?
4727         }
4728     }
4729
4730     @Override
4731     public void setVoiceKeepAwake(IVoiceInteractionSession session, boolean keepAwake) {
4732         synchronized (this) {
4733             if (mRunningVoice != null && mRunningVoice.asBinder() == session.asBinder()) {
4734                 if (keepAwake) {
4735                     mVoiceWakeLock.acquire();
4736                 } else {
4737                     mVoiceWakeLock.release();
4738                 }
4739             }
4740         }
4741     }
4742
4743     @Override
4744     public boolean startNextMatchingActivity(IBinder callingActivity,
4745             Intent intent, Bundle bOptions) {
4746         // Refuse possible leaked file descriptors
4747         if (intent != null && intent.hasFileDescriptors() == true) {
4748             throw new IllegalArgumentException("File descriptors passed in Intent");
4749         }
4750         ActivityOptions options = ActivityOptions.fromBundle(bOptions);
4751
4752         synchronized (this) {
4753             final ActivityRecord r = ActivityRecord.isInStackLocked(callingActivity);
4754             if (r == null) {
4755                 ActivityOptions.abort(options);
4756                 return false;
4757             }
4758             if (r.app == null || r.app.thread == null) {
4759                 // The caller is not running...  d'oh!
4760                 ActivityOptions.abort(options);
4761                 return false;
4762             }
4763             intent = new Intent(intent);
4764             // The caller is not allowed to change the data.
4765             intent.setDataAndType(r.intent.getData(), r.intent.getType());
4766             // And we are resetting to find the next component...
4767             intent.setComponent(null);
4768
4769             final boolean debug = ((intent.getFlags() & Intent.FLAG_DEBUG_LOG_RESOLUTION) != 0);
4770
4771             ActivityInfo aInfo = null;
4772             try {
4773                 List<ResolveInfo> resolves =
4774                     AppGlobals.getPackageManager().queryIntentActivities(
4775                             intent, r.resolvedType,
4776                             PackageManager.MATCH_DEFAULT_ONLY | STOCK_PM_FLAGS,
4777                             UserHandle.getCallingUserId()).getList();
4778
4779                 // Look for the original activity in the list...
4780                 final int N = resolves != null ? resolves.size() : 0;
4781                 for (int i=0; i<N; i++) {
4782                     ResolveInfo rInfo = resolves.get(i);
4783                     if (rInfo.activityInfo.packageName.equals(r.packageName)
4784                             && rInfo.activityInfo.name.equals(r.info.name)) {
4785                         // We found the current one...  the next matching is
4786                         // after it.
4787                         i++;
4788                         if (i<N) {
4789                             aInfo = resolves.get(i).activityInfo;
4790                         }
4791                         if (debug) {
4792                             Slog.v(TAG, "Next matching activity: found current " + r.packageName
4793                                     + "/" + r.info.name);
4794                             Slog.v(TAG, "Next matching activity: next is " + ((aInfo == null)
4795                                     ? "null" : aInfo.packageName + "/" + aInfo.name));
4796                         }
4797                         break;
4798                     }
4799                 }
4800             } catch (RemoteException e) {
4801             }
4802
4803             if (aInfo == null) {
4804                 // Nobody who is next!
4805                 ActivityOptions.abort(options);
4806                 if (debug) Slog.d(TAG, "Next matching activity: nothing found");
4807                 return false;
4808             }
4809
4810             intent.setComponent(new ComponentName(
4811                     aInfo.applicationInfo.packageName, aInfo.name));
4812             intent.setFlags(intent.getFlags()&~(
4813                     Intent.FLAG_ACTIVITY_FORWARD_RESULT|
4814                     Intent.FLAG_ACTIVITY_CLEAR_TOP|
4815                     Intent.FLAG_ACTIVITY_MULTIPLE_TASK|
4816                     Intent.FLAG_ACTIVITY_NEW_TASK));
4817
4818             // Okay now we need to start the new activity, replacing the
4819             // currently running activity.  This is a little tricky because
4820             // we want to start the new one as if the current one is finished,
4821             // but not finish the current one first so that there is no flicker.
4822             // And thus...
4823             final boolean wasFinishing = r.finishing;
4824             r.finishing = true;
4825
4826             // Propagate reply information over to the new activity.
4827             final ActivityRecord resultTo = r.resultTo;
4828             final String resultWho = r.resultWho;
4829             final int requestCode = r.requestCode;
4830             r.resultTo = null;
4831             if (resultTo != null) {
4832                 resultTo.removeResultsLocked(r, resultWho, requestCode);
4833             }
4834
4835             final long origId = Binder.clearCallingIdentity();
4836             int res = mActivityStarter.startActivityLocked(r.app.thread, intent,
4837                     null /*ephemeralIntent*/, r.resolvedType, aInfo, null /*rInfo*/, null,
4838                     null, resultTo != null ? resultTo.appToken : null, resultWho, requestCode, -1,
4839                     r.launchedFromUid, r.launchedFromPackage, -1, r.launchedFromUid, 0, options,
4840                     false, false, null, null, null, "startNextMatchingActivity");
4841             Binder.restoreCallingIdentity(origId);
4842
4843             r.finishing = wasFinishing;
4844             if (res != ActivityManager.START_SUCCESS) {
4845                 return false;
4846             }
4847             return true;
4848         }
4849     }
4850
4851     @Override
4852     public final int startActivityFromRecents(int taskId, Bundle bOptions) {
4853         if (checkCallingPermission(START_TASKS_FROM_RECENTS) != PackageManager.PERMISSION_GRANTED) {
4854             String msg = "Permission Denial: startActivityFromRecents called without " +
4855                     START_TASKS_FROM_RECENTS;
4856             Slog.w(TAG, msg);
4857             throw new SecurityException(msg);
4858         }
4859         final long origId = Binder.clearCallingIdentity();
4860         try {
4861             synchronized (this) {
4862                 return mStackSupervisor.startActivityFromRecentsInner(taskId, bOptions);
4863             }
4864         } finally {
4865             Binder.restoreCallingIdentity(origId);
4866         }
4867     }
4868
4869     final int startActivityInPackage(int uid, String callingPackage,
4870             Intent intent, String resolvedType, IBinder resultTo,
4871             String resultWho, int requestCode, int startFlags, Bundle bOptions, int userId,
4872             IActivityContainer container, TaskRecord inTask, String reason) {
4873
4874         userId = mUserController.handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(),
4875                 userId, false, ALLOW_FULL_ONLY, "startActivityInPackage", null);
4876
4877         // TODO: Switch to user app stacks here.
4878         int ret = mActivityStarter.startActivityMayWait(null, uid, callingPackage, intent,
4879                 resolvedType, null, null, resultTo, resultWho, requestCode, startFlags,
4880                 null, null, null, bOptions, false, userId, container, inTask, reason);
4881         return ret;
4882     }
4883
4884     @Override
4885     public final int startActivities(IApplicationThread caller, String callingPackage,
4886             Intent[] intents, String[] resolvedTypes, IBinder resultTo, Bundle bOptions,
4887             int userId) {
4888         final String reason = "startActivities";
4889         enforceNotIsolatedCaller(reason);
4890         userId = mUserController.handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(),
4891                 userId, false, ALLOW_FULL_ONLY, reason, null);
4892         // TODO: Switch to user app stacks here.
4893         int ret = mActivityStarter.startActivities(caller, -1, callingPackage, intents,
4894                 resolvedTypes, resultTo, bOptions, userId, reason);
4895         return ret;
4896     }
4897
4898     final int startActivitiesInPackage(int uid, String callingPackage,
4899             Intent[] intents, String[] resolvedTypes, IBinder resultTo,
4900             Bundle bOptions, int userId) {
4901
4902         final String reason = "startActivityInPackage";
4903         userId = mUserController.handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(),
4904                 userId, false, ALLOW_FULL_ONLY, reason, null);
4905         // TODO: Switch to user app stacks here.
4906         int ret = mActivityStarter.startActivities(null, uid, callingPackage, intents, resolvedTypes,
4907                 resultTo, bOptions, userId, reason);
4908         return ret;
4909     }
4910
4911     @Override
4912     public void reportActivityFullyDrawn(IBinder token) {
4913         synchronized (this) {
4914             ActivityRecord r = ActivityRecord.isInStackLocked(token);
4915             if (r == null) {
4916                 return;
4917             }
4918             r.reportFullyDrawnLocked();
4919         }
4920     }
4921
4922     @Override
4923     public void setRequestedOrientation(IBinder token, int requestedOrientation) {
4924         synchronized (this) {
4925             ActivityRecord r = ActivityRecord.isInStackLocked(token);
4926             if (r == null) {
4927                 return;
4928             }
4929             final long origId = Binder.clearCallingIdentity();
4930             try {
4931                 r.setRequestedOrientation(requestedOrientation);
4932             } finally {
4933                 Binder.restoreCallingIdentity(origId);
4934             }
4935         }
4936     }
4937
4938     @Override
4939     public int getRequestedOrientation(IBinder token) {
4940         synchronized (this) {
4941             ActivityRecord r = ActivityRecord.isInStackLocked(token);
4942             if (r == null) {
4943                 return ActivityInfo.SCREEN_ORIENTATION_UNSPECIFIED;
4944             }
4945             return r.getRequestedOrientation();
4946         }
4947     }
4948
4949     @Override
4950     public final void requestActivityRelaunch(IBinder token) {
4951         synchronized(this) {
4952             ActivityRecord r = ActivityRecord.isInStackLocked(token);
4953             if (r == null) {
4954                 return;
4955             }
4956             final long origId = Binder.clearCallingIdentity();
4957             try {
4958                 r.forceNewConfig = true;
4959                 r.ensureActivityConfigurationLocked(0 /* globalChanges */,
4960                         true /* preserveWindow */);
4961             } finally {
4962                 Binder.restoreCallingIdentity(origId);
4963             }
4964         }
4965     }
4966
4967     /**
4968      * This is the internal entry point for handling Activity.finish().
4969      *
4970      * @param token The Binder token referencing the Activity we want to finish.
4971      * @param resultCode Result code, if any, from this Activity.
4972      * @param resultData Result data (Intent), if any, from this Activity.
4973      * @param finishTask Whether to finish the task associated with this Activity.
4974      *
4975      * @return Returns true if the activity successfully finished, or false if it is still running.
4976      */
4977     @Override
4978     public final boolean finishActivity(IBinder token, int resultCode, Intent resultData,
4979             int finishTask) {
4980         // Refuse possible leaked file descriptors
4981         if (resultData != null && resultData.hasFileDescriptors() == true) {
4982             throw new IllegalArgumentException("File descriptors passed in Intent");
4983         }
4984
4985         synchronized(this) {
4986             ActivityRecord r = ActivityRecord.isInStackLocked(token);
4987             if (r == null) {
4988                 return true;
4989             }
4990             // Keep track of the root activity of the task before we finish it
4991             TaskRecord tr = r.getTask();
4992             ActivityRecord rootR = tr.getRootActivity();
4993             if (rootR == null) {
4994                 Slog.w(TAG, "Finishing task with all activities already finished");
4995             }
4996             // Do not allow task to finish if last task in lockTask mode. Launchable priv-apps can
4997             // finish.
4998             if (tr.mLockTaskAuth != LOCK_TASK_AUTH_LAUNCHABLE_PRIV && rootR == r &&
4999                     mStackSupervisor.isLastLockedTask(tr)) {
5000                 Slog.i(TAG, "Not finishing task in lock task mode");
5001                 mStackSupervisor.showLockTaskToast();
5002                 return false;
5003             }
5004             if (mController != null) {
5005                 // Find the first activity that is not finishing.
5006                 ActivityRecord next = r.getStack().topRunningActivityLocked(token, 0);
5007                 if (next != null) {
5008                     // ask watcher if this is allowed
5009                     boolean resumeOK = true;
5010                     try {
5011                         resumeOK = mController.activityResuming(next.packageName);
5012                     } catch (RemoteException e) {
5013                         mController = null;
5014                         Watchdog.getInstance().setActivityController(null);
5015                     }
5016
5017                     if (!resumeOK) {
5018                         Slog.i(TAG, "Not finishing activity because controller resumed");
5019                         return false;
5020                     }
5021                 }
5022             }
5023             final long origId = Binder.clearCallingIdentity();
5024             try {
5025                 boolean res;
5026                 final boolean finishWithRootActivity =
5027                         finishTask == Activity.FINISH_TASK_WITH_ROOT_ACTIVITY;
5028                 if (finishTask == Activity.FINISH_TASK_WITH_ACTIVITY
5029                         || (finishWithRootActivity && r == rootR)) {
5030                     // If requested, remove the task that is associated to this activity only if it
5031                     // was the root activity in the task. The result code and data is ignored
5032                     // because we don't support returning them across task boundaries. Also, to
5033                     // keep backwards compatibility we remove the task from recents when finishing
5034                     // task with root activity.
5035                     res = mStackSupervisor.removeTaskByIdLocked(tr.taskId, false, finishWithRootActivity);
5036                     if (!res) {
5037                         Slog.i(TAG, "Removing task failed to finish activity");
5038                     }
5039                 } else {
5040                     res = tr.getStack().requestFinishActivityLocked(token, resultCode,
5041                             resultData, "app-request", true);
5042                     if (!res) {
5043                         Slog.i(TAG, "Failed to finish by app-request");
5044                     }
5045                 }
5046                 return res;
5047             } finally {
5048                 Binder.restoreCallingIdentity(origId);
5049             }
5050         }
5051     }
5052
5053     @Override
5054     public final void finishHeavyWeightApp() {
5055         if (checkCallingPermission(android.Manifest.permission.FORCE_STOP_PACKAGES)
5056                 != PackageManager.PERMISSION_GRANTED) {
5057             String msg = "Permission Denial: finishHeavyWeightApp() from pid="
5058                     + Binder.getCallingPid()
5059                     + ", uid=" + Binder.getCallingUid()
5060                     + " requires " + android.Manifest.permission.FORCE_STOP_PACKAGES;
5061             Slog.w(TAG, msg);
5062             throw new SecurityException(msg);
5063         }
5064
5065         synchronized(this) {
5066             if (mHeavyWeightProcess == null) {
5067                 return;
5068             }
5069
5070             ArrayList<ActivityRecord> activities = new ArrayList<>(mHeavyWeightProcess.activities);
5071             for (int i = 0; i < activities.size(); i++) {
5072                 ActivityRecord r = activities.get(i);
5073                 if (!r.finishing && r.isInStackLocked()) {
5074                     r.getStack().finishActivityLocked(r, Activity.RESULT_CANCELED,
5075                             null, "finish-heavy", true);
5076                 }
5077             }
5078
5079             mHandler.sendMessage(mHandler.obtainMessage(CANCEL_HEAVY_NOTIFICATION_MSG,
5080                     mHeavyWeightProcess.userId, 0));
5081             mHeavyWeightProcess = null;
5082         }
5083     }
5084
5085     @Override
5086     public void crashApplication(int uid, int initialPid, String packageName, int userId,
5087             String message) {
5088         if (checkCallingPermission(android.Manifest.permission.FORCE_STOP_PACKAGES)
5089                 != PackageManager.PERMISSION_GRANTED) {
5090             String msg = "Permission Denial: crashApplication() from pid="
5091                     + Binder.getCallingPid()
5092                     + ", uid=" + Binder.getCallingUid()
5093                     + " requires " + android.Manifest.permission.FORCE_STOP_PACKAGES;
5094             Slog.w(TAG, msg);
5095             throw new SecurityException(msg);
5096         }
5097
5098         synchronized(this) {
5099             mAppErrors.scheduleAppCrashLocked(uid, initialPid, packageName, userId, message);
5100         }
5101     }
5102
5103     @Override
5104     public final void finishSubActivity(IBinder token, String resultWho,
5105             int requestCode) {
5106         synchronized(this) {
5107             final long origId = Binder.clearCallingIdentity();
5108             ActivityRecord r = ActivityRecord.isInStackLocked(token);
5109             if (r != null) {
5110                 r.getStack().finishSubActivityLocked(r, resultWho, requestCode);
5111             }
5112             Binder.restoreCallingIdentity(origId);
5113         }
5114     }
5115
5116     @Override
5117     public boolean finishActivityAffinity(IBinder token) {
5118         synchronized(this) {
5119             final long origId = Binder.clearCallingIdentity();
5120             try {
5121                 ActivityRecord r = ActivityRecord.isInStackLocked(token);
5122                 if (r == null) {
5123                     return false;
5124                 }
5125
5126                 // Do not allow task to finish if last task in lockTask mode. Launchable priv-apps
5127                 // can finish.
5128                 final TaskRecord task = r.getTask();
5129                 if (task.mLockTaskAuth != LOCK_TASK_AUTH_LAUNCHABLE_PRIV &&
5130                         mStackSupervisor.isLastLockedTask(task) && task.getRootActivity() == r) {
5131                     mStackSupervisor.showLockTaskToast();
5132                     return false;
5133                 }
5134                 return task.getStack().finishActivityAffinityLocked(r);
5135             } finally {
5136                 Binder.restoreCallingIdentity(origId);
5137             }
5138         }
5139     }
5140
5141     @Override
5142     public void finishVoiceTask(IVoiceInteractionSession session) {
5143         synchronized (this) {
5144             final long origId = Binder.clearCallingIdentity();
5145             try {
5146                 // TODO: VI Consider treating local voice interactions and voice tasks
5147                 // differently here
5148                 mStackSupervisor.finishVoiceTask(session);
5149             } finally {
5150                 Binder.restoreCallingIdentity(origId);
5151             }
5152         }
5153
5154     }
5155
5156     @Override
5157     public boolean releaseActivityInstance(IBinder token) {
5158         synchronized(this) {
5159             final long origId = Binder.clearCallingIdentity();
5160             try {
5161                 ActivityRecord r = ActivityRecord.isInStackLocked(token);
5162                 if (r == null) {
5163                     return false;
5164                 }
5165                 return r.getStack().safelyDestroyActivityLocked(r, "app-req");
5166             } finally {
5167                 Binder.restoreCallingIdentity(origId);
5168             }
5169         }
5170     }
5171
5172     @Override
5173     public void releaseSomeActivities(IApplicationThread appInt) {
5174         synchronized(this) {
5175             final long origId = Binder.clearCallingIdentity();
5176             try {
5177                 ProcessRecord app = getRecordForAppLocked(appInt);
5178                 mStackSupervisor.releaseSomeActivitiesLocked(app, "low-mem");
5179             } finally {
5180                 Binder.restoreCallingIdentity(origId);
5181             }
5182         }
5183     }
5184
5185     @Override
5186     public boolean willActivityBeVisible(IBinder token) {
5187         synchronized(this) {
5188             ActivityStack stack = ActivityRecord.getStackLocked(token);
5189             if (stack != null) {
5190                 return stack.willActivityBeVisibleLocked(token);
5191             }
5192             return false;
5193         }
5194     }
5195
5196     @Override
5197     public void overridePendingTransition(IBinder token, String packageName,
5198             int enterAnim, int exitAnim) {
5199         synchronized(this) {
5200             ActivityRecord self = ActivityRecord.isInStackLocked(token);
5201             if (self == null) {
5202                 return;
5203             }
5204
5205             final long origId = Binder.clearCallingIdentity();
5206
5207             if (self.state == ActivityState.RESUMED
5208                     || self.state == ActivityState.PAUSING) {
5209                 mWindowManager.overridePendingAppTransition(packageName,
5210                         enterAnim, exitAnim, null);
5211             }
5212
5213             Binder.restoreCallingIdentity(origId);
5214         }
5215     }
5216
5217     /**
5218      * Main function for removing an existing process from the activity manager
5219      * as a result of that process going away.  Clears out all connections
5220      * to the process.
5221      */
5222     private final void handleAppDiedLocked(ProcessRecord app,
5223             boolean restarting, boolean allowRestart) {
5224         int pid = app.pid;
5225         boolean kept = cleanUpApplicationRecordLocked(app, restarting, allowRestart, -1,
5226                 false /*replacingPid*/);
5227         if (!kept && !restarting) {
5228             removeLruProcessLocked(app);
5229             if (pid > 0) {
5230                 ProcessList.remove(pid);
5231             }
5232         }
5233
5234         if (mProfileProc == app) {
5235             clearProfilerLocked();
5236         }
5237
5238         // Remove this application's activities from active lists.
5239         boolean hasVisibleActivities = mStackSupervisor.handleAppDiedLocked(app);
5240
5241         app.activities.clear();
5242
5243         if (app.instr != null) {
5244             Slog.w(TAG, "Crash of app " + app.processName
5245                   + " running instrumentation " + app.instr.mClass);
5246             Bundle info = new Bundle();
5247             info.putString("shortMsg", "Process crashed.");
5248             finishInstrumentationLocked(app, Activity.RESULT_CANCELED, info);
5249         }
5250
5251         mWindowManager.deferSurfaceLayout();
5252         try {
5253             if (!restarting && hasVisibleActivities
5254                     && !mStackSupervisor.resumeFocusedStackTopActivityLocked()) {
5255                 // If there was nothing to resume, and we are not already restarting this process, but
5256                 // there is a visible activity that is hosted by the process...  then make sure all
5257                 // visible activities are running, taking care of restarting this process.
5258                 mStackSupervisor.ensureActivitiesVisibleLocked(null, 0, !PRESERVE_WINDOWS);
5259             }
5260         } finally {
5261             mWindowManager.continueSurfaceLayout();
5262         }
5263     }
5264
5265     private final int getLRURecordIndexForAppLocked(IApplicationThread thread) {
5266         final IBinder threadBinder = thread.asBinder();
5267         // Find the application record.
5268         for (int i=mLruProcesses.size()-1; i>=0; i--) {
5269             final ProcessRecord rec = mLruProcesses.get(i);
5270             if (rec.thread != null && rec.thread.asBinder() == threadBinder) {
5271                 return i;
5272             }
5273         }
5274         return -1;
5275     }
5276
5277     final ProcessRecord getRecordForAppLocked(
5278             IApplicationThread thread) {
5279         if (thread == null) {
5280             return null;
5281         }
5282
5283         int appIndex = getLRURecordIndexForAppLocked(thread);
5284         if (appIndex >= 0) {
5285             return mLruProcesses.get(appIndex);
5286         }
5287
5288         // Validation: if it isn't in the LRU list, it shouldn't exist, but let's
5289         // double-check that.
5290         final IBinder threadBinder = thread.asBinder();
5291         final ArrayMap<String, SparseArray<ProcessRecord>> pmap = mProcessNames.getMap();
5292         for (int i = pmap.size()-1; i >= 0; i--) {
5293             final SparseArray<ProcessRecord> procs = pmap.valueAt(i);
5294             for (int j = procs.size()-1; j >= 0; j--) {
5295                 final ProcessRecord proc = procs.valueAt(j);
5296                 if (proc.thread != null && proc.thread.asBinder() == threadBinder) {
5297                     Slog.wtf(TAG, "getRecordForApp: exists in name list but not in LRU list: "
5298                             + proc);
5299                     return proc;
5300                 }
5301             }
5302         }
5303
5304         return null;
5305     }
5306
5307     final void doLowMemReportIfNeededLocked(ProcessRecord dyingProc) {
5308         // If there are no longer any background processes running,
5309         // and the app that died was not running instrumentation,
5310         // then tell everyone we are now low on memory.
5311         boolean haveBg = false;
5312         for (int i=mLruProcesses.size()-1; i>=0; i--) {
5313             ProcessRecord rec = mLruProcesses.get(i);
5314             if (rec.thread != null
5315                     && rec.setProcState >= ActivityManager.PROCESS_STATE_CACHED_ACTIVITY) {
5316                 haveBg = true;
5317                 break;
5318             }
5319         }
5320
5321         if (!haveBg) {
5322             boolean doReport = "1".equals(SystemProperties.get(SYSTEM_DEBUGGABLE, "0"));
5323             if (doReport) {
5324                 long now = SystemClock.uptimeMillis();
5325                 if (now < (mLastMemUsageReportTime+5*60*1000)) {
5326                     doReport = false;
5327                 } else {
5328                     mLastMemUsageReportTime = now;
5329                 }
5330             }
5331             final ArrayList<ProcessMemInfo> memInfos
5332                     = doReport ? new ArrayList<ProcessMemInfo>(mLruProcesses.size()) : null;
5333             EventLog.writeEvent(EventLogTags.AM_LOW_MEMORY, mLruProcesses.size());
5334             long now = SystemClock.uptimeMillis();
5335             for (int i=mLruProcesses.size()-1; i>=0; i--) {
5336                 ProcessRecord rec = mLruProcesses.get(i);
5337                 if (rec == dyingProc || rec.thread == null) {
5338                     continue;
5339                 }
5340                 if (doReport) {
5341                     memInfos.add(new ProcessMemInfo(rec.processName, rec.pid, rec.setAdj,
5342                             rec.setProcState, rec.adjType, rec.makeAdjReason()));
5343                 }
5344                 if ((rec.lastLowMemory+mConstants.GC_MIN_INTERVAL) <= now) {
5345                     // The low memory report is overriding any current
5346                     // state for a GC request.  Make sure to do
5347                     // heavy/important/visible/foreground processes first.
5348                     if (rec.setAdj <= ProcessList.HEAVY_WEIGHT_APP_ADJ) {
5349                         rec.lastRequestedGc = 0;
5350                     } else {
5351                         rec.lastRequestedGc = rec.lastLowMemory;
5352                     }
5353                     rec.reportLowMemory = true;
5354                     rec.lastLowMemory = now;
5355                     mProcessesToGc.remove(rec);
5356                     addProcessToGcListLocked(rec);
5357                 }
5358             }
5359             if (doReport) {
5360                 Message msg = mHandler.obtainMessage(REPORT_MEM_USAGE_MSG, memInfos);
5361                 mHandler.sendMessage(msg);
5362             }
5363             scheduleAppGcsLocked();
5364         }
5365     }
5366
5367     final void appDiedLocked(ProcessRecord app) {
5368        appDiedLocked(app, app.pid, app.thread, false);
5369     }
5370
5371     final void appDiedLocked(ProcessRecord app, int pid, IApplicationThread thread,
5372             boolean fromBinderDied) {
5373         // First check if this ProcessRecord is actually active for the pid.
5374         synchronized (mPidsSelfLocked) {
5375             ProcessRecord curProc = mPidsSelfLocked.get(pid);
5376             if (curProc != app) {
5377                 Slog.w(TAG, "Spurious death for " + app + ", curProc for " + pid + ": " + curProc);
5378                 return;
5379             }
5380         }
5381
5382         BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
5383         synchronized (stats) {
5384             stats.noteProcessDiedLocked(app.info.uid, pid);
5385         }
5386
5387         if (!app.killed) {
5388             if (!fromBinderDied) {
5389                 killProcessQuiet(pid);
5390             }
5391             killProcessGroup(app.uid, pid);
5392             app.killed = true;
5393         }
5394
5395         // Clean up already done if the process has been re-started.
5396         if (app.pid == pid && app.thread != null &&
5397                 app.thread.asBinder() == thread.asBinder()) {
5398             boolean doLowMem = app.instr == null;
5399             boolean doOomAdj = doLowMem;
5400             if (!app.killedByAm) {
5401                 Slog.i(TAG, "Process " + app.processName + " (pid " + pid + ") has died: "
5402                         + ProcessList.makeOomAdjString(app.setAdj)
5403                         + ProcessList.makeProcStateString(app.setProcState));
5404                 mAllowLowerMemLevel = true;
5405             } else {
5406                 // Note that we always want to do oom adj to update our state with the
5407                 // new number of procs.
5408                 mAllowLowerMemLevel = false;
5409                 doLowMem = false;
5410             }
5411             EventLog.writeEvent(EventLogTags.AM_PROC_DIED, app.userId, app.pid, app.processName,
5412                     app.setAdj, app.setProcState);
5413             if (DEBUG_CLEANUP) Slog.v(TAG_CLEANUP,
5414                 "Dying app: " + app + ", pid: " + pid + ", thread: " + thread.asBinder());
5415             handleAppDiedLocked(app, false, true);
5416
5417             if (doOomAdj) {
5418                 updateOomAdjLocked();
5419             }
5420             if (doLowMem) {
5421                 doLowMemReportIfNeededLocked(app);
5422             }
5423         } else if (app.pid != pid) {
5424             // A new process has already been started.
5425             Slog.i(TAG, "Process " + app.processName + " (pid " + pid
5426                     + ") has died and restarted (pid " + app.pid + ").");
5427             EventLog.writeEvent(EventLogTags.AM_PROC_DIED, app.userId, app.pid, app.processName);
5428         } else if (DEBUG_PROCESSES) {
5429             Slog.d(TAG_PROCESSES, "Received spurious death notification for thread "
5430                     + thread.asBinder());
5431         }
5432     }
5433
5434     /**
5435      * If a stack trace dump file is configured, dump process stack traces.
5436      * @param clearTraces causes the dump file to be erased prior to the new
5437      *    traces being written, if true; when false, the new traces will be
5438      *    appended to any existing file content.
5439      * @param firstPids of dalvik VM processes to dump stack traces for first
5440      * @param lastPids of dalvik VM processes to dump stack traces for last
5441      * @param nativePids optional list of native pids to dump stack crawls
5442      */
5443     public static File dumpStackTraces(boolean clearTraces, ArrayList<Integer> firstPids,
5444             ProcessCpuTracker processCpuTracker, SparseArray<Boolean> lastPids,
5445             ArrayList<Integer> nativePids) {
5446         ArrayList<Integer> extraPids = null;
5447
5448         // Measure CPU usage as soon as we're called in order to get a realistic sampling
5449         // of the top users at the time of the request.
5450         if (processCpuTracker != null) {
5451             processCpuTracker.init();
5452             try {
5453                 Thread.sleep(200);
5454             } catch (InterruptedException ignored) {
5455             }
5456
5457             processCpuTracker.update();
5458
5459             // We'll take the stack crawls of just the top apps using CPU.
5460             final int N = processCpuTracker.countWorkingStats();
5461             extraPids = new ArrayList<>();
5462             for (int i = 0; i < N && extraPids.size() < 5; i++) {
5463                 ProcessCpuTracker.Stats stats = processCpuTracker.getWorkingStats(i);
5464                 if (lastPids.indexOfKey(stats.pid) >= 0) {
5465                     if (DEBUG_ANR) Slog.d(TAG, "Collecting stacks for extra pid " + stats.pid);
5466
5467                     extraPids.add(stats.pid);
5468                 } else if (DEBUG_ANR) {
5469                     Slog.d(TAG, "Skipping next CPU consuming process, not a java proc: "
5470                             + stats.pid);
5471                 }
5472             }
5473         }
5474
5475         boolean useTombstonedForJavaTraces = false;
5476         File tracesFile;
5477
5478         final String tracesDir = SystemProperties.get("dalvik.vm.stack-trace-dir", "");
5479         if (tracesDir.isEmpty()) {
5480             // When dalvik.vm.stack-trace-dir is not set, we are using the "old" trace
5481             // dumping scheme. All traces are written to a global trace file (usually
5482             // "/data/anr/traces.txt") so the code below must take care to unlink and recreate
5483             // the file if requested.
5484             //
5485             // This mode of operation will be removed in the near future.
5486
5487
5488             String globalTracesPath = SystemProperties.get("dalvik.vm.stack-trace-file", null);
5489             if (globalTracesPath.isEmpty()) {
5490                 Slog.w(TAG, "dumpStackTraces: no trace path configured");
5491                 return null;
5492             }
5493
5494             tracesFile = new File(globalTracesPath);
5495             try {
5496                 if (clearTraces && tracesFile.exists()) {
5497                     tracesFile.delete();
5498                 }
5499
5500                 tracesFile.createNewFile();
5501                 FileUtils.setPermissions(globalTracesPath, 0666, -1, -1); // -rw-rw-rw-
5502             } catch (IOException e) {
5503                 Slog.w(TAG, "Unable to prepare ANR traces file: " + tracesFile, e);
5504                 return null;
5505             }
5506         } else {
5507             // When dalvik.vm.stack-trace-dir is set, we use the "new" trace dumping scheme.
5508             // Each set of ANR traces is written to a separate file and dumpstate will process
5509             // all such files and add them to a captured bug report if they're recent enough.
5510             //
5511             // NOTE: We should consider creating the file in native code atomically once we've
5512             // gotten rid of the old scheme of dumping and lot of the code that deals with paths
5513             // can be removed.
5514             try {
5515                 tracesFile = File.createTempFile("anr_", "", new File(tracesDir));
5516                 FileUtils.setPermissions(tracesFile.getAbsolutePath(), 0600, -1, -1); // -rw-------
5517             } catch (IOException ioe) {
5518                 Slog.w(TAG, "Unable to create ANR traces file: ", ioe);
5519                 return null;
5520             }
5521
5522             useTombstonedForJavaTraces = true;
5523         }
5524
5525         dumpStackTraces(tracesFile.getAbsolutePath(), firstPids, nativePids, extraPids,
5526                 useTombstonedForJavaTraces);
5527         return tracesFile;
5528     }
5529
5530     /**
5531      * Legacy code, do not use. Existing users will be deleted.
5532      *
5533      * @deprecated
5534      */
5535     @Deprecated
5536     public static class DumpStackFileObserver extends FileObserver {
5537         // Keep in sync with frameworks/native/cmds/dumpstate/utils.cpp
5538         private static final int TRACE_DUMP_TIMEOUT_MS = 10000; // 10 seconds
5539
5540         private final String mTracesPath;
5541         private boolean mClosed;
5542
5543         public DumpStackFileObserver(String tracesPath) {
5544             super(tracesPath, FileObserver.CLOSE_WRITE);
5545             mTracesPath = tracesPath;
5546         }
5547
5548         @Override
5549         public synchronized void onEvent(int event, String path) {
5550             mClosed = true;
5551             notify();
5552         }
5553
5554         public long dumpWithTimeout(int pid, long timeout) {
5555             sendSignal(pid, SIGNAL_QUIT);
5556             final long start = SystemClock.elapsedRealtime();
5557
5558             final long waitTime = Math.min(timeout, TRACE_DUMP_TIMEOUT_MS);
5559             synchronized (this) {
5560                 try {
5561                     wait(waitTime); // Wait for traces file to be closed.
5562                 } catch (InterruptedException e) {
5563                     Slog.wtf(TAG, e);
5564                 }
5565             }
5566
5567             // This avoids a corner case of passing a negative time to the native
5568             // trace in case we've already hit the overall timeout.
5569             final long timeWaited = SystemClock.elapsedRealtime() - start;
5570             if (timeWaited >= timeout) {
5571                 return timeWaited;
5572             }
5573
5574             if (!mClosed) {
5575                 Slog.w(TAG, "Didn't see close of " + mTracesPath + " for pid " + pid +
5576                        ". Attempting native stack collection.");
5577
5578                 final long nativeDumpTimeoutMs = Math.min(
5579                         NATIVE_DUMP_TIMEOUT_MS, timeout - timeWaited);
5580
5581                 Debug.dumpNativeBacktraceToFileTimeout(pid, mTracesPath,
5582                         (int) (nativeDumpTimeoutMs / 1000));
5583             }
5584
5585             final long end = SystemClock.elapsedRealtime();
5586             mClosed = false;
5587
5588             return (end - start);
5589         }
5590     }
5591
5592     /**
5593      * Dump java traces for process {@code pid} to the specified file. If java trace dumping
5594      * fails, a native backtrace is attempted. Note that the timeout {@code timeoutMs} only applies
5595      * to the java section of the trace, a further {@code NATIVE_DUMP_TIMEOUT_MS} might be spent
5596      * attempting to obtain native traces in the case of a failure. Returns the total time spent
5597      * capturing traces.
5598      */
5599     private static long dumpJavaTracesTombstoned(int pid, String fileName, long timeoutMs) {
5600         final long timeStart = SystemClock.elapsedRealtime();
5601         if (!Debug.dumpJavaBacktraceToFileTimeout(pid, fileName, (int) (timeoutMs / 1000))) {
5602             Debug.dumpNativeBacktraceToFileTimeout(pid, fileName,
5603                     (NATIVE_DUMP_TIMEOUT_MS / 1000));
5604         }
5605
5606         return SystemClock.elapsedRealtime() - timeStart;
5607     }
5608
5609     private static void dumpStackTraces(String tracesFile, ArrayList<Integer> firstPids,
5610             ArrayList<Integer> nativePids, ArrayList<Integer> extraPids,
5611             boolean useTombstonedForJavaTraces) {
5612
5613         // We don't need any sort of inotify based monitoring when we're dumping traces via
5614         // tombstoned. Data is piped to an "intercept" FD installed in tombstoned so we're in full
5615         // control of all writes to the file in question.
5616         final DumpStackFileObserver observer;
5617         if (useTombstonedForJavaTraces) {
5618             observer = null;
5619         } else {
5620             // Use a FileObserver to detect when traces finish writing.
5621             // The order of traces is considered important to maintain for legibility.
5622             observer = new DumpStackFileObserver(tracesFile);
5623         }
5624
5625         // We must complete all stack dumps within 20 seconds.
5626         long remainingTime = 20 * 1000;
5627         try {
5628             if (observer != null) {
5629                 observer.startWatching();
5630             }
5631
5632             // First collect all of the stacks of the most important pids.
5633             if (firstPids != null) {
5634                 int num = firstPids.size();
5635                 for (int i = 0; i < num; i++) {
5636                     if (DEBUG_ANR) Slog.d(TAG, "Collecting stacks for pid "
5637                             + firstPids.get(i));
5638                     final long timeTaken;
5639                     if (useTombstonedForJavaTraces) {
5640                         timeTaken = dumpJavaTracesTombstoned(firstPids.get(i), tracesFile, remainingTime);
5641                     } else {
5642                         timeTaken = observer.dumpWithTimeout(firstPids.get(i), remainingTime);
5643                     }
5644
5645                     remainingTime -= timeTaken;
5646                     if (remainingTime <= 0) {
5647                         Slog.e(TAG, "Aborting stack trace dump (current firstPid=" + firstPids.get(i) +
5648                             "); deadline exceeded.");
5649                         return;
5650                     }
5651
5652                     if (DEBUG_ANR) {
5653                         Slog.d(TAG, "Done with pid " + firstPids.get(i) + " in " + timeTaken + "ms");
5654                     }
5655                 }
5656             }
5657
5658             // Next collect the stacks of the native pids
5659             if (nativePids != null) {
5660                 for (int pid : nativePids) {
5661                     if (DEBUG_ANR) Slog.d(TAG, "Collecting stacks for native pid " + pid);
5662                     final long nativeDumpTimeoutMs = Math.min(NATIVE_DUMP_TIMEOUT_MS, remainingTime);
5663
5664                     final long start = SystemClock.elapsedRealtime();
5665                     Debug.dumpNativeBacktraceToFileTimeout(
5666                             pid, tracesFile, (int) (nativeDumpTimeoutMs / 1000));
5667                     final long timeTaken = SystemClock.elapsedRealtime() - start;
5668
5669                     remainingTime -= timeTaken;
5670                     if (remainingTime <= 0) {
5671                         Slog.e(TAG, "Aborting stack trace dump (current native pid=" + pid +
5672                             "); deadline exceeded.");
5673                         return;
5674                     }
5675
5676                     if (DEBUG_ANR) {
5677                         Slog.d(TAG, "Done with native pid " + pid + " in " + timeTaken + "ms");
5678                     }
5679                 }
5680             }
5681
5682             // Lastly, dump stacks for all extra PIDs from the CPU tracker.
5683             if (extraPids != null) {
5684                 for (int pid : extraPids) {
5685                     if (DEBUG_ANR) Slog.d(TAG, "Collecting stacks for extra pid " + pid);
5686
5687                     final long timeTaken;
5688                     if (useTombstonedForJavaTraces) {
5689                         timeTaken = dumpJavaTracesTombstoned(pid, tracesFile, remainingTime);
5690                     } else {
5691                         timeTaken = observer.dumpWithTimeout(pid, remainingTime);
5692                     }
5693
5694                     remainingTime -= timeTaken;
5695                     if (remainingTime <= 0) {
5696                         Slog.e(TAG, "Aborting stack trace dump (current extra pid=" + pid +
5697                                 "); deadline exceeded.");
5698                         return;
5699                     }
5700
5701                     if (DEBUG_ANR) {
5702                         Slog.d(TAG, "Done with extra pid " + pid + " in " + timeTaken + "ms");
5703                     }
5704                 }
5705             }
5706         } finally {
5707             if (observer != null) {
5708                 observer.stopWatching();
5709             }
5710         }
5711     }
5712
5713     final void logAppTooSlow(ProcessRecord app, long startTime, String msg) {
5714         if (true || IS_USER_BUILD) {
5715             return;
5716         }
5717         String tracesPath = SystemProperties.get("dalvik.vm.stack-trace-file", null);
5718         if (tracesPath == null || tracesPath.length() == 0) {
5719             return;
5720         }
5721
5722         StrictMode.ThreadPolicy oldPolicy = StrictMode.allowThreadDiskReads();
5723         StrictMode.allowThreadDiskWrites();
5724         try {
5725             final File tracesFile = new File(tracesPath);
5726             final File tracesDir = tracesFile.getParentFile();
5727             final File tracesTmp = new File(tracesDir, "__tmp__");
5728             try {
5729                 if (tracesFile.exists()) {
5730                     tracesTmp.delete();
5731                     tracesFile.renameTo(tracesTmp);
5732                 }
5733                 StringBuilder sb = new StringBuilder();
5734                 Time tobj = new Time();
5735                 tobj.set(System.currentTimeMillis());
5736                 sb.append(tobj.format("%Y-%m-%d %H:%M:%S"));
5737                 sb.append(": ");
5738                 TimeUtils.formatDuration(SystemClock.uptimeMillis()-startTime, sb);
5739                 sb.append(" since ");
5740                 sb.append(msg);
5741                 FileOutputStream fos = new FileOutputStream(tracesFile);
5742                 fos.write(sb.toString().getBytes());
5743                 if (app == null) {
5744                     fos.write("\n*** No application process!".getBytes());
5745                 }
5746                 fos.close();
5747                 FileUtils.setPermissions(tracesFile.getPath(), 0666, -1, -1); // -rw-rw-rw-
5748             } catch (IOException e) {
5749                 Slog.w(TAG, "Unable to prepare slow app traces file: " + tracesPath, e);
5750                 return;
5751             }
5752
5753             if (app != null) {
5754                 ArrayList<Integer> firstPids = new ArrayList<Integer>();
5755                 firstPids.add(app.pid);
5756                 dumpStackTraces(tracesPath, firstPids, null, null, true /* useTombstoned */);
5757             }
5758
5759             File lastTracesFile = null;
5760             File curTracesFile = null;
5761             for (int i=9; i>=0; i--) {
5762                 String name = String.format(Locale.US, "slow%02d.txt", i);
5763                 curTracesFile = new File(tracesDir, name);
5764                 if (curTracesFile.exists()) {
5765                     if (lastTracesFile != null) {
5766                         curTracesFile.renameTo(lastTracesFile);
5767                     } else {
5768                         curTracesFile.delete();
5769                     }
5770                 }
5771                 lastTracesFile = curTracesFile;
5772             }
5773             tracesFile.renameTo(curTracesFile);
5774             if (tracesTmp.exists()) {
5775                 tracesTmp.renameTo(tracesFile);
5776             }
5777         } finally {
5778             StrictMode.setThreadPolicy(oldPolicy);
5779         }
5780     }
5781
5782     final void showLaunchWarningLocked(final ActivityRecord cur, final ActivityRecord next) {
5783         if (!mLaunchWarningShown) {
5784             mLaunchWarningShown = true;
5785             mUiHandler.post(new Runnable() {
5786                 @Override
5787                 public void run() {
5788                     synchronized (ActivityManagerService.this) {
5789                         final Dialog d = new LaunchWarningWindow(mContext, cur, next);
5790                         d.show();
5791                         mUiHandler.postDelayed(new Runnable() {
5792                             @Override
5793                             public void run() {
5794                                 synchronized (ActivityManagerService.this) {
5795                                     d.dismiss();
5796                                     mLaunchWarningShown = false;
5797                                 }
5798                             }
5799                         }, 4000);
5800                     }
5801                 }
5802             });
5803         }
5804     }
5805
5806     @Override
5807     public boolean clearApplicationUserData(final String packageName,
5808             final IPackageDataObserver observer, int userId) {
5809         enforceNotIsolatedCaller("clearApplicationUserData");
5810         int uid = Binder.getCallingUid();
5811         int pid = Binder.getCallingPid();
5812         userId = mUserController.handleIncomingUser(pid, uid, userId, false,
5813                 ALLOW_FULL_ONLY, "clearApplicationUserData", null);
5814
5815
5816         long callingId = Binder.clearCallingIdentity();
5817         try {
5818             IPackageManager pm = AppGlobals.getPackageManager();
5819             int pkgUid = -1;
5820             synchronized(this) {
5821                 if (getPackageManagerInternalLocked().isPackageDataProtected(
5822                         userId, packageName)) {
5823                     throw new SecurityException(
5824                             "Cannot clear data for a protected package: " + packageName);
5825                 }
5826
5827                 try {
5828                     pkgUid = pm.getPackageUid(packageName, MATCH_UNINSTALLED_PACKAGES, userId);
5829                 } catch (RemoteException e) {
5830                 }
5831                 if (pkgUid == -1) {
5832                     Slog.w(TAG, "Invalid packageName: " + packageName);
5833                     if (observer != null) {
5834                         try {
5835                             observer.onRemoveCompleted(packageName, false);
5836                         } catch (RemoteException e) {
5837                             Slog.i(TAG, "Observer no longer exists.");
5838                         }
5839                     }
5840                     return false;
5841                 }
5842                 if (uid == pkgUid || checkComponentPermission(
5843                         android.Manifest.permission.CLEAR_APP_USER_DATA,
5844                         pid, uid, -1, true)
5845                         == PackageManager.PERMISSION_GRANTED) {
5846                     forceStopPackageLocked(packageName, pkgUid, "clear data");
5847                 } else {
5848                     throw new SecurityException("PID " + pid + " does not have permission "
5849                             + android.Manifest.permission.CLEAR_APP_USER_DATA + " to clear data"
5850                                     + " of package " + packageName);
5851                 }
5852
5853                 // Remove all tasks match the cleared application package and user
5854                 for (int i = mRecentTasks.size() - 1; i >= 0; i--) {
5855                     final TaskRecord tr = mRecentTasks.get(i);
5856                     final String taskPackageName =
5857                             tr.getBaseIntent().getComponent().getPackageName();
5858                     if (tr.userId != userId) continue;
5859                     if (!taskPackageName.equals(packageName)) continue;
5860                     mStackSupervisor.removeTaskByIdLocked(tr.taskId, false, REMOVE_FROM_RECENTS);
5861                 }
5862             }
5863
5864             final int pkgUidF = pkgUid;
5865             final int userIdF = userId;
5866             final IPackageDataObserver localObserver = new IPackageDataObserver.Stub() {
5867                 @Override
5868                 public void onRemoveCompleted(String packageName, boolean succeeded)
5869                         throws RemoteException {
5870                     synchronized (ActivityManagerService.this) {
5871                         finishForceStopPackageLocked(packageName, pkgUidF);
5872                     }
5873
5874                     final Intent intent = new Intent(Intent.ACTION_PACKAGE_DATA_CLEARED,
5875                             Uri.fromParts("package", packageName, null));
5876                     intent.addFlags(Intent.FLAG_RECEIVER_INCLUDE_BACKGROUND);
5877                     intent.putExtra(Intent.EXTRA_UID, pkgUidF);
5878                     intent.putExtra(Intent.EXTRA_USER_HANDLE, UserHandle.getUserId(pkgUidF));
5879                     broadcastIntentInPackage("android", SYSTEM_UID, intent,
5880                             null, null, 0, null, null, null, null, false, false, userIdF);
5881
5882                     if (observer != null) {
5883                         observer.onRemoveCompleted(packageName, succeeded);
5884                     }
5885                 }
5886             };
5887
5888             try {
5889                 // Clear application user data
5890                 pm.clearApplicationUserData(packageName, localObserver, userId);
5891
5892                 synchronized(this) {
5893                     // Remove all permissions granted from/to this package
5894                     removeUriPermissionsForPackageLocked(packageName, userId, true);
5895                 }
5896
5897                 // Reset notification settings.
5898                 INotificationManager inm = NotificationManager.getService();
5899                 inm.clearData(packageName, pkgUidF, uid == pkgUidF);
5900             } catch (RemoteException e) {
5901             }
5902         } finally {
5903             Binder.restoreCallingIdentity(callingId);
5904         }
5905         return true;
5906     }
5907
5908     @Override
5909     public void killBackgroundProcesses(final String packageName, int userId) {
5910         if (checkCallingPermission(android.Manifest.permission.KILL_BACKGROUND_PROCESSES)
5911                 != PackageManager.PERMISSION_GRANTED &&
5912                 checkCallingPermission(android.Manifest.permission.RESTART_PACKAGES)
5913                         != PackageManager.PERMISSION_GRANTED) {
5914             String msg = "Permission Denial: killBackgroundProcesses() from pid="
5915                     + Binder.getCallingPid()
5916                     + ", uid=" + Binder.getCallingUid()
5917                     + " requires " + android.Manifest.permission.KILL_BACKGROUND_PROCESSES;
5918             Slog.w(TAG, msg);
5919             throw new SecurityException(msg);
5920         }
5921
5922         userId = mUserController.handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(),
5923                 userId, true, ALLOW_FULL_ONLY, "killBackgroundProcesses", null);
5924         long callingId = Binder.clearCallingIdentity();
5925         try {
5926             IPackageManager pm = AppGlobals.getPackageManager();
5927             synchronized(this) {
5928                 int appId = -1;
5929                 try {
5930                     appId = UserHandle.getAppId(
5931                             pm.getPackageUid(packageName, MATCH_DEBUG_TRIAGED_MISSING, userId));
5932                 } catch (RemoteException e) {
5933                 }
5934                 if (appId == -1) {
5935                     Slog.w(TAG, "Invalid packageName: " + packageName);
5936                     return;
5937                 }
5938                 killPackageProcessesLocked(packageName, appId, userId,
5939                         ProcessList.SERVICE_ADJ, false, true, true, false, "kill background");
5940             }
5941         } finally {
5942             Binder.restoreCallingIdentity(callingId);
5943         }
5944     }
5945
5946     @Override
5947     public void killAllBackgroundProcesses() {
5948         if (checkCallingPermission(android.Manifest.permission.KILL_BACKGROUND_PROCESSES)
5949                 != PackageManager.PERMISSION_GRANTED) {
5950             final String msg = "Permission Denial: killAllBackgroundProcesses() from pid="
5951                     + Binder.getCallingPid() + ", uid=" + Binder.getCallingUid()
5952                     + " requires " + android.Manifest.permission.KILL_BACKGROUND_PROCESSES;
5953             Slog.w(TAG, msg);
5954             throw new SecurityException(msg);
5955         }
5956
5957         final long callingId = Binder.clearCallingIdentity();
5958         try {
5959             synchronized (this) {
5960                 final ArrayList<ProcessRecord> procs = new ArrayList<>();
5961                 final int NP = mProcessNames.getMap().size();
5962                 for (int ip = 0; ip < NP; ip++) {
5963                     final SparseArray<ProcessRecord> apps = mProcessNames.getMap().valueAt(ip);
5964                     final int NA = apps.size();
5965                     for (int ia = 0; ia < NA; ia++) {
5966                         final ProcessRecord app = apps.valueAt(ia);
5967                         if (app.persistent) {
5968                             // We don't kill persistent processes.
5969                             continue;
5970                         }
5971                         if (app.removed) {
5972                             procs.add(app);
5973                         } else if (app.setAdj >= ProcessList.CACHED_APP_MIN_ADJ) {
5974                             app.removed = true;
5975                             procs.add(app);
5976                         }
5977                     }
5978                 }
5979
5980                 final int N = procs.size();
5981                 for (int i = 0; i < N; i++) {
5982                     removeProcessLocked(procs.get(i), false, true, "kill all background");
5983                 }
5984
5985                 mAllowLowerMemLevel = true;
5986
5987                 updateOomAdjLocked();
5988                 doLowMemReportIfNeededLocked(null);
5989             }
5990         } finally {
5991             Binder.restoreCallingIdentity(callingId);
5992         }
5993     }
5994
5995     /**
5996      * Kills all background processes, except those matching any of the
5997      * specified properties.
5998      *
5999      * @param minTargetSdk the target SDK version at or above which to preserve
6000      *                     processes, or {@code -1} to ignore the target SDK
6001      * @param maxProcState the process state at or below which to preserve
6002      *                     processes, or {@code -1} to ignore the process state
6003      */
6004     private void killAllBackgroundProcessesExcept(int minTargetSdk, int maxProcState) {
6005         if (checkCallingPermission(android.Manifest.permission.KILL_BACKGROUND_PROCESSES)
6006                 != PackageManager.PERMISSION_GRANTED) {
6007             final String msg = "Permission Denial: killAllBackgroundProcessesExcept() from pid="
6008                     + Binder.getCallingPid() + ", uid=" + Binder.getCallingUid()
6009                     + " requires " + android.Manifest.permission.KILL_BACKGROUND_PROCESSES;
6010             Slog.w(TAG, msg);
6011             throw new SecurityException(msg);
6012         }
6013
6014         final long callingId = Binder.clearCallingIdentity();
6015         try {
6016             synchronized (this) {
6017                 final ArrayList<ProcessRecord> procs = new ArrayList<>();
6018                 final int NP = mProcessNames.getMap().size();
6019                 for (int ip = 0; ip < NP; ip++) {
6020                     final SparseArray<ProcessRecord> apps = mProcessNames.getMap().valueAt(ip);
6021                     final int NA = apps.size();
6022                     for (int ia = 0; ia < NA; ia++) {
6023                         final ProcessRecord app = apps.valueAt(ia);
6024                         if (app.removed) {
6025                             procs.add(app);
6026                         } else if ((minTargetSdk < 0 || app.info.targetSdkVersion < minTargetSdk)
6027                                 && (maxProcState < 0 || app.setProcState > maxProcState)) {
6028                             app.removed = true;
6029                             procs.add(app);
6030                         }
6031                     }
6032                 }
6033
6034                 final int N = procs.size();
6035                 for (int i = 0; i < N; i++) {
6036                     removeProcessLocked(procs.get(i), false, true, "kill all background except");
6037                 }
6038             }
6039         } finally {
6040             Binder.restoreCallingIdentity(callingId);
6041         }
6042     }
6043
6044     @Override
6045     public void forceStopPackage(final String packageName, int userId) {
6046         if (checkCallingPermission(android.Manifest.permission.FORCE_STOP_PACKAGES)
6047                 != PackageManager.PERMISSION_GRANTED) {
6048             String msg = "Permission Denial: forceStopPackage() from pid="
6049                     + Binder.getCallingPid()
6050                     + ", uid=" + Binder.getCallingUid()
6051                     + " requires " + android.Manifest.permission.FORCE_STOP_PACKAGES;
6052             Slog.w(TAG, msg);
6053             throw new SecurityException(msg);
6054         }
6055         final int callingPid = Binder.getCallingPid();
6056         userId = mUserController.handleIncomingUser(callingPid, Binder.getCallingUid(),
6057                 userId, true, ALLOW_FULL_ONLY, "forceStopPackage", null);
6058         long callingId = Binder.clearCallingIdentity();
6059         try {
6060             IPackageManager pm = AppGlobals.getPackageManager();
6061             synchronized(this) {
6062                 int[] users = userId == UserHandle.USER_ALL
6063                         ? mUserController.getUsers() : new int[] { userId };
6064                 for (int user : users) {
6065                     int pkgUid = -1;
6066                     try {
6067                         pkgUid = pm.getPackageUid(packageName, MATCH_DEBUG_TRIAGED_MISSING,
6068                                 user);
6069                     } catch (RemoteException e) {
6070                     }
6071                     if (pkgUid == -1) {
6072                         Slog.w(TAG, "Invalid packageName: " + packageName);
6073                         continue;
6074                     }
6075                     try {
6076                         pm.setPackageStoppedState(packageName, true, user);
6077                     } catch (RemoteException e) {
6078                     } catch (IllegalArgumentException e) {
6079                         Slog.w(TAG, "Failed trying to unstop package "
6080                                 + packageName + ": " + e);
6081                     }
6082                     if (mUserController.isUserRunningLocked(user, 0)) {
6083                         forceStopPackageLocked(packageName, pkgUid, "from pid " + callingPid);
6084                         finishForceStopPackageLocked(packageName, pkgUid);
6085                     }
6086                 }
6087             }
6088         } finally {
6089             Binder.restoreCallingIdentity(callingId);
6090         }
6091     }
6092
6093     @Override
6094     public void addPackageDependency(String packageName) {
6095         synchronized (this) {
6096             int callingPid = Binder.getCallingPid();
6097             if (callingPid == myPid()) {
6098                 //  Yeah, um, no.
6099                 return;
6100             }
6101             ProcessRecord proc;
6102             synchronized (mPidsSelfLocked) {
6103                 proc = mPidsSelfLocked.get(Binder.getCallingPid());
6104             }
6105             if (proc != null) {
6106                 if (proc.pkgDeps == null) {
6107                     proc.pkgDeps = new ArraySet<String>(1);
6108                 }
6109                 proc.pkgDeps.add(packageName);
6110             }
6111         }
6112     }
6113
6114     /*
6115      * The pkg name and app id have to be specified.
6116      */
6117     @Override
6118     public void killApplication(String pkg, int appId, int userId, String reason) {
6119         if (pkg == null) {
6120             return;
6121         }
6122         // Make sure the uid is valid.
6123         if (appId < 0) {
6124             Slog.w(TAG, "Invalid appid specified for pkg : " + pkg);
6125             return;
6126         }
6127         int callerUid = Binder.getCallingUid();
6128         // Only the system server can kill an application
6129         if (UserHandle.getAppId(callerUid) == SYSTEM_UID) {
6130             // Post an aysnc message to kill the application
6131             Message msg = mHandler.obtainMessage(KILL_APPLICATION_MSG);
6132             msg.arg1 = appId;
6133             msg.arg2 = userId;
6134             Bundle bundle = new Bundle();
6135             bundle.putString("pkg", pkg);
6136             bundle.putString("reason", reason);
6137             msg.obj = bundle;
6138             mHandler.sendMessage(msg);
6139         } else {
6140             throw new SecurityException(callerUid + " cannot kill pkg: " +
6141                     pkg);
6142         }
6143     }
6144
6145     @Override
6146     public void closeSystemDialogs(String reason) {
6147         enforceNotIsolatedCaller("closeSystemDialogs");
6148
6149         final int pid = Binder.getCallingPid();
6150         final int uid = Binder.getCallingUid();
6151         final long origId = Binder.clearCallingIdentity();
6152         try {
6153             synchronized (this) {
6154                 // Only allow this from foreground processes, so that background
6155                 // applications can't abuse it to prevent system UI from being shown.
6156                 if (uid >= FIRST_APPLICATION_UID) {
6157                     ProcessRecord proc;
6158                     synchronized (mPidsSelfLocked) {
6159                         proc = mPidsSelfLocked.get(pid);
6160                     }
6161                     if (proc.curRawAdj > ProcessList.PERCEPTIBLE_APP_ADJ) {
6162                         Slog.w(TAG, "Ignoring closeSystemDialogs " + reason
6163                                 + " from background process " + proc);
6164                         return;
6165                     }
6166                 }
6167                 closeSystemDialogsLocked(reason);
6168             }
6169         } finally {
6170             Binder.restoreCallingIdentity(origId);
6171         }
6172     }
6173
6174     void closeSystemDialogsLocked(String reason) {
6175         Intent intent = new Intent(Intent.ACTION_CLOSE_SYSTEM_DIALOGS);
6176         intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY
6177                 | Intent.FLAG_RECEIVER_FOREGROUND);
6178         if (reason != null) {
6179             intent.putExtra("reason", reason);
6180         }
6181         mWindowManager.closeSystemDialogs(reason);
6182
6183         mStackSupervisor.closeSystemDialogsLocked();
6184
6185         broadcastIntentLocked(null, null, intent, null, null, 0, null, null, null,
6186                 AppOpsManager.OP_NONE, null, false, false,
6187                 -1, SYSTEM_UID, UserHandle.USER_ALL);
6188     }
6189
6190     @Override
6191     public Debug.MemoryInfo[] getProcessMemoryInfo(int[] pids) {
6192         enforceNotIsolatedCaller("getProcessMemoryInfo");
6193         Debug.MemoryInfo[] infos = new Debug.MemoryInfo[pids.length];
6194         for (int i=pids.length-1; i>=0; i--) {
6195             ProcessRecord proc;
6196             int oomAdj;
6197             synchronized (this) {
6198                 synchronized (mPidsSelfLocked) {
6199                     proc = mPidsSelfLocked.get(pids[i]);
6200                     oomAdj = proc != null ? proc.setAdj : 0;
6201                 }
6202             }
6203             infos[i] = new Debug.MemoryInfo();
6204             Debug.getMemoryInfo(pids[i], infos[i]);
6205             if (proc != null) {
6206                 synchronized (this) {
6207                     if (proc.thread != null && proc.setAdj == oomAdj) {
6208                         // Record this for posterity if the process has been stable.
6209                         proc.baseProcessTracker.addPss(infos[i].getTotalPss(),
6210                                 infos[i].getTotalUss(), false, proc.pkgList);
6211                     }
6212                 }
6213             }
6214         }
6215         return infos;
6216     }
6217
6218     @Override
6219     public long[] getProcessPss(int[] pids) {
6220         enforceNotIsolatedCaller("getProcessPss");
6221         long[] pss = new long[pids.length];
6222         for (int i=pids.length-1; i>=0; i--) {
6223             ProcessRecord proc;
6224             int oomAdj;
6225             synchronized (this) {
6226                 synchronized (mPidsSelfLocked) {
6227                     proc = mPidsSelfLocked.get(pids[i]);
6228                     oomAdj = proc != null ? proc.setAdj : 0;
6229                 }
6230             }
6231             long[] tmpUss = new long[1];
6232             pss[i] = Debug.getPss(pids[i], tmpUss, null);
6233             if (proc != null) {
6234                 synchronized (this) {
6235                     if (proc.thread != null && proc.setAdj == oomAdj) {
6236                         // Record this for posterity if the process has been stable.
6237                         proc.baseProcessTracker.addPss(pss[i], tmpUss[0], false, proc.pkgList);
6238                     }
6239                 }
6240             }
6241         }
6242         return pss;
6243     }
6244
6245     @Override
6246     public void killApplicationProcess(String processName, int uid) {
6247         if (processName == null) {
6248             return;
6249         }
6250
6251         int callerUid = Binder.getCallingUid();
6252         // Only the system server can kill an application
6253         if (callerUid == SYSTEM_UID) {
6254             synchronized (this) {
6255                 ProcessRecord app = getProcessRecordLocked(processName, uid, true);
6256                 if (app != null && app.thread != null) {
6257                     try {
6258                         app.thread.scheduleSuicide();
6259                     } catch (RemoteException e) {
6260                         // If the other end already died, then our work here is done.
6261                     }
6262                 } else {
6263                     Slog.w(TAG, "Process/uid not found attempting kill of "
6264                             + processName + " / " + uid);
6265                 }
6266             }
6267         } else {
6268             throw new SecurityException(callerUid + " cannot kill app process: " +
6269                     processName);
6270         }
6271     }
6272
6273     private void forceStopPackageLocked(final String packageName, int uid, String reason) {
6274         forceStopPackageLocked(packageName, UserHandle.getAppId(uid), false,
6275                 false, true, false, false, UserHandle.getUserId(uid), reason);
6276     }
6277
6278     private void finishForceStopPackageLocked(final String packageName, int uid) {
6279         Intent intent = new Intent(Intent.ACTION_PACKAGE_RESTARTED,
6280                 Uri.fromParts("package", packageName, null));
6281         if (!mProcessesReady) {
6282             intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY
6283                     | Intent.FLAG_RECEIVER_FOREGROUND);
6284         }
6285         intent.putExtra(Intent.EXTRA_UID, uid);
6286         intent.putExtra(Intent.EXTRA_USER_HANDLE, UserHandle.getUserId(uid));
6287         broadcastIntentLocked(null, null, intent,
6288                 null, null, 0, null, null, null, AppOpsManager.OP_NONE,
6289                 null, false, false, MY_PID, SYSTEM_UID, UserHandle.getUserId(uid));
6290     }
6291
6292
6293     private final boolean killPackageProcessesLocked(String packageName, int appId,
6294             int userId, int minOomAdj, boolean callerWillRestart, boolean allowRestart,
6295             boolean doit, boolean evenPersistent, String reason) {
6296         ArrayList<ProcessRecord> procs = new ArrayList<>();
6297
6298         // Remove all processes this package may have touched: all with the
6299         // same UID (except for the system or root user), and all whose name
6300         // matches the package name.
6301         final int NP = mProcessNames.getMap().size();
6302         for (int ip=0; ip<NP; ip++) {
6303             SparseArray<ProcessRecord> apps = mProcessNames.getMap().valueAt(ip);
6304             final int NA = apps.size();
6305             for (int ia=0; ia<NA; ia++) {
6306                 ProcessRecord app = apps.valueAt(ia);
6307                 if (app.persistent && !evenPersistent) {
6308                     // we don't kill persistent processes
6309                     continue;
6310                 }
6311                 if (app.removed) {
6312                     if (doit) {
6313                         procs.add(app);
6314                     }
6315                     continue;
6316                 }
6317
6318                 // Skip process if it doesn't meet our oom adj requirement.
6319                 if (app.setAdj < minOomAdj) {
6320                     continue;
6321                 }
6322
6323                 // If no package is specified, we call all processes under the
6324                 // give user id.
6325                 if (packageName == null) {
6326                     if (userId != UserHandle.USER_ALL && app.userId != userId) {
6327                         continue;
6328                     }
6329                     if (appId >= 0 && UserHandle.getAppId(app.uid) != appId) {
6330                         continue;
6331                     }
6332                 // Package has been specified, we want to hit all processes
6333                 // that match it.  We need to qualify this by the processes
6334                 // that are running under the specified app and user ID.
6335                 } else {
6336                     final boolean isDep = app.pkgDeps != null
6337                             && app.pkgDeps.contains(packageName);
6338                     if (!isDep && UserHandle.getAppId(app.uid) != appId) {
6339                         continue;
6340                     }
6341                     if (userId != UserHandle.USER_ALL && app.userId != userId) {
6342                         continue;
6343                     }
6344                     if (!app.pkgList.containsKey(packageName) && !isDep) {
6345                         continue;
6346                     }
6347                 }
6348
6349                 // Process has passed all conditions, kill it!
6350                 if (!doit) {
6351                     return true;
6352                 }
6353                 app.removed = true;
6354                 procs.add(app);
6355             }
6356         }
6357
6358         int N = procs.size();
6359         for (int i=0; i<N; i++) {
6360             removeProcessLocked(procs.get(i), callerWillRestart, allowRestart, reason);
6361         }
6362         updateOomAdjLocked();
6363         return N > 0;
6364     }
6365
6366     private void cleanupDisabledPackageComponentsLocked(
6367             String packageName, int userId, boolean killProcess, String[] changedClasses) {
6368
6369         Set<String> disabledClasses = null;
6370         boolean packageDisabled = false;
6371         IPackageManager pm = AppGlobals.getPackageManager();
6372
6373         if (changedClasses == null) {
6374             // Nothing changed...
6375             return;
6376         }
6377
6378         // Determine enable/disable state of the package and its components.
6379         int enabled = PackageManager.COMPONENT_ENABLED_STATE_DEFAULT;
6380         for (int i = changedClasses.length - 1; i >= 0; i--) {
6381             final String changedClass = changedClasses[i];
6382
6383             if (changedClass.equals(packageName)) {
6384                 try {
6385                     // Entire package setting changed
6386                     enabled = pm.getApplicationEnabledSetting(packageName,
6387                             (userId != UserHandle.USER_ALL) ? userId : UserHandle.USER_SYSTEM);
6388                 } catch (Exception e) {
6389                     // No such package/component; probably racing with uninstall.  In any
6390                     // event it means we have nothing further to do here.
6391                     return;
6392                 }
6393                 packageDisabled = enabled != PackageManager.COMPONENT_ENABLED_STATE_ENABLED
6394                         && enabled != PackageManager.COMPONENT_ENABLED_STATE_DEFAULT;
6395                 if (packageDisabled) {
6396                     // Entire package is disabled.
6397                     // No need to continue to check component states.
6398                     disabledClasses = null;
6399                     break;
6400                 }
6401             } else {
6402                 try {
6403                     enabled = pm.getComponentEnabledSetting(
6404                             new ComponentName(packageName, changedClass),
6405                             (userId != UserHandle.USER_ALL) ? userId : UserHandle.USER_SYSTEM);
6406                 } catch (Exception e) {
6407                     // As above, probably racing with uninstall.
6408                     return;
6409                 }
6410                 if (enabled != PackageManager.COMPONENT_ENABLED_STATE_ENABLED
6411                         && enabled != PackageManager.COMPONENT_ENABLED_STATE_DEFAULT) {
6412                     if (disabledClasses == null) {
6413                         disabledClasses = new ArraySet<>(changedClasses.length);
6414                     }
6415                     disabledClasses.add(changedClass);
6416                 }
6417             }
6418         }
6419
6420         if (!packageDisabled && disabledClasses == null) {
6421             // Nothing to do here...
6422             return;
6423         }
6424
6425         // Clean-up disabled activities.
6426         if (mStackSupervisor.finishDisabledPackageActivitiesLocked(
6427                 packageName, disabledClasses, true, false, userId) && mBooted) {
6428             mStackSupervisor.resumeFocusedStackTopActivityLocked();
6429             mStackSupervisor.scheduleIdleLocked();
6430         }
6431
6432         // Clean-up disabled tasks
6433         cleanupDisabledPackageTasksLocked(packageName, disabledClasses, userId);
6434
6435         // Clean-up disabled services.
6436         mServices.bringDownDisabledPackageServicesLocked(
6437                 packageName, disabledClasses, userId, false, killProcess, true);
6438
6439         // Clean-up disabled providers.
6440         ArrayList<ContentProviderRecord> providers = new ArrayList<>();
6441         mProviderMap.collectPackageProvidersLocked(
6442                 packageName, disabledClasses, true, false, userId, providers);
6443         for (int i = providers.size() - 1; i >= 0; i--) {
6444             removeDyingProviderLocked(null, providers.get(i), true);
6445         }
6446
6447         // Clean-up disabled broadcast receivers.
6448         for (int i = mBroadcastQueues.length - 1; i >= 0; i--) {
6449             mBroadcastQueues[i].cleanupDisabledPackageReceiversLocked(
6450                     packageName, disabledClasses, userId, true);
6451         }
6452
6453     }
6454
6455     final boolean clearBroadcastQueueForUserLocked(int userId) {
6456         boolean didSomething = false;
6457         for (int i = mBroadcastQueues.length - 1; i >= 0; i--) {
6458             didSomething |= mBroadcastQueues[i].cleanupDisabledPackageReceiversLocked(
6459                     null, null, userId, true);
6460         }
6461         return didSomething;
6462     }
6463
6464     final boolean forceStopPackageLocked(String packageName, int appId,
6465             boolean callerWillRestart, boolean purgeCache, boolean doit,
6466             boolean evenPersistent, boolean uninstalling, int userId, String reason) {
6467         int i;
6468
6469         if (userId == UserHandle.USER_ALL && packageName == null) {
6470             Slog.w(TAG, "Can't force stop all processes of all users, that is insane!");
6471         }
6472
6473         if (appId < 0 && packageName != null) {
6474             try {
6475                 appId = UserHandle.getAppId(AppGlobals.getPackageManager()
6476                         .getPackageUid(packageName, MATCH_DEBUG_TRIAGED_MISSING, 0));
6477             } catch (RemoteException e) {
6478             }
6479         }
6480
6481         if (doit) {
6482             if (packageName != null) {
6483                 Slog.i(TAG, "Force stopping " + packageName + " appid=" + appId
6484                         + " user=" + userId + ": " + reason);
6485             } else {
6486                 Slog.i(TAG, "Force stopping u" + userId + ": " + reason);
6487             }
6488
6489             mAppErrors.resetProcessCrashTimeLocked(packageName == null, appId, userId);
6490         }
6491
6492         boolean didSomething = killPackageProcessesLocked(packageName, appId, userId,
6493                 ProcessList.INVALID_ADJ, callerWillRestart, true, doit, evenPersistent,
6494                 packageName == null ? ("stop user " + userId) : ("stop " + packageName));
6495
6496         didSomething |= mActivityStarter.clearPendingActivityLaunchesLocked(packageName);
6497
6498         if (mStackSupervisor.finishDisabledPackageActivitiesLocked(
6499                 packageName, null, doit, evenPersistent, userId)) {
6500             if (!doit) {
6501                 return true;
6502             }
6503             didSomething = true;
6504         }
6505
6506         if (mServices.bringDownDisabledPackageServicesLocked(
6507                 packageName, null, userId, evenPersistent, true, doit)) {
6508             if (!doit) {
6509                 return true;
6510             }
6511             didSomething = true;
6512         }
6513
6514         if (packageName == null) {
6515             // Remove all sticky broadcasts from this user.
6516             mStickyBroadcasts.remove(userId);
6517         }
6518
6519         ArrayList<ContentProviderRecord> providers = new ArrayList<>();
6520         if (mProviderMap.collectPackageProvidersLocked(packageName, null, doit, evenPersistent,
6521                 userId, providers)) {
6522             if (!doit) {
6523                 return true;
6524             }
6525             didSomething = true;
6526         }
6527         for (i = providers.size() - 1; i >= 0; i--) {
6528             removeDyingProviderLocked(null, providers.get(i), true);
6529         }
6530
6531         // Remove transient permissions granted from/to this package/user
6532         removeUriPermissionsForPackageLocked(packageName, userId, false);
6533
6534         if (doit) {
6535             for (i = mBroadcastQueues.length - 1; i >= 0; i--) {
6536                 didSomething |= mBroadcastQueues[i].cleanupDisabledPackageReceiversLocked(
6537                         packageName, null, userId, doit);
6538             }
6539         }
6540
6541         if (packageName == null || uninstalling) {
6542             // Remove pending intents.  For now we only do this when force
6543             // stopping users, because we have some problems when doing this
6544             // for packages -- app widgets are not currently cleaned up for
6545             // such packages, so they can be left with bad pending intents.
6546             if (mIntentSenderRecords.size() > 0) {
6547                 Iterator<WeakReference<PendingIntentRecord>> it
6548                         = mIntentSenderRecords.values().iterator();
6549                 while (it.hasNext()) {
6550                     WeakReference<PendingIntentRecord> wpir = it.next();
6551                     if (wpir == null) {
6552                         it.remove();
6553                         continue;
6554                     }
6555                     PendingIntentRecord pir = wpir.get();
6556                     if (pir == null) {
6557                         it.remove();
6558                         continue;
6559                     }
6560                     if (packageName == null) {
6561                         // Stopping user, remove all objects for the user.
6562                         if (pir.key.userId != userId) {
6563                             // Not the same user, skip it.
6564                             continue;
6565                         }
6566                     } else {
6567                         if (UserHandle.getAppId(pir.uid) != appId) {
6568                             // Different app id, skip it.
6569                             continue;
6570                         }
6571                         if (userId != UserHandle.USER_ALL && pir.key.userId != userId) {
6572                             // Different user, skip it.
6573                             continue;
6574                         }
6575                         if (!pir.key.packageName.equals(packageName)) {
6576                             // Different package, skip it.
6577                             continue;
6578                         }
6579                     }
6580                     if (!doit) {
6581                         return true;
6582                     }
6583                     didSomething = true;
6584                     it.remove();
6585                     makeIntentSenderCanceledLocked(pir);
6586                     if (pir.key.activity != null && pir.key.activity.pendingResults != null) {
6587                         pir.key.activity.pendingResults.remove(pir.ref);
6588                     }
6589                 }
6590             }
6591         }
6592
6593         if (doit) {
6594             if (purgeCache && packageName != null) {
6595                 AttributeCache ac = AttributeCache.instance();
6596                 if (ac != null) {
6597                     ac.removePackage(packageName);
6598                 }
6599             }
6600             if (mBooted) {
6601                 mStackSupervisor.resumeFocusedStackTopActivityLocked();
6602                 mStackSupervisor.scheduleIdleLocked();
6603             }
6604         }
6605
6606         return didSomething;
6607     }
6608
6609     private final ProcessRecord removeProcessNameLocked(final String name, final int uid) {
6610         return removeProcessNameLocked(name, uid, null);
6611     }
6612
6613     private final ProcessRecord removeProcessNameLocked(final String name, final int uid,
6614             final ProcessRecord expecting) {
6615         ProcessRecord old = mProcessNames.get(name, uid);
6616         // Only actually remove when the currently recorded value matches the
6617         // record that we expected; if it doesn't match then we raced with a
6618         // newly created process and we don't want to destroy the new one.
6619         if ((expecting == null) || (old == expecting)) {
6620             mProcessNames.remove(name, uid);
6621         }
6622         if (old != null && old.uidRecord != null) {
6623             old.uidRecord.numProcs--;
6624             if (old.uidRecord.numProcs == 0) {
6625                 // No more processes using this uid, tell clients it is gone.
6626                 if (DEBUG_UID_OBSERVERS) Slog.i(TAG_UID_OBSERVERS,
6627                         "No more processes in " + old.uidRecord);
6628                 enqueueUidChangeLocked(old.uidRecord, -1, UidRecord.CHANGE_GONE);
6629                 EventLogTags.writeAmUidStopped(uid);
6630                 mActiveUids.remove(uid);
6631                 noteUidProcessState(uid, ActivityManager.PROCESS_STATE_NONEXISTENT);
6632             }
6633             old.uidRecord = null;
6634         }
6635         mIsolatedProcesses.remove(uid);
6636         return old;
6637     }
6638
6639     private final void addProcessNameLocked(ProcessRecord proc) {
6640         // We shouldn't already have a process under this name, but just in case we
6641         // need to clean up whatever may be there now.
6642         ProcessRecord old = removeProcessNameLocked(proc.processName, proc.uid);
6643         if (old == proc && proc.persistent) {
6644             // We are re-adding a persistent process.  Whatevs!  Just leave it there.
6645             Slog.w(TAG, "Re-adding persistent process " + proc);
6646         } else if (old != null) {
6647             Slog.wtf(TAG, "Already have existing proc " + old + " when adding " + proc);
6648         }
6649         UidRecord uidRec = mActiveUids.get(proc.uid);
6650         if (uidRec == null) {
6651             uidRec = new UidRecord(proc.uid);
6652             // This is the first appearance of the uid, report it now!
6653             if (DEBUG_UID_OBSERVERS) Slog.i(TAG_UID_OBSERVERS,
6654                     "Creating new process uid: " + uidRec);
6655             if (Arrays.binarySearch(mDeviceIdleTempWhitelist, UserHandle.getAppId(proc.uid)) >= 0
6656                     || mPendingTempWhitelist.indexOfKey(proc.uid) >= 0) {
6657                 uidRec.setWhitelist = uidRec.curWhitelist = true;
6658             }
6659             uidRec.updateHasInternetPermission();
6660             mActiveUids.put(proc.uid, uidRec);
6661             EventLogTags.writeAmUidRunning(uidRec.uid);
6662             noteUidProcessState(uidRec.uid, uidRec.curProcState);
6663             enqueueUidChangeLocked(uidRec, -1, UidRecord.CHANGE_ACTIVE);
6664         }
6665         proc.uidRecord = uidRec;
6666
6667         // Reset render thread tid if it was already set, so new process can set it again.
6668         proc.renderThreadTid = 0;
6669         uidRec.numProcs++;
6670         mProcessNames.put(proc.processName, proc.uid, proc);
6671         if (proc.isolated) {
6672             mIsolatedProcesses.put(proc.uid, proc);
6673         }
6674     }
6675
6676     boolean removeProcessLocked(ProcessRecord app,
6677             boolean callerWillRestart, boolean allowRestart, String reason) {
6678         final String name = app.processName;
6679         final int uid = app.uid;
6680         if (DEBUG_PROCESSES) Slog.d(TAG_PROCESSES,
6681             "Force removing proc " + app.toShortString() + " (" + name + "/" + uid + ")");
6682
6683         ProcessRecord old = mProcessNames.get(name, uid);
6684         if (old != app) {
6685             // This process is no longer active, so nothing to do.
6686             Slog.w(TAG, "Ignoring remove of inactive process: " + app);
6687             return false;
6688         }
6689         removeProcessNameLocked(name, uid);
6690         if (mHeavyWeightProcess == app) {
6691             mHandler.sendMessage(mHandler.obtainMessage(CANCEL_HEAVY_NOTIFICATION_MSG,
6692                     mHeavyWeightProcess.userId, 0));
6693             mHeavyWeightProcess = null;
6694         }
6695         boolean needRestart = false;
6696         if (app.pid > 0 && app.pid != MY_PID) {
6697             int pid = app.pid;
6698             synchronized (mPidsSelfLocked) {
6699                 mPidsSelfLocked.remove(pid);
6700                 mHandler.removeMessages(PROC_START_TIMEOUT_MSG, app);
6701             }
6702             mBatteryStatsService.noteProcessFinish(app.processName, app.info.uid);
6703             if (app.isolated) {
6704                 mBatteryStatsService.removeIsolatedUid(app.uid, app.info.uid);
6705                 getPackageManagerInternalLocked().removeIsolatedUid(app.uid);
6706             }
6707             boolean willRestart = false;
6708             if (app.persistent && !app.isolated) {
6709                 if (!callerWillRestart) {
6710                     willRestart = true;
6711                 } else {
6712                     needRestart = true;
6713                 }
6714             }
6715             app.kill(reason, true);
6716             handleAppDiedLocked(app, willRestart, allowRestart);
6717             if (willRestart) {
6718                 removeLruProcessLocked(app);
6719                 addAppLocked(app.info, null, false, null /* ABI override */);
6720             }
6721         } else {
6722             mRemovedProcesses.add(app);
6723         }
6724
6725         return needRestart;
6726     }
6727
6728     private final void processContentProviderPublishTimedOutLocked(ProcessRecord app) {
6729         cleanupAppInLaunchingProvidersLocked(app, true);
6730         removeProcessLocked(app, false, true, "timeout publishing content providers");
6731     }
6732
6733     private final void processStartTimedOutLocked(ProcessRecord app) {
6734         final int pid = app.pid;
6735         boolean gone = false;
6736         synchronized (mPidsSelfLocked) {
6737             ProcessRecord knownApp = mPidsSelfLocked.get(pid);
6738             if (knownApp != null && knownApp.thread == null) {
6739                 mPidsSelfLocked.remove(pid);
6740                 gone = true;
6741             }
6742         }
6743
6744         if (gone) {
6745             Slog.w(TAG, "Process " + app + " failed to attach");
6746             EventLog.writeEvent(EventLogTags.AM_PROCESS_START_TIMEOUT, app.userId,
6747                     pid, app.uid, app.processName);
6748             removeProcessNameLocked(app.processName, app.uid);
6749             if (mHeavyWeightProcess == app) {
6750                 mHandler.sendMessage(mHandler.obtainMessage(CANCEL_HEAVY_NOTIFICATION_MSG,
6751                         mHeavyWeightProcess.userId, 0));
6752                 mHeavyWeightProcess = null;
6753             }
6754             mBatteryStatsService.noteProcessFinish(app.processName, app.info.uid);
6755             if (app.isolated) {
6756                 mBatteryStatsService.removeIsolatedUid(app.uid, app.info.uid);
6757             }
6758             // Take care of any launching providers waiting for this process.
6759             cleanupAppInLaunchingProvidersLocked(app, true);
6760             // Take care of any services that are waiting for the process.
6761             mServices.processStartTimedOutLocked(app);
6762             app.kill("start timeout", true);
6763             removeLruProcessLocked(app);
6764             if (mBackupTarget != null && mBackupTarget.app.pid == pid) {
6765                 Slog.w(TAG, "Unattached app died before backup, skipping");
6766                 mHandler.post(new Runnable() {
6767                 @Override
6768                     public void run(){
6769                         try {
6770                             IBackupManager bm = IBackupManager.Stub.asInterface(
6771                                     ServiceManager.getService(Context.BACKUP_SERVICE));
6772                             bm.agentDisconnected(app.info.packageName);
6773                         } catch (RemoteException e) {
6774                             // Can't happen; the backup manager is local
6775                         }
6776                     }
6777                 });
6778             }
6779             if (isPendingBroadcastProcessLocked(pid)) {
6780                 Slog.w(TAG, "Unattached app died before broadcast acknowledged, skipping");
6781                 skipPendingBroadcastLocked(pid);
6782             }
6783         } else {
6784             Slog.w(TAG, "Spurious process start timeout - pid not known for " + app);
6785         }
6786     }
6787
6788     private final boolean attachApplicationLocked(IApplicationThread thread,
6789             int pid) {
6790
6791         // Find the application record that is being attached...  either via
6792         // the pid if we are running in multiple processes, or just pull the
6793         // next app record if we are emulating process with anonymous threads.
6794         ProcessRecord app;
6795         long startTime = SystemClock.uptimeMillis();
6796         if (pid != MY_PID && pid >= 0) {
6797             synchronized (mPidsSelfLocked) {
6798                 app = mPidsSelfLocked.get(pid);
6799             }
6800         } else {
6801             app = null;
6802         }
6803
6804         if (app == null) {
6805             Slog.w(TAG, "No pending application record for pid " + pid
6806                     + " (IApplicationThread " + thread + "); dropping process");
6807             EventLog.writeEvent(EventLogTags.AM_DROP_PROCESS, pid);
6808             if (pid > 0 && pid != MY_PID) {
6809                 killProcessQuiet(pid);
6810                 //TODO: killProcessGroup(app.info.uid, pid);
6811             } else {
6812                 try {
6813                     thread.scheduleExit();
6814                 } catch (Exception e) {
6815                     // Ignore exceptions.
6816                 }
6817             }
6818             return false;
6819         }
6820
6821         // If this application record is still attached to a previous
6822         // process, clean it up now.
6823         if (app.thread != null) {
6824             handleAppDiedLocked(app, true, true);
6825         }
6826
6827         // Tell the process all about itself.
6828
6829         if (DEBUG_ALL) Slog.v(
6830                 TAG, "Binding process pid " + pid + " to record " + app);
6831
6832         final String processName = app.processName;
6833         try {
6834             AppDeathRecipient adr = new AppDeathRecipient(
6835                     app, pid, thread);
6836             thread.asBinder().linkToDeath(adr, 0);
6837             app.deathRecipient = adr;
6838         } catch (RemoteException e) {
6839             app.resetPackageList(mProcessStats);
6840             startProcessLocked(app, "link fail", processName);
6841             return false;
6842         }
6843
6844         EventLog.writeEvent(EventLogTags.AM_PROC_BOUND, app.userId, app.pid, app.processName);
6845
6846         app.makeActive(thread, mProcessStats);
6847         app.curAdj = app.setAdj = app.verifiedAdj = ProcessList.INVALID_ADJ;
6848         app.curSchedGroup = app.setSchedGroup = ProcessList.SCHED_GROUP_DEFAULT;
6849         app.forcingToImportant = null;
6850         updateProcessForegroundLocked(app, false, false);
6851         app.hasShownUi = false;
6852         app.debugging = false;
6853         app.cached = false;
6854         app.killedByAm = false;
6855         app.killed = false;
6856
6857
6858         // We carefully use the same state that PackageManager uses for
6859         // filtering, since we use this flag to decide if we need to install
6860         // providers when user is unlocked later
6861         app.unlocked = StorageManager.isUserKeyUnlocked(app.userId);
6862
6863         mHandler.removeMessages(PROC_START_TIMEOUT_MSG, app);
6864
6865         boolean normalMode = mProcessesReady || isAllowedWhileBooting(app.info);
6866         List<ProviderInfo> providers = normalMode ? generateApplicationProvidersLocked(app) : null;
6867
6868         if (providers != null && checkAppInLaunchingProvidersLocked(app)) {
6869             Message msg = mHandler.obtainMessage(CONTENT_PROVIDER_PUBLISH_TIMEOUT_MSG);
6870             msg.obj = app;
6871             mHandler.sendMessageDelayed(msg, CONTENT_PROVIDER_PUBLISH_TIMEOUT);
6872         }
6873
6874         checkTime(startTime, "attachApplicationLocked: before bindApplication");
6875
6876         if (!normalMode) {
6877             Slog.i(TAG, "Launching preboot mode app: " + app);
6878         }
6879
6880         if (DEBUG_ALL) Slog.v(
6881             TAG, "New app record " + app
6882             + " thread=" + thread.asBinder() + " pid=" + pid);
6883         try {
6884             int testMode = ApplicationThreadConstants.DEBUG_OFF;
6885             if (mDebugApp != null && mDebugApp.equals(processName)) {
6886                 testMode = mWaitForDebugger
6887                     ? ApplicationThreadConstants.DEBUG_WAIT
6888                     : ApplicationThreadConstants.DEBUG_ON;
6889                 app.debugging = true;
6890                 if (mDebugTransient) {
6891                     mDebugApp = mOrigDebugApp;
6892                     mWaitForDebugger = mOrigWaitForDebugger;
6893                 }
6894             }
6895             String profileFile = app.instr != null ? app.instr.mProfileFile : null;
6896             ParcelFileDescriptor profileFd = null;
6897             int samplingInterval = 0;
6898             boolean profileAutoStop = false;
6899             boolean profileStreamingOutput = false;
6900             if (mProfileApp != null && mProfileApp.equals(processName)) {
6901                 mProfileProc = app;
6902                 profileFile = mProfileFile;
6903                 profileFd = mProfileFd;
6904                 samplingInterval = mSamplingInterval;
6905                 profileAutoStop = mAutoStopProfiler;
6906                 profileStreamingOutput = mStreamingOutput;
6907             }
6908             boolean enableTrackAllocation = false;
6909             if (mTrackAllocationApp != null && mTrackAllocationApp.equals(processName)) {
6910                 enableTrackAllocation = true;
6911                 mTrackAllocationApp = null;
6912             }
6913
6914             // If the app is being launched for restore or full backup, set it up specially
6915             boolean isRestrictedBackupMode = false;
6916             if (mBackupTarget != null && mBackupAppName.equals(processName)) {
6917                 isRestrictedBackupMode = mBackupTarget.appInfo.uid >= FIRST_APPLICATION_UID
6918                         && ((mBackupTarget.backupMode == BackupRecord.RESTORE)
6919                                 || (mBackupTarget.backupMode == BackupRecord.RESTORE_FULL)
6920                                 || (mBackupTarget.backupMode == BackupRecord.BACKUP_FULL));
6921             }
6922
6923             if (app.instr != null) {
6924                 notifyPackageUse(app.instr.mClass.getPackageName(),
6925                                  PackageManager.NOTIFY_PACKAGE_USE_INSTRUMENTATION);
6926             }
6927             if (DEBUG_CONFIGURATION) Slog.v(TAG_CONFIGURATION, "Binding proc "
6928                     + processName + " with config " + getGlobalConfiguration());
6929             ApplicationInfo appInfo = app.instr != null ? app.instr.mTargetInfo : app.info;
6930             app.compat = compatibilityInfoForPackageLocked(appInfo);
6931             if (profileFd != null) {
6932                 profileFd = profileFd.dup();
6933             }
6934             ProfilerInfo profilerInfo = profileFile == null ? null
6935                     : new ProfilerInfo(profileFile, profileFd, samplingInterval, profileAutoStop,
6936                                        profileStreamingOutput);
6937
6938             // We deprecated Build.SERIAL and it is not accessible to
6939             // apps that target the v2 security sandbox. Since access to
6940             // the serial is now behind a permission we push down the value.
6941             String buildSerial = Build.UNKNOWN;
6942             if (appInfo.targetSandboxVersion != 2) {
6943                 buildSerial = IDeviceIdentifiersPolicyService.Stub.asInterface(
6944                         ServiceManager.getService(Context.DEVICE_IDENTIFIERS_SERVICE))
6945                         .getSerial();
6946             }
6947
6948             // Check if this is a secondary process that should be incorporated into some
6949             // currently active instrumentation.  (Note we do this AFTER all of the profiling
6950             // stuff above because profiling can currently happen only in the primary
6951             // instrumentation process.)
6952             if (mActiveInstrumentation.size() > 0 && app.instr == null) {
6953                 for (int i = mActiveInstrumentation.size() - 1; i >= 0 && app.instr == null; i--) {
6954                     ActiveInstrumentation aInstr = mActiveInstrumentation.get(i);
6955                     if (!aInstr.mFinished && aInstr.mTargetInfo.uid == app.uid) {
6956                         if (aInstr.mTargetProcesses.length == 0) {
6957                             // This is the wildcard mode, where every process brought up for
6958                             // the target instrumentation should be included.
6959                             if (aInstr.mTargetInfo.packageName.equals(app.info.packageName)) {
6960                                 app.instr = aInstr;
6961                                 aInstr.mRunningProcesses.add(app);
6962                             }
6963                         } else {
6964                             for (String proc : aInstr.mTargetProcesses) {
6965                                 if (proc.equals(app.processName)) {
6966                                     app.instr = aInstr;
6967                                     aInstr.mRunningProcesses.add(app);
6968                                     break;
6969                                 }
6970                             }
6971                         }
6972                     }
6973                 }
6974             }
6975
6976             checkTime(startTime, "attachApplicationLocked: immediately before bindApplication");
6977             mStackSupervisor.mActivityMetricsLogger.notifyBindApplication(app);
6978             if (app.instr != null) {
6979                 thread.bindApplication(processName, appInfo, providers,
6980                         app.instr.mClass,
6981                         profilerInfo, app.instr.mArguments,
6982                         app.instr.mWatcher,
6983                         app.instr.mUiAutomationConnection, testMode,
6984                         mBinderTransactionTrackingEnabled, enableTrackAllocation,
6985                         isRestrictedBackupMode || !normalMode, app.persistent,
6986                         new Configuration(getGlobalConfiguration()), app.compat,
6987                         getCommonServicesLocked(app.isolated),
6988                         mCoreSettingsObserver.getCoreSettingsLocked(),
6989                         buildSerial);
6990             } else {
6991                 thread.bindApplication(processName, appInfo, providers, null, profilerInfo,
6992                         null, null, null, testMode,
6993                         mBinderTransactionTrackingEnabled, enableTrackAllocation,
6994                         isRestrictedBackupMode || !normalMode, app.persistent,
6995                         new Configuration(getGlobalConfiguration()), app.compat,
6996                         getCommonServicesLocked(app.isolated),
6997                         mCoreSettingsObserver.getCoreSettingsLocked(),
6998                         buildSerial);
6999             }
7000
7001             checkTime(startTime, "attachApplicationLocked: immediately after bindApplication");
7002             updateLruProcessLocked(app, false, null);
7003             checkTime(startTime, "attachApplicationLocked: after updateLruProcessLocked");
7004             app.lastRequestedGc = app.lastLowMemory = SystemClock.uptimeMillis();
7005         } catch (Exception e) {
7006             // todo: Yikes!  What should we do?  For now we will try to
7007             // start another process, but that could easily get us in
7008             // an infinite loop of restarting processes...
7009             Slog.wtf(TAG, "Exception thrown during bind of " + app, e);
7010
7011             app.resetPackageList(mProcessStats);
7012             app.unlinkDeathRecipient();
7013             startProcessLocked(app, "bind fail", processName);
7014             return false;
7015         }
7016
7017         // Remove this record from the list of starting applications.
7018         mPersistentStartingProcesses.remove(app);
7019         if (DEBUG_PROCESSES && mProcessesOnHold.contains(app)) Slog.v(TAG_PROCESSES,
7020                 "Attach application locked removing on hold: " + app);
7021         mProcessesOnHold.remove(app);
7022
7023         boolean badApp = false;
7024         boolean didSomething = false;
7025
7026         // See if the top visible activity is waiting to run in this process...
7027         if (normalMode) {
7028             try {
7029                 if (mStackSupervisor.attachApplicationLocked(app)) {
7030                     didSomething = true;
7031                 }
7032             } catch (Exception e) {
7033                 Slog.wtf(TAG, "Exception thrown launching activities in " + app, e);
7034                 badApp = true;
7035             }
7036         }
7037
7038         // Find any services that should be running in this process...
7039         if (!badApp) {
7040             try {
7041                 didSomething |= mServices.attachApplicationLocked(app, processName);
7042                 checkTime(startTime, "attachApplicationLocked: after mServices.attachApplicationLocked");
7043             } catch (Exception e) {
7044                 Slog.wtf(TAG, "Exception thrown starting services in " + app, e);
7045                 badApp = true;
7046             }
7047         }
7048
7049         // Check if a next-broadcast receiver is in this process...
7050         if (!badApp && isPendingBroadcastProcessLocked(pid)) {
7051             try {
7052                 didSomething |= sendPendingBroadcastsLocked(app);
7053                 checkTime(startTime, "attachApplicationLocked: after sendPendingBroadcastsLocked");
7054             } catch (Exception e) {
7055                 // If the app died trying to launch the receiver we declare it 'bad'
7056                 Slog.wtf(TAG, "Exception thrown dispatching broadcasts in " + app, e);
7057                 badApp = true;
7058             }
7059         }
7060
7061         // Check whether the next backup agent is in this process...
7062         if (!badApp && mBackupTarget != null && mBackupTarget.app == app) {
7063             if (DEBUG_BACKUP) Slog.v(TAG_BACKUP,
7064                     "New app is backup target, launching agent for " + app);
7065             notifyPackageUse(mBackupTarget.appInfo.packageName,
7066                              PackageManager.NOTIFY_PACKAGE_USE_BACKUP);
7067             try {
7068                 thread.scheduleCreateBackupAgent(mBackupTarget.appInfo,
7069                         compatibilityInfoForPackageLocked(mBackupTarget.appInfo),
7070                         mBackupTarget.backupMode);
7071             } catch (Exception e) {
7072                 Slog.wtf(TAG, "Exception thrown creating backup agent in " + app, e);
7073                 badApp = true;
7074             }
7075         }
7076
7077         if (badApp) {
7078             app.kill("error during init", true);
7079             handleAppDiedLocked(app, false, true);
7080             return false;
7081         }
7082
7083         if (!didSomething) {
7084             updateOomAdjLocked();
7085             checkTime(startTime, "attachApplicationLocked: after updateOomAdjLocked");
7086         }
7087
7088         return true;
7089     }
7090
7091     @Override
7092     public final void attachApplication(IApplicationThread thread) {
7093         synchronized (this) {
7094             int callingPid = Binder.getCallingPid();
7095             final long origId = Binder.clearCallingIdentity();
7096             attachApplicationLocked(thread, callingPid);
7097             Binder.restoreCallingIdentity(origId);
7098         }
7099     }
7100
7101     @Override
7102     public final void activityIdle(IBinder token, Configuration config, boolean stopProfiling) {
7103         final long origId = Binder.clearCallingIdentity();
7104         synchronized (this) {
7105             ActivityStack stack = ActivityRecord.getStackLocked(token);
7106             if (stack != null) {
7107                 ActivityRecord r =
7108                         mStackSupervisor.activityIdleInternalLocked(token, false /* fromTimeout */,
7109                                 false /* processPausingActivities */, config);
7110                 if (stopProfiling) {
7111                     if ((mProfileProc == r.app) && (mProfileFd != null)) {
7112                         try {
7113                             mProfileFd.close();
7114                         } catch (IOException e) {
7115                         }
7116                         clearProfilerLocked();
7117                     }
7118                 }
7119             }
7120         }
7121         Binder.restoreCallingIdentity(origId);
7122     }
7123
7124     void postFinishBooting(boolean finishBooting, boolean enableScreen) {
7125         mHandler.sendMessage(mHandler.obtainMessage(FINISH_BOOTING_MSG,
7126                 finishBooting ? 1 : 0, enableScreen ? 1 : 0));
7127     }
7128
7129     void enableScreenAfterBoot() {
7130         EventLog.writeEvent(EventLogTags.BOOT_PROGRESS_ENABLE_SCREEN,
7131                 SystemClock.uptimeMillis());
7132         mWindowManager.enableScreenAfterBoot();
7133
7134         synchronized (this) {
7135             updateEventDispatchingLocked();
7136         }
7137     }
7138
7139     @Override
7140     public void showBootMessage(final CharSequence msg, final boolean always) {
7141         if (Binder.getCallingUid() != myUid()) {
7142             throw new SecurityException();
7143         }
7144         mWindowManager.showBootMessage(msg, always);
7145     }
7146
7147     @Override
7148     public void keyguardGoingAway(int flags) {
7149         enforceNotIsolatedCaller("keyguardGoingAway");
7150         final long token = Binder.clearCallingIdentity();
7151         try {
7152             synchronized (this) {
7153                 mKeyguardController.keyguardGoingAway(flags);
7154             }
7155         } finally {
7156             Binder.restoreCallingIdentity(token);
7157         }
7158     }
7159
7160     /**
7161      * @return whther the keyguard is currently locked.
7162      */
7163     boolean isKeyguardLocked() {
7164         return mKeyguardController.isKeyguardLocked();
7165     }
7166
7167     final void finishBooting() {
7168         synchronized (this) {
7169             if (!mBootAnimationComplete) {
7170                 mCallFinishBooting = true;
7171                 return;
7172             }
7173             mCallFinishBooting = false;
7174         }
7175
7176         ArraySet<String> completedIsas = new ArraySet<String>();
7177         for (String abi : Build.SUPPORTED_ABIS) {
7178             zygoteProcess.establishZygoteConnectionForAbi(abi);
7179             final String instructionSet = VMRuntime.getInstructionSet(abi);
7180             if (!completedIsas.contains(instructionSet)) {
7181                 try {
7182                     mInstaller.markBootComplete(VMRuntime.getInstructionSet(abi));
7183                 } catch (InstallerException e) {
7184                     Slog.w(TAG, "Unable to mark boot complete for abi: " + abi + " (" +
7185                             e.getMessage() +")");
7186                 }
7187                 completedIsas.add(instructionSet);
7188             }
7189         }
7190
7191         IntentFilter pkgFilter = new IntentFilter();
7192         pkgFilter.addAction(Intent.ACTION_QUERY_PACKAGE_RESTART);
7193         pkgFilter.addDataScheme("package");
7194         mContext.registerReceiver(new BroadcastReceiver() {
7195             @Override
7196             public void onReceive(Context context, Intent intent) {
7197                 String[] pkgs = intent.getStringArrayExtra(Intent.EXTRA_PACKAGES);
7198                 if (pkgs != null) {
7199                     for (String pkg : pkgs) {
7200                         synchronized (ActivityManagerService.this) {
7201                             if (forceStopPackageLocked(pkg, -1, false, false, false, false, false,
7202                                     0, "query restart")) {
7203                                 setResultCode(Activity.RESULT_OK);
7204                                 return;
7205                             }
7206                         }
7207                     }
7208                 }
7209             }
7210         }, pkgFilter);
7211
7212         IntentFilter dumpheapFilter = new IntentFilter();
7213         dumpheapFilter.addAction(DumpHeapActivity.ACTION_DELETE_DUMPHEAP);
7214         mContext.registerReceiver(new BroadcastReceiver() {
7215             @Override
7216             public void onReceive(Context context, Intent intent) {
7217                 if (intent.getBooleanExtra(DumpHeapActivity.EXTRA_DELAY_DELETE, false)) {
7218                     mHandler.sendEmptyMessageDelayed(POST_DUMP_HEAP_NOTIFICATION_MSG, 5*60*1000);
7219                 } else {
7220                     mHandler.sendEmptyMessage(POST_DUMP_HEAP_NOTIFICATION_MSG);
7221                 }
7222             }
7223         }, dumpheapFilter);
7224
7225         // Let system services know.
7226         mSystemServiceManager.startBootPhase(SystemService.PHASE_BOOT_COMPLETED);
7227
7228         synchronized (this) {
7229             // Ensure that any processes we had put on hold are now started
7230             // up.
7231             final int NP = mProcessesOnHold.size();
7232             if (NP > 0) {
7233                 ArrayList<ProcessRecord> procs =
7234                     new ArrayList<ProcessRecord>(mProcessesOnHold);
7235                 for (int ip=0; ip<NP; ip++) {
7236                     if (DEBUG_PROCESSES) Slog.v(TAG_PROCESSES, "Starting process on hold: "
7237                             + procs.get(ip));
7238                     startProcessLocked(procs.get(ip), "on-hold", null);
7239                 }
7240             }
7241
7242             if (mFactoryTest != FactoryTest.FACTORY_TEST_LOW_LEVEL) {
7243                 // Start looking for apps that are abusing wake locks.
7244                 Message nmsg = mHandler.obtainMessage(CHECK_EXCESSIVE_WAKE_LOCKS_MSG);
7245                 mHandler.sendMessageDelayed(nmsg, mConstants.POWER_CHECK_DELAY);
7246                 // Tell anyone interested that we are done booting!
7247                 SystemProperties.set("sys.boot_completed", "1");
7248
7249                 // And trigger dev.bootcomplete if we are not showing encryption progress
7250                 if (!"trigger_restart_min_framework".equals(SystemProperties.get("vold.decrypt"))
7251                     || "".equals(SystemProperties.get("vold.encrypt_progress"))) {
7252                     SystemProperties.set("dev.bootcomplete", "1");
7253                 }
7254                 mUserController.sendBootCompletedLocked(
7255                         new IIntentReceiver.Stub() {
7256                             @Override
7257                             public void performReceive(Intent intent, int resultCode,
7258                                     String data, Bundle extras, boolean ordered,
7259                                     boolean sticky, int sendingUser) {
7260                                 synchronized (ActivityManagerService.this) {
7261                                     requestPssAllProcsLocked(SystemClock.uptimeMillis(),
7262                                             true, false);
7263                                 }
7264                             }
7265                         });
7266                 scheduleStartProfilesLocked();
7267             }
7268         }
7269     }
7270
7271     @Override
7272     public void bootAnimationComplete() {
7273         final boolean callFinishBooting;
7274         synchronized (this) {
7275             callFinishBooting = mCallFinishBooting;
7276             mBootAnimationComplete = true;
7277         }
7278         if (callFinishBooting) {
7279             Trace.traceBegin(Trace.TRACE_TAG_ACTIVITY_MANAGER, "FinishBooting");
7280             finishBooting();
7281             Trace.traceEnd(Trace.TRACE_TAG_ACTIVITY_MANAGER);
7282         }
7283     }
7284
7285     final void ensureBootCompleted() {
7286         boolean booting;
7287         boolean enableScreen;
7288         synchronized (this) {
7289             booting = mBooting;
7290             mBooting = false;
7291             enableScreen = !mBooted;
7292             mBooted = true;
7293         }
7294
7295         if (booting) {
7296             Trace.traceBegin(Trace.TRACE_TAG_ACTIVITY_MANAGER, "FinishBooting");
7297             finishBooting();
7298             Trace.traceEnd(Trace.TRACE_TAG_ACTIVITY_MANAGER);
7299         }
7300
7301         if (enableScreen) {
7302             enableScreenAfterBoot();
7303         }
7304     }
7305
7306     @Override
7307     public final void activityResumed(IBinder token) {
7308         final long origId = Binder.clearCallingIdentity();
7309         synchronized(this) {
7310             ActivityRecord.activityResumedLocked(token);
7311             mWindowManager.notifyAppResumedFinished(token);
7312         }
7313         Binder.restoreCallingIdentity(origId);
7314     }
7315
7316     @Override
7317     public final void activityPaused(IBinder token) {
7318         final long origId = Binder.clearCallingIdentity();
7319         synchronized(this) {
7320             ActivityStack stack = ActivityRecord.getStackLocked(token);
7321             if (stack != null) {
7322                 stack.activityPausedLocked(token, false);
7323             }
7324         }
7325         Binder.restoreCallingIdentity(origId);
7326     }
7327
7328     @Override
7329     public final void activityStopped(IBinder token, Bundle icicle,
7330             PersistableBundle persistentState, CharSequence description) {
7331         if (DEBUG_ALL) Slog.v(TAG, "Activity stopped: token=" + token);
7332
7333         // Refuse possible leaked file descriptors
7334         if (icicle != null && icicle.hasFileDescriptors()) {
7335             throw new IllegalArgumentException("File descriptors passed in Bundle");
7336         }
7337
7338         final long origId = Binder.clearCallingIdentity();
7339
7340         synchronized (this) {
7341             final ActivityRecord r = ActivityRecord.isInStackLocked(token);
7342             if (r != null) {
7343                 r.activityStoppedLocked(icicle, persistentState, description);
7344             }
7345         }
7346
7347         trimApplications();
7348
7349         Binder.restoreCallingIdentity(origId);
7350     }
7351
7352     @Override
7353     public final void activityDestroyed(IBinder token) {
7354         if (DEBUG_SWITCH) Slog.v(TAG_SWITCH, "ACTIVITY DESTROYED: " + token);
7355         synchronized (this) {
7356             ActivityStack stack = ActivityRecord.getStackLocked(token);
7357             if (stack != null) {
7358                 stack.activityDestroyedLocked(token, "activityDestroyed");
7359             }
7360         }
7361     }
7362
7363     @Override
7364     public final void activityRelaunched(IBinder token) {
7365         final long origId = Binder.clearCallingIdentity();
7366         synchronized (this) {
7367             mStackSupervisor.activityRelaunchedLocked(token);
7368         }
7369         Binder.restoreCallingIdentity(origId);
7370     }
7371
7372     @Override
7373     public void reportSizeConfigurations(IBinder token, int[] horizontalSizeConfiguration,
7374             int[] verticalSizeConfigurations, int[] smallestSizeConfigurations) {
7375         if (DEBUG_CONFIGURATION) Slog.v(TAG, "Report configuration: " + token + " "
7376                 + horizontalSizeConfiguration + " " + verticalSizeConfigurations);
7377         synchronized (this) {
7378             ActivityRecord record = ActivityRecord.isInStackLocked(token);
7379             if (record == null) {
7380                 throw new IllegalArgumentException("reportSizeConfigurations: ActivityRecord not "
7381                         + "found for: " + token);
7382             }
7383             record.setSizeConfigurations(horizontalSizeConfiguration,
7384                     verticalSizeConfigurations, smallestSizeConfigurations);
7385         }
7386     }
7387
7388     @Override
7389     public final void backgroundResourcesReleased(IBinder token) {
7390         final long origId = Binder.clearCallingIdentity();
7391         try {
7392             synchronized (this) {
7393                 ActivityStack stack = ActivityRecord.getStackLocked(token);
7394                 if (stack != null) {
7395                     stack.backgroundResourcesReleased();
7396                 }
7397             }
7398         } finally {
7399             Binder.restoreCallingIdentity(origId);
7400         }
7401     }
7402
7403     @Override
7404     public final void notifyLaunchTaskBehindComplete(IBinder token) {
7405         mStackSupervisor.scheduleLaunchTaskBehindComplete(token);
7406     }
7407
7408     @Override
7409     public final void notifyEnterAnimationComplete(IBinder token) {
7410         mHandler.sendMessage(mHandler.obtainMessage(ENTER_ANIMATION_COMPLETE_MSG, token));
7411     }
7412
7413     @Override
7414     public String getCallingPackage(IBinder token) {
7415         synchronized (this) {
7416             ActivityRecord r = getCallingRecordLocked(token);
7417             return r != null ? r.info.packageName : null;
7418         }
7419     }
7420
7421     @Override
7422     public ComponentName getCallingActivity(IBinder token) {
7423         synchronized (this) {
7424             ActivityRecord r = getCallingRecordLocked(token);
7425             return r != null ? r.intent.getComponent() : null;
7426         }
7427     }
7428
7429     private ActivityRecord getCallingRecordLocked(IBinder token) {
7430         ActivityRecord r = ActivityRecord.isInStackLocked(token);
7431         if (r == null) {
7432             return null;
7433         }
7434         return r.resultTo;
7435     }
7436
7437     @Override
7438     public ComponentName getActivityClassForToken(IBinder token) {
7439         synchronized(this) {
7440             ActivityRecord r = ActivityRecord.isInStackLocked(token);
7441             if (r == null) {
7442                 return null;
7443             }
7444             return r.intent.getComponent();
7445         }
7446     }
7447
7448     @Override
7449     public String getPackageForToken(IBinder token) {
7450         synchronized(this) {
7451             ActivityRecord r = ActivityRecord.isInStackLocked(token);
7452             if (r == null) {
7453                 return null;
7454             }
7455             return r.packageName;
7456         }
7457     }
7458
7459     @Override
7460     public boolean isRootVoiceInteraction(IBinder token) {
7461         synchronized(this) {
7462             ActivityRecord r = ActivityRecord.isInStackLocked(token);
7463             if (r == null) {
7464                 return false;
7465             }
7466             return r.rootVoiceInteraction;
7467         }
7468     }
7469
7470     @Override
7471     public IIntentSender getIntentSender(int type,
7472             String packageName, IBinder token, String resultWho,
7473             int requestCode, Intent[] intents, String[] resolvedTypes,
7474             int flags, Bundle bOptions, int userId) {
7475         enforceNotIsolatedCaller("getIntentSender");
7476         // Refuse possible leaked file descriptors
7477         if (intents != null) {
7478             if (intents.length < 1) {
7479                 throw new IllegalArgumentException("Intents array length must be >= 1");
7480             }
7481             for (int i=0; i<intents.length; i++) {
7482                 Intent intent = intents[i];
7483                 if (intent != null) {
7484                     if (intent.hasFileDescriptors()) {
7485                         throw new IllegalArgumentException("File descriptors passed in Intent");
7486                     }
7487                     if (type == ActivityManager.INTENT_SENDER_BROADCAST &&
7488                             (intent.getFlags()&Intent.FLAG_RECEIVER_BOOT_UPGRADE) != 0) {
7489                         throw new IllegalArgumentException(
7490                                 "Can't use FLAG_RECEIVER_BOOT_UPGRADE here");
7491                     }
7492                     intents[i] = new Intent(intent);
7493                 }
7494             }
7495             if (resolvedTypes != null && resolvedTypes.length != intents.length) {
7496                 throw new IllegalArgumentException(
7497                         "Intent array length does not match resolvedTypes length");
7498             }
7499         }
7500         if (bOptions != null) {
7501             if (bOptions.hasFileDescriptors()) {
7502                 throw new IllegalArgumentException("File descriptors passed in options");
7503             }
7504         }
7505
7506         synchronized(this) {
7507             int callingUid = Binder.getCallingUid();
7508             int origUserId = userId;
7509             userId = mUserController.handleIncomingUser(Binder.getCallingPid(), callingUid, userId,
7510                     type == ActivityManager.INTENT_SENDER_BROADCAST,
7511                     ALLOW_NON_FULL, "getIntentSender", null);
7512             if (origUserId == UserHandle.USER_CURRENT) {
7513                 // We don't want to evaluate this until the pending intent is
7514                 // actually executed.  However, we do want to always do the
7515                 // security checking for it above.
7516                 userId = UserHandle.USER_CURRENT;
7517             }
7518             try {
7519                 if (callingUid != 0 && callingUid != SYSTEM_UID) {
7520                     final int uid = AppGlobals.getPackageManager().getPackageUid(packageName,
7521                             MATCH_DEBUG_TRIAGED_MISSING, UserHandle.getUserId(callingUid));
7522                     if (!UserHandle.isSameApp(callingUid, uid)) {
7523                         String msg = "Permission Denial: getIntentSender() from pid="
7524                             + Binder.getCallingPid()
7525                             + ", uid=" + Binder.getCallingUid()
7526                             + ", (need uid=" + uid + ")"
7527                             + " is not allowed to send as package " + packageName;
7528                         Slog.w(TAG, msg);
7529                         throw new SecurityException(msg);
7530                     }
7531                 }
7532
7533                 return getIntentSenderLocked(type, packageName, callingUid, userId,
7534                         token, resultWho, requestCode, intents, resolvedTypes, flags, bOptions);
7535
7536             } catch (RemoteException e) {
7537                 throw new SecurityException(e);
7538             }
7539         }
7540     }
7541
7542     IIntentSender getIntentSenderLocked(int type, String packageName,
7543             int callingUid, int userId, IBinder token, String resultWho,
7544             int requestCode, Intent[] intents, String[] resolvedTypes, int flags,
7545             Bundle bOptions) {
7546         if (DEBUG_MU) Slog.v(TAG_MU, "getIntentSenderLocked(): uid=" + callingUid);
7547         ActivityRecord activity = null;
7548         if (type == ActivityManager.INTENT_SENDER_ACTIVITY_RESULT) {
7549             activity = ActivityRecord.isInStackLocked(token);
7550             if (activity == null) {
7551                 Slog.w(TAG, "Failed createPendingResult: activity " + token + " not in any stack");
7552                 return null;
7553             }
7554             if (activity.finishing) {
7555                 Slog.w(TAG, "Failed createPendingResult: activity " + activity + " is finishing");
7556                 return null;
7557             }
7558         }
7559
7560         // We're going to be splicing together extras before sending, so we're
7561         // okay poking into any contained extras.
7562         if (intents != null) {
7563             for (int i = 0; i < intents.length; i++) {
7564                 intents[i].setDefusable(true);
7565             }
7566         }
7567         Bundle.setDefusable(bOptions, true);
7568
7569         final boolean noCreate = (flags&PendingIntent.FLAG_NO_CREATE) != 0;
7570         final boolean cancelCurrent = (flags&PendingIntent.FLAG_CANCEL_CURRENT) != 0;
7571         final boolean updateCurrent = (flags&PendingIntent.FLAG_UPDATE_CURRENT) != 0;
7572         flags &= ~(PendingIntent.FLAG_NO_CREATE|PendingIntent.FLAG_CANCEL_CURRENT
7573                 |PendingIntent.FLAG_UPDATE_CURRENT);
7574
7575         PendingIntentRecord.Key key = new PendingIntentRecord.Key(
7576                 type, packageName, activity, resultWho,
7577                 requestCode, intents, resolvedTypes, flags, bOptions, userId);
7578         WeakReference<PendingIntentRecord> ref;
7579         ref = mIntentSenderRecords.get(key);
7580         PendingIntentRecord rec = ref != null ? ref.get() : null;
7581         if (rec != null) {
7582             if (!cancelCurrent) {
7583                 if (updateCurrent) {
7584                     if (rec.key.requestIntent != null) {
7585                         rec.key.requestIntent.replaceExtras(intents != null ?
7586                                 intents[intents.length - 1] : null);
7587                     }
7588                     if (intents != null) {
7589                         intents[intents.length-1] = rec.key.requestIntent;
7590                         rec.key.allIntents = intents;
7591                         rec.key.allResolvedTypes = resolvedTypes;
7592                     } else {
7593                         rec.key.allIntents = null;
7594                         rec.key.allResolvedTypes = null;
7595                     }
7596                 }
7597                 return rec;
7598             }
7599             makeIntentSenderCanceledLocked(rec);
7600             mIntentSenderRecords.remove(key);
7601         }
7602         if (noCreate) {
7603             return rec;
7604         }
7605         rec = new PendingIntentRecord(this, key, callingUid);
7606         mIntentSenderRecords.put(key, rec.ref);
7607         if (type == ActivityManager.INTENT_SENDER_ACTIVITY_RESULT) {
7608             if (activity.pendingResults == null) {
7609                 activity.pendingResults
7610                         = new HashSet<WeakReference<PendingIntentRecord>>();
7611             }
7612             activity.pendingResults.add(rec.ref);
7613         }
7614         return rec;
7615     }
7616
7617     @Override
7618     public int sendIntentSender(IIntentSender target, IBinder whitelistToken, int code,
7619             Intent intent, String resolvedType,
7620             IIntentReceiver finishedReceiver, String requiredPermission, Bundle options) {
7621         if (target instanceof PendingIntentRecord) {
7622             return ((PendingIntentRecord)target).sendWithResult(code, intent, resolvedType,
7623                     whitelistToken, finishedReceiver, requiredPermission, options);
7624         } else {
7625             if (intent == null) {
7626                 // Weird case: someone has given us their own custom IIntentSender, and now
7627                 // they have someone else trying to send to it but of course this isn't
7628                 // really a PendingIntent, so there is no base Intent, and the caller isn't
7629                 // supplying an Intent... but we never want to dispatch a null Intent to
7630                 // a receiver, so um...  let's make something up.
7631                 Slog.wtf(TAG, "Can't use null intent with direct IIntentSender call");
7632                 intent = new Intent(Intent.ACTION_MAIN);
7633             }
7634             try {
7635                 target.send(code, intent, resolvedType, whitelistToken, null,
7636                         requiredPermission, options);
7637             } catch (RemoteException e) {
7638             }
7639             // Platform code can rely on getting a result back when the send is done, but if
7640             // this intent sender is from outside of the system we can't rely on it doing that.
7641             // So instead we don't give it the result receiver, and instead just directly
7642             // report the finish immediately.
7643             if (finishedReceiver != null) {
7644                 try {
7645                     finishedReceiver.performReceive(intent, 0,
7646                             null, null, false, false, UserHandle.getCallingUserId());
7647                 } catch (RemoteException e) {
7648                 }
7649             }
7650             return 0;
7651         }
7652     }
7653
7654     @Override
7655     public void cancelIntentSender(IIntentSender sender) {
7656         if (!(sender instanceof PendingIntentRecord)) {
7657             return;
7658         }
7659         synchronized(this) {
7660             PendingIntentRecord rec = (PendingIntentRecord)sender;
7661             try {
7662                 final int uid = AppGlobals.getPackageManager().getPackageUid(rec.key.packageName,
7663                         MATCH_DEBUG_TRIAGED_MISSING, UserHandle.getCallingUserId());
7664                 if (!UserHandle.isSameApp(uid, Binder.getCallingUid())) {
7665                     String msg = "Permission Denial: cancelIntentSender() from pid="
7666                         + Binder.getCallingPid()
7667                         + ", uid=" + Binder.getCallingUid()
7668                         + " is not allowed to cancel package "
7669                         + rec.key.packageName;
7670                     Slog.w(TAG, msg);
7671                     throw new SecurityException(msg);
7672                 }
7673             } catch (RemoteException e) {
7674                 throw new SecurityException(e);
7675             }
7676             cancelIntentSenderLocked(rec, true);
7677         }
7678     }
7679
7680     void cancelIntentSenderLocked(PendingIntentRecord rec, boolean cleanActivity) {
7681         makeIntentSenderCanceledLocked(rec);
7682         mIntentSenderRecords.remove(rec.key);
7683         if (cleanActivity && rec.key.activity != null) {
7684             rec.key.activity.pendingResults.remove(rec.ref);
7685         }
7686     }
7687
7688     void makeIntentSenderCanceledLocked(PendingIntentRecord rec) {
7689         rec.canceled = true;
7690         RemoteCallbackList<IResultReceiver> callbacks = rec.detachCancelListenersLocked();
7691         if (callbacks != null) {
7692             mHandler.obtainMessage(DISPATCH_PENDING_INTENT_CANCEL_MSG, callbacks).sendToTarget();
7693         }
7694     }
7695
7696     @Override
7697     public String getPackageForIntentSender(IIntentSender pendingResult) {
7698         if (!(pendingResult instanceof PendingIntentRecord)) {
7699             return null;
7700         }
7701         try {
7702             PendingIntentRecord res = (PendingIntentRecord)pendingResult;
7703             return res.key.packageName;
7704         } catch (ClassCastException e) {
7705         }
7706         return null;
7707     }
7708
7709     @Override
7710     public void registerIntentSenderCancelListener(IIntentSender sender, IResultReceiver receiver) {
7711         if (!(sender instanceof PendingIntentRecord)) {
7712             return;
7713         }
7714         synchronized(this) {
7715             ((PendingIntentRecord)sender).registerCancelListenerLocked(receiver);
7716         }
7717     }
7718
7719     @Override
7720     public void unregisterIntentSenderCancelListener(IIntentSender sender,
7721             IResultReceiver receiver) {
7722         if (!(sender instanceof PendingIntentRecord)) {
7723             return;
7724         }
7725         synchronized(this) {
7726             ((PendingIntentRecord)sender).unregisterCancelListenerLocked(receiver);
7727         }
7728     }
7729
7730     @Override
7731     public int getUidForIntentSender(IIntentSender sender) {
7732         if (sender instanceof PendingIntentRecord) {
7733             try {
7734                 PendingIntentRecord res = (PendingIntentRecord)sender;
7735                 return res.uid;
7736             } catch (ClassCastException e) {
7737             }
7738         }
7739         return -1;
7740     }
7741
7742     @Override
7743     public boolean isIntentSenderTargetedToPackage(IIntentSender pendingResult) {
7744         if (!(pendingResult instanceof PendingIntentRecord)) {
7745             return false;
7746         }
7747         try {
7748             PendingIntentRecord res = (PendingIntentRecord)pendingResult;
7749             if (res.key.allIntents == null) {
7750                 return false;
7751             }
7752             for (int i=0; i<res.key.allIntents.length; i++) {
7753                 Intent intent = res.key.allIntents[i];
7754                 if (intent.getPackage() != null && intent.getComponent() != null) {
7755                     return false;
7756                 }
7757             }
7758             return true;
7759         } catch (ClassCastException e) {
7760         }
7761         return false;
7762     }
7763
7764     @Override
7765     public boolean isIntentSenderAnActivity(IIntentSender pendingResult) {
7766         if (!(pendingResult instanceof PendingIntentRecord)) {
7767             return false;
7768         }
7769         try {
7770             PendingIntentRecord res = (PendingIntentRecord)pendingResult;
7771             if (res.key.type == ActivityManager.INTENT_SENDER_ACTIVITY) {
7772                 return true;
7773             }
7774             return false;
7775         } catch (ClassCastException e) {
7776         }
7777         return false;
7778     }
7779
7780     @Override
7781     public Intent getIntentForIntentSender(IIntentSender pendingResult) {
7782         enforceCallingPermission(Manifest.permission.GET_INTENT_SENDER_INTENT,
7783                 "getIntentForIntentSender()");
7784         if (!(pendingResult instanceof PendingIntentRecord)) {
7785             return null;
7786         }
7787         try {
7788             PendingIntentRecord res = (PendingIntentRecord)pendingResult;
7789             return res.key.requestIntent != null ? new Intent(res.key.requestIntent) : null;
7790         } catch (ClassCastException e) {
7791         }
7792         return null;
7793     }
7794
7795     @Override
7796     public String getTagForIntentSender(IIntentSender pendingResult, String prefix) {
7797         if (!(pendingResult instanceof PendingIntentRecord)) {
7798             return null;
7799         }
7800         try {
7801             PendingIntentRecord res = (PendingIntentRecord)pendingResult;
7802             synchronized (this) {
7803                 return getTagForIntentSenderLocked(res, prefix);
7804             }
7805         } catch (ClassCastException e) {
7806         }
7807         return null;
7808     }
7809
7810     String getTagForIntentSenderLocked(PendingIntentRecord res, String prefix) {
7811         final Intent intent = res.key.requestIntent;
7812         if (intent != null) {
7813             if (res.lastTag != null && res.lastTagPrefix == prefix && (res.lastTagPrefix == null
7814                     || res.lastTagPrefix.equals(prefix))) {
7815                 return res.lastTag;
7816             }
7817             res.lastTagPrefix = prefix;
7818             final StringBuilder sb = new StringBuilder(128);
7819             if (prefix != null) {
7820                 sb.append(prefix);
7821             }
7822             if (intent.getAction() != null) {
7823                 sb.append(intent.getAction());
7824             } else if (intent.getComponent() != null) {
7825                 intent.getComponent().appendShortString(sb);
7826             } else {
7827                 sb.append("?");
7828             }
7829             return res.lastTag = sb.toString();
7830         }
7831         return null;
7832     }
7833
7834     @Override
7835     public void setProcessLimit(int max) {
7836         enforceCallingPermission(android.Manifest.permission.SET_PROCESS_LIMIT,
7837                 "setProcessLimit()");
7838         synchronized (this) {
7839             mConstants.setOverrideMaxCachedProcesses(max);
7840         }
7841         trimApplications();
7842     }
7843
7844     @Override
7845     public int getProcessLimit() {
7846         synchronized (this) {
7847             return mConstants.getOverrideMaxCachedProcesses();
7848         }
7849     }
7850
7851     void importanceTokenDied(ImportanceToken token) {
7852         synchronized (ActivityManagerService.this) {
7853             synchronized (mPidsSelfLocked) {
7854                 ImportanceToken cur
7855                     = mImportantProcesses.get(token.pid);
7856                 if (cur != token) {
7857                     return;
7858                 }
7859                 mImportantProcesses.remove(token.pid);
7860                 ProcessRecord pr = mPidsSelfLocked.get(token.pid);
7861                 if (pr == null) {
7862                     return;
7863                 }
7864                 pr.forcingToImportant = null;
7865                 updateProcessForegroundLocked(pr, false, false);
7866             }
7867             updateOomAdjLocked();
7868         }
7869     }
7870
7871     @Override
7872     public void setProcessImportant(IBinder token, int pid, boolean isForeground, String reason) {
7873         enforceCallingPermission(android.Manifest.permission.SET_PROCESS_LIMIT,
7874                 "setProcessImportant()");
7875         synchronized(this) {
7876             boolean changed = false;
7877
7878             synchronized (mPidsSelfLocked) {
7879                 ProcessRecord pr = mPidsSelfLocked.get(pid);
7880                 if (pr == null && isForeground) {
7881                     Slog.w(TAG, "setProcessForeground called on unknown pid: " + pid);
7882                     return;
7883                 }
7884                 ImportanceToken oldToken = mImportantProcesses.get(pid);
7885                 if (oldToken != null) {
7886                     oldToken.token.unlinkToDeath(oldToken, 0);
7887                     mImportantProcesses.remove(pid);
7888                     if (pr != null) {
7889                         pr.forcingToImportant = null;
7890                     }
7891                     changed = true;
7892                 }
7893                 if (isForeground && token != null) {
7894                     ImportanceToken newToken = new ImportanceToken(pid, token, reason) {
7895                         @Override
7896                         public void binderDied() {
7897                             importanceTokenDied(this);
7898                         }
7899                     };
7900                     try {
7901                         token.linkToDeath(newToken, 0);
7902                         mImportantProcesses.put(pid, newToken);
7903                         pr.forcingToImportant = newToken;
7904                         changed = true;
7905                     } catch (RemoteException e) {
7906                         // If the process died while doing this, we will later
7907                         // do the cleanup with the process death link.
7908                     }
7909                 }
7910             }
7911
7912             if (changed) {
7913                 updateOomAdjLocked();
7914             }
7915         }
7916     }
7917
7918     @Override
7919     public boolean isAppForeground(int uid) throws RemoteException {
7920         int callerUid = Binder.getCallingUid();
7921         if (UserHandle.isCore(callerUid) || callerUid == uid) {
7922             return isAppForegroundInternal(uid);
7923         }
7924         return false;
7925     }
7926
7927     private boolean isAppForegroundInternal(int uid) {
7928         synchronized (this) {
7929             UidRecord uidRec = mActiveUids.get(uid);
7930             if (uidRec == null || uidRec.idle) {
7931                 return false;
7932             }
7933             return uidRec.curProcState <= ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND;
7934         }
7935     }
7936
7937     // NOTE: this is an internal method used by the OnShellCommand implementation only and should
7938     // be guarded by permission checking.
7939     int getUidState(int uid) {
7940         synchronized (this) {
7941             return getUidStateLocked(uid);
7942         }
7943     }
7944
7945     int getUidStateLocked(int uid) {
7946         UidRecord uidRec = mActiveUids.get(uid);
7947         return uidRec == null ? ActivityManager.PROCESS_STATE_NONEXISTENT : uidRec.curProcState;
7948     }
7949
7950     @Override
7951     public boolean isInMultiWindowMode(IBinder token) {
7952         final long origId = Binder.clearCallingIdentity();
7953         try {
7954             synchronized(this) {
7955                 final ActivityRecord r = ActivityRecord.isInStackLocked(token);
7956                 if (r == null) {
7957                     return false;
7958                 }
7959                 // An activity is consider to be in multi-window mode if its task isn't fullscreen.
7960                 return !r.getTask().mFullscreen;
7961             }
7962         } finally {
7963             Binder.restoreCallingIdentity(origId);
7964         }
7965     }
7966
7967     @Override
7968     public boolean isInPictureInPictureMode(IBinder token) {
7969         final long origId = Binder.clearCallingIdentity();
7970         try {
7971             synchronized(this) {
7972                 return isInPictureInPictureMode(ActivityRecord.forTokenLocked(token));
7973             }
7974         } finally {
7975             Binder.restoreCallingIdentity(origId);
7976         }
7977     }
7978
7979     private boolean isInPictureInPictureMode(ActivityRecord r) {
7980         if (r == null || r.getStack() == null || !r.getStack().isPinnedStack() ||
7981                 r.getStack().isInStackLocked(r) == null) {
7982             return false;
7983         }
7984
7985         // If we are animating to fullscreen then we have already dispatched the PIP mode
7986         // changed, so we should reflect that check here as well.
7987         final PinnedActivityStack stack = r.getStack();
7988         final PinnedStackWindowController windowController = stack.getWindowContainerController();
7989         return !windowController.isAnimatingBoundsToFullscreen();
7990     }
7991
7992     @Override
7993     public boolean enterPictureInPictureMode(IBinder token, final PictureInPictureParams params) {
7994         final long origId = Binder.clearCallingIdentity();
7995         try {
7996             synchronized(this) {
7997                 final ActivityRecord r = ensureValidPictureInPictureActivityParamsLocked(
7998                         "enterPictureInPictureMode", token, params);
7999
8000                 // If the activity is already in picture in picture mode, then just return early
8001                 if (isInPictureInPictureMode(r)) {
8002                     return true;
8003                 }
8004
8005                 // Activity supports picture-in-picture, now check that we can enter PiP at this
8006                 // point, if it is
8007                 if (!r.checkEnterPictureInPictureState("enterPictureInPictureMode",
8008                         false /* noThrow */, false /* beforeStopping */)) {
8009                     return false;
8010                 }
8011
8012                 final Runnable enterPipRunnable = () -> {
8013                     // Only update the saved args from the args that are set
8014                     r.pictureInPictureArgs.copyOnlySet(params);
8015                     final float aspectRatio = r.pictureInPictureArgs.getAspectRatio();
8016                     final List<RemoteAction> actions = r.pictureInPictureArgs.getActions();
8017                     // Adjust the source bounds by the insets for the transition down
8018                     final Rect sourceBounds = new Rect(r.pictureInPictureArgs.getSourceRectHint());
8019                     mStackSupervisor.moveActivityToPinnedStackLocked(r, sourceBounds, aspectRatio,
8020                             true /* moveHomeStackToFront */, "enterPictureInPictureMode");
8021                     final PinnedActivityStack stack = mStackSupervisor.getStack(PINNED_STACK_ID);
8022                     stack.setPictureInPictureAspectRatio(aspectRatio);
8023                     stack.setPictureInPictureActions(actions);
8024
8025                     MetricsLogger.action(mContext, MetricsEvent.ACTION_PICTURE_IN_PICTURE_ENTERED,
8026                             r.supportsPictureInPictureWhilePausing);
8027                     logPictureInPictureArgs(params);
8028                 };
8029
8030                 if (isKeyguardLocked()) {
8031                     // If the keyguard is showing or occluded, then try and dismiss it before
8032                     // entering picture-in-picture (this will prompt the user to authenticate if the
8033                     // device is currently locked).
8034                     try {
8035                         dismissKeyguard(token, new IKeyguardDismissCallback.Stub() {
8036                             @Override
8037                             public void onDismissError() throws RemoteException {
8038                                 // Do nothing
8039                             }
8040
8041                             @Override
8042                             public void onDismissSucceeded() throws RemoteException {
8043                                 mHandler.post(enterPipRunnable);
8044                             }
8045
8046                             @Override
8047                             public void onDismissCancelled() throws RemoteException {
8048                                 // Do nothing
8049                             }
8050                         });
8051                     } catch (RemoteException e) {
8052                         // Local call
8053                     }
8054                 } else {
8055                     // Enter picture in picture immediately otherwise
8056                     enterPipRunnable.run();
8057                 }
8058                 return true;
8059             }
8060         } finally {
8061             Binder.restoreCallingIdentity(origId);
8062         }
8063     }
8064
8065     @Override
8066     public void setPictureInPictureParams(IBinder token, final PictureInPictureParams params) {
8067         final long origId = Binder.clearCallingIdentity();
8068         try {
8069             synchronized(this) {
8070                 final ActivityRecord r = ensureValidPictureInPictureActivityParamsLocked(
8071                         "setPictureInPictureParams", token, params);
8072
8073                 // Only update the saved args from the args that are set
8074                 r.pictureInPictureArgs.copyOnlySet(params);
8075                 if (r.getStack().getStackId() == PINNED_STACK_ID) {
8076                     // If the activity is already in picture-in-picture, update the pinned stack now
8077                     // if it is not already expanding to fullscreen. Otherwise, the arguments will
8078                     // be used the next time the activity enters PiP
8079                     final PinnedActivityStack stack = r.getStack();
8080                     if (!stack.isAnimatingBoundsToFullscreen()) {
8081                         stack.setPictureInPictureAspectRatio(
8082                                 r.pictureInPictureArgs.getAspectRatio());
8083                         stack.setPictureInPictureActions(r.pictureInPictureArgs.getActions());
8084                     }
8085                 }
8086                 logPictureInPictureArgs(params);
8087             }
8088         } finally {
8089             Binder.restoreCallingIdentity(origId);
8090         }
8091     }
8092
8093     @Override
8094     public int getMaxNumPictureInPictureActions(IBinder token) {
8095         // Currently, this is a static constant, but later, we may change this to be dependent on
8096         // the context of the activity
8097         return 3;
8098     }
8099
8100     private void logPictureInPictureArgs(PictureInPictureParams params) {
8101         if (params.hasSetActions()) {
8102             MetricsLogger.histogram(mContext, "tron_varz_picture_in_picture_actions_count",
8103                     params.getActions().size());
8104         }
8105         if (params.hasSetAspectRatio()) {
8106             LogMaker lm = new LogMaker(MetricsEvent.ACTION_PICTURE_IN_PICTURE_ASPECT_RATIO_CHANGED);
8107             lm.addTaggedData(MetricsEvent.PICTURE_IN_PICTURE_ASPECT_RATIO, params.getAspectRatio());
8108             MetricsLogger.action(lm);
8109         }
8110     }
8111
8112     /**
8113      * Checks the state of the system and the activity associated with the given {@param token} to
8114      * verify that picture-in-picture is supported for that activity.
8115      *
8116      * @return the activity record for the given {@param token} if all the checks pass.
8117      */
8118     private ActivityRecord ensureValidPictureInPictureActivityParamsLocked(String caller,
8119             IBinder token, PictureInPictureParams params) {
8120         if (!mSupportsPictureInPicture) {
8121             throw new IllegalStateException(caller
8122                     + ": Device doesn't support picture-in-picture mode.");
8123         }
8124
8125         final ActivityRecord r = ActivityRecord.forTokenLocked(token);
8126         if (r == null) {
8127             throw new IllegalStateException(caller
8128                     + ": Can't find activity for token=" + token);
8129         }
8130
8131         if (!r.supportsPictureInPicture()) {
8132             throw new IllegalStateException(caller
8133                     + ": Current activity does not support picture-in-picture.");
8134         }
8135
8136         if (!StackId.isAllowedToEnterPictureInPicture(r.getStack().getStackId())) {
8137             throw new IllegalStateException(caller
8138                     + ": Activities on the home, assistant, or recents stack not supported");
8139         }
8140
8141         if (params.hasSetAspectRatio()
8142                 && !mWindowManager.isValidPictureInPictureAspectRatio(r.getStack().mDisplayId,
8143                         params.getAspectRatio())) {
8144             final float minAspectRatio = mContext.getResources().getFloat(
8145                     com.android.internal.R.dimen.config_pictureInPictureMinAspectRatio);
8146             final float maxAspectRatio = mContext.getResources().getFloat(
8147                     com.android.internal.R.dimen.config_pictureInPictureMaxAspectRatio);
8148             throw new IllegalArgumentException(String.format(caller
8149                     + ": Aspect ratio is too extreme (must be between %f and %f).",
8150                             minAspectRatio, maxAspectRatio));
8151         }
8152
8153         // Truncate the number of actions if necessary
8154         params.truncateActions(getMaxNumPictureInPictureActions(token));
8155
8156         return r;
8157     }
8158
8159     // =========================================================
8160     // PROCESS INFO
8161     // =========================================================
8162
8163     static class ProcessInfoService extends IProcessInfoService.Stub {
8164         final ActivityManagerService mActivityManagerService;
8165         ProcessInfoService(ActivityManagerService activityManagerService) {
8166             mActivityManagerService = activityManagerService;
8167         }
8168
8169         @Override
8170         public void getProcessStatesFromPids(/*in*/ int[] pids, /*out*/ int[] states) {
8171             mActivityManagerService.getProcessStatesAndOomScoresForPIDs(
8172                     /*in*/ pids, /*out*/ states, null);
8173         }
8174
8175         @Override
8176         public void getProcessStatesAndOomScoresFromPids(
8177                 /*in*/ int[] pids, /*out*/ int[] states, /*out*/ int[] scores) {
8178             mActivityManagerService.getProcessStatesAndOomScoresForPIDs(
8179                     /*in*/ pids, /*out*/ states, /*out*/ scores);
8180         }
8181     }
8182
8183     /**
8184      * For each PID in the given input array, write the current process state
8185      * for that process into the states array, or -1 to indicate that no
8186      * process with the given PID exists. If scores array is provided, write
8187      * the oom score for the process into the scores array, with INVALID_ADJ
8188      * indicating the PID doesn't exist.
8189      */
8190     public void getProcessStatesAndOomScoresForPIDs(
8191             /*in*/ int[] pids, /*out*/ int[] states, /*out*/ int[] scores) {
8192         if (scores != null) {
8193             enforceCallingPermission(android.Manifest.permission.GET_PROCESS_STATE_AND_OOM_SCORE,
8194                     "getProcessStatesAndOomScoresForPIDs()");
8195         }
8196
8197         if (pids == null) {
8198             throw new NullPointerException("pids");
8199         } else if (states == null) {
8200             throw new NullPointerException("states");
8201         } else if (pids.length != states.length) {
8202             throw new IllegalArgumentException("pids and states arrays have different lengths!");
8203         } else if (scores != null && pids.length != scores.length) {
8204             throw new IllegalArgumentException("pids and scores arrays have different lengths!");
8205         }
8206
8207         synchronized (mPidsSelfLocked) {
8208             for (int i = 0; i < pids.length; i++) {
8209                 ProcessRecord pr = mPidsSelfLocked.get(pids[i]);
8210                 states[i] = (pr == null) ? ActivityManager.PROCESS_STATE_NONEXISTENT :
8211                         pr.curProcState;
8212                 if (scores != null) {
8213                     scores[i] = (pr == null) ? ProcessList.INVALID_ADJ : pr.curAdj;
8214                 }
8215             }
8216         }
8217     }
8218
8219     // =========================================================
8220     // PERMISSIONS
8221     // =========================================================
8222
8223     static class PermissionController extends IPermissionController.Stub {
8224         ActivityManagerService mActivityManagerService;
8225         PermissionController(ActivityManagerService activityManagerService) {
8226             mActivityManagerService = activityManagerService;
8227         }
8228
8229         @Override
8230         public boolean checkPermission(String permission, int pid, int uid) {
8231             return mActivityManagerService.checkPermission(permission, pid,
8232                     uid) == PackageManager.PERMISSION_GRANTED;
8233         }
8234
8235         @Override
8236         public String[] getPackagesForUid(int uid) {
8237             return mActivityManagerService.mContext.getPackageManager()
8238                     .getPackagesForUid(uid);
8239         }
8240
8241         @Override
8242         public boolean isRuntimePermission(String permission) {
8243             try {
8244                 PermissionInfo info = mActivityManagerService.mContext.getPackageManager()
8245                         .getPermissionInfo(permission, 0);
8246                 return (info.protectionLevel & PermissionInfo.PROTECTION_MASK_BASE)
8247                         == PermissionInfo.PROTECTION_DANGEROUS;
8248             } catch (NameNotFoundException nnfe) {
8249                 Slog.e(TAG, "No such permission: "+ permission, nnfe);
8250             }
8251             return false;
8252         }
8253     }
8254
8255     class IntentFirewallInterface implements IntentFirewall.AMSInterface {
8256         @Override
8257         public int checkComponentPermission(String permission, int pid, int uid,
8258                 int owningUid, boolean exported) {
8259             return ActivityManagerService.this.checkComponentPermission(permission, pid, uid,
8260                     owningUid, exported);
8261         }
8262
8263         @Override
8264         public Object getAMSLock() {
8265             return ActivityManagerService.this;
8266         }
8267     }
8268
8269     /**
8270      * This can be called with or without the global lock held.
8271      */
8272     int checkComponentPermission(String permission, int pid, int uid,
8273             int owningUid, boolean exported) {
8274         if (pid == MY_PID) {
8275             return PackageManager.PERMISSION_GRANTED;
8276         }
8277         return ActivityManager.checkComponentPermission(permission, uid,
8278                 owningUid, exported);
8279     }
8280
8281     /**
8282      * As the only public entry point for permissions checking, this method
8283      * can enforce the semantic that requesting a check on a null global
8284      * permission is automatically denied.  (Internally a null permission
8285      * string is used when calling {@link #checkComponentPermission} in cases
8286      * when only uid-based security is needed.)
8287      *
8288      * This can be called with or without the global lock held.
8289      */
8290     @Override
8291     public int checkPermission(String permission, int pid, int uid) {
8292         if (permission == null) {
8293             return PackageManager.PERMISSION_DENIED;
8294         }
8295         return checkComponentPermission(permission, pid, uid, -1, true);
8296     }
8297
8298     @Override
8299     public int checkPermissionWithToken(String permission, int pid, int uid, IBinder callerToken) {
8300         if (permission == null) {
8301             return PackageManager.PERMISSION_DENIED;
8302         }
8303
8304         // We might be performing an operation on behalf of an indirect binder
8305         // invocation, e.g. via {@link #openContentUri}.  Check and adjust the
8306         // client identity accordingly before proceeding.
8307         Identity tlsIdentity = sCallerIdentity.get();
8308         if (tlsIdentity != null && tlsIdentity.token == callerToken) {
8309             Slog.d(TAG, "checkComponentPermission() adjusting {pid,uid} to {"
8310                     + tlsIdentity.pid + "," + tlsIdentity.uid + "}");
8311             uid = tlsIdentity.uid;
8312             pid = tlsIdentity.pid;
8313         }
8314
8315         return checkComponentPermission(permission, pid, uid, -1, true);
8316     }
8317
8318     /**
8319      * Binder IPC calls go through the public entry point.
8320      * This can be called with or without the global lock held.
8321      */
8322     int checkCallingPermission(String permission) {
8323         return checkPermission(permission,
8324                 Binder.getCallingPid(),
8325                 UserHandle.getAppId(Binder.getCallingUid()));
8326     }
8327
8328     /**
8329      * This can be called with or without the global lock held.
8330      */
8331     void enforceCallingPermission(String permission, String func) {
8332         if (checkCallingPermission(permission)
8333                 == PackageManager.PERMISSION_GRANTED) {
8334             return;
8335         }
8336
8337         String msg = "Permission Denial: " + func + " from pid="
8338                 + Binder.getCallingPid()
8339                 + ", uid=" + Binder.getCallingUid()
8340                 + " requires " + permission;
8341         Slog.w(TAG, msg);
8342         throw new SecurityException(msg);
8343     }
8344
8345     /**
8346      * Determine if UID is holding permissions required to access {@link Uri} in
8347      * the given {@link ProviderInfo}. Final permission checking is always done
8348      * in {@link ContentProvider}.
8349      */
8350     private final boolean checkHoldingPermissionsLocked(
8351             IPackageManager pm, ProviderInfo pi, GrantUri grantUri, int uid, final int modeFlags) {
8352         if (DEBUG_URI_PERMISSION) Slog.v(TAG_URI_PERMISSION,
8353                 "checkHoldingPermissionsLocked: uri=" + grantUri + " uid=" + uid);
8354         if (UserHandle.getUserId(uid) != grantUri.sourceUserId) {
8355             if (ActivityManager.checkComponentPermission(INTERACT_ACROSS_USERS, uid, -1, true)
8356                     != PERMISSION_GRANTED) {
8357                 return false;
8358             }
8359         }
8360         return checkHoldingPermissionsInternalLocked(pm, pi, grantUri, uid, modeFlags, true);
8361     }
8362
8363     private final boolean checkHoldingPermissionsInternalLocked(IPackageManager pm, ProviderInfo pi,
8364             GrantUri grantUri, int uid, final int modeFlags, boolean considerUidPermissions) {
8365         if (pi.applicationInfo.uid == uid) {
8366             return true;
8367         } else if (!pi.exported) {
8368             return false;
8369         }
8370
8371         boolean readMet = (modeFlags & Intent.FLAG_GRANT_READ_URI_PERMISSION) == 0;
8372         boolean writeMet = (modeFlags & Intent.FLAG_GRANT_WRITE_URI_PERMISSION) == 0;
8373         try {
8374             // check if target holds top-level <provider> permissions
8375             if (!readMet && pi.readPermission != null && considerUidPermissions
8376                     && (pm.checkUidPermission(pi.readPermission, uid) == PERMISSION_GRANTED)) {
8377                 readMet = true;
8378             }
8379             if (!writeMet && pi.writePermission != null && considerUidPermissions
8380                     && (pm.checkUidPermission(pi.writePermission, uid) == PERMISSION_GRANTED)) {
8381                 writeMet = true;
8382             }
8383
8384             // track if unprotected read/write is allowed; any denied
8385             // <path-permission> below removes this ability
8386             boolean allowDefaultRead = pi.readPermission == null;
8387             boolean allowDefaultWrite = pi.writePermission == null;
8388
8389             // check if target holds any <path-permission> that match uri
8390             final PathPermission[] pps = pi.pathPermissions;
8391             if (pps != null) {
8392                 final String path = grantUri.uri.getPath();
8393                 int i = pps.length;
8394                 while (i > 0 && (!readMet || !writeMet)) {
8395                     i--;
8396                     PathPermission pp = pps[i];
8397                     if (pp.match(path)) {
8398                         if (!readMet) {
8399                             final String pprperm = pp.getReadPermission();
8400                             if (DEBUG_URI_PERMISSION) Slog.v(TAG_URI_PERMISSION,
8401                                     "Checking read perm for " + pprperm + " for " + pp.getPath()
8402                                     + ": match=" + pp.match(path)
8403                                     + " check=" + pm.checkUidPermission(pprperm, uid));
8404                             if (pprperm != null) {
8405                                 if (considerUidPermissions && pm.checkUidPermission(pprperm, uid)
8406                                         == PERMISSION_GRANTED) {
8407                                     readMet = true;
8408                                 } else {
8409                                     allowDefaultRead = false;
8410                                 }
8411                             }
8412                         }
8413                         if (!writeMet) {
8414                             final String ppwperm = pp.getWritePermission();
8415                             if (DEBUG_URI_PERMISSION) Slog.v(TAG_URI_PERMISSION,
8416                                     "Checking write perm " + ppwperm + " for " + pp.getPath()
8417                                     + ": match=" + pp.match(path)
8418                                     + " check=" + pm.checkUidPermission(ppwperm, uid));
8419                             if (ppwperm != null) {
8420                                 if (considerUidPermissions && pm.checkUidPermission(ppwperm, uid)
8421                                         == PERMISSION_GRANTED) {
8422                                     writeMet = true;
8423                                 } else {
8424                                     allowDefaultWrite = false;
8425                                 }
8426                             }
8427                         }
8428                     }
8429                 }
8430             }
8431
8432             // grant unprotected <provider> read/write, if not blocked by
8433             // <path-permission> above
8434             if (allowDefaultRead) readMet = true;
8435             if (allowDefaultWrite) writeMet = true;
8436
8437         } catch (RemoteException e) {
8438             return false;
8439         }
8440
8441         return readMet && writeMet;
8442     }
8443
8444     public boolean isAppStartModeDisabled(int uid, String packageName) {
8445         synchronized (this) {
8446             return getAppStartModeLocked(uid, packageName, 0, -1, false, true)
8447                     == ActivityManager.APP_START_MODE_DISABLED;
8448         }
8449     }
8450
8451     // Unified app-op and target sdk check
8452     int appRestrictedInBackgroundLocked(int uid, String packageName, int packageTargetSdk) {
8453         // Apps that target O+ are always subject to background check
8454         if (packageTargetSdk >= Build.VERSION_CODES.O) {
8455             if (DEBUG_BACKGROUND_CHECK) {
8456                 Slog.i(TAG, "App " + uid + "/" + packageName + " targets O+, restricted");
8457             }
8458             return ActivityManager.APP_START_MODE_DELAYED_RIGID;
8459         }
8460         // ...and legacy apps get an AppOp check
8461         int appop = mAppOpsService.noteOperation(AppOpsManager.OP_RUN_IN_BACKGROUND,
8462                 uid, packageName);
8463         if (DEBUG_BACKGROUND_CHECK) {
8464             Slog.i(TAG, "Legacy app " + uid + "/" + packageName + " bg appop " + appop);
8465         }
8466         switch (appop) {
8467             case AppOpsManager.MODE_ALLOWED:
8468                 return ActivityManager.APP_START_MODE_NORMAL;
8469             case AppOpsManager.MODE_IGNORED:
8470                 return ActivityManager.APP_START_MODE_DELAYED;
8471             default:
8472                 return ActivityManager.APP_START_MODE_DELAYED_RIGID;
8473         }
8474     }
8475
8476     // Service launch is available to apps with run-in-background exemptions but
8477     // some other background operations are not.  If we're doing a check
8478     // of service-launch policy, allow those callers to proceed unrestricted.
8479     int appServicesRestrictedInBackgroundLocked(int uid, String packageName, int packageTargetSdk) {
8480         // Persistent app?
8481         if (mPackageManagerInt.isPackagePersistent(packageName)) {
8482             if (DEBUG_BACKGROUND_CHECK) {
8483                 Slog.i(TAG, "App " + uid + "/" + packageName
8484                         + " is persistent; not restricted in background");
8485             }
8486             return ActivityManager.APP_START_MODE_NORMAL;
8487         }
8488
8489         // Non-persistent but background whitelisted?
8490         if (uidOnBackgroundWhitelist(uid)) {
8491             if (DEBUG_BACKGROUND_CHECK) {
8492                 Slog.i(TAG, "App " + uid + "/" + packageName
8493                         + " on background whitelist; not restricted in background");
8494             }
8495             return ActivityManager.APP_START_MODE_NORMAL;
8496         }
8497
8498         // Is this app on the battery whitelist?
8499         if (isOnDeviceIdleWhitelistLocked(uid)) {
8500             if (DEBUG_BACKGROUND_CHECK) {
8501                 Slog.i(TAG, "App " + uid + "/" + packageName
8502                         + " on idle whitelist; not restricted in background");
8503             }
8504             return ActivityManager.APP_START_MODE_NORMAL;
8505         }
8506
8507         // None of the service-policy criteria apply, so we apply the common criteria
8508         return appRestrictedInBackgroundLocked(uid, packageName, packageTargetSdk);
8509     }
8510
8511     int getAppStartModeLocked(int uid, String packageName, int packageTargetSdk,
8512             int callingPid, boolean alwaysRestrict, boolean disabledOnly) {
8513         UidRecord uidRec = mActiveUids.get(uid);
8514         if (DEBUG_BACKGROUND_CHECK) Slog.d(TAG, "checkAllowBackground: uid=" + uid + " pkg="
8515                 + packageName + " rec=" + uidRec + " always=" + alwaysRestrict + " idle="
8516                 + (uidRec != null ? uidRec.idle : false));
8517         if (uidRec == null || alwaysRestrict || uidRec.idle) {
8518             boolean ephemeral;
8519             if (uidRec == null) {
8520                 ephemeral = getPackageManagerInternalLocked().isPackageEphemeral(
8521                         UserHandle.getUserId(uid), packageName);
8522             } else {
8523                 ephemeral = uidRec.ephemeral;
8524             }
8525
8526             if (ephemeral) {
8527                 // We are hard-core about ephemeral apps not running in the background.
8528                 return ActivityManager.APP_START_MODE_DISABLED;
8529             } else {
8530                 if (disabledOnly) {
8531                     // The caller is only interested in whether app starts are completely
8532                     // disabled for the given package (that is, it is an instant app).  So
8533                     // we don't need to go further, which is all just seeing if we should
8534                     // apply a "delayed" mode for a regular app.
8535                     return ActivityManager.APP_START_MODE_NORMAL;
8536                 }
8537                 final int startMode = (alwaysRestrict)
8538                         ? appRestrictedInBackgroundLocked(uid, packageName, packageTargetSdk)
8539                         : appServicesRestrictedInBackgroundLocked(uid, packageName,
8540                                 packageTargetSdk);
8541                 if (DEBUG_BACKGROUND_CHECK) Slog.d(TAG, "checkAllowBackground: uid=" + uid
8542                         + " pkg=" + packageName + " startMode=" + startMode
8543                         + " onwhitelist=" + isOnDeviceIdleWhitelistLocked(uid));
8544                 if (startMode == ActivityManager.APP_START_MODE_DELAYED) {
8545                     // This is an old app that has been forced into a "compatible as possible"
8546                     // mode of background check.  To increase compatibility, we will allow other
8547                     // foreground apps to cause its services to start.
8548                     if (callingPid >= 0) {
8549                         ProcessRecord proc;
8550                         synchronized (mPidsSelfLocked) {
8551                             proc = mPidsSelfLocked.get(callingPid);
8552                         }
8553                         if (proc != null &&
8554                                 !ActivityManager.isProcStateBackground(proc.curProcState)) {
8555                             // Whoever is instigating this is in the foreground, so we will allow it
8556                             // to go through.
8557                             return ActivityManager.APP_START_MODE_NORMAL;
8558                         }
8559                     }
8560                 }
8561                 return startMode;
8562             }
8563         }
8564         return ActivityManager.APP_START_MODE_NORMAL;
8565     }
8566
8567     boolean isOnDeviceIdleWhitelistLocked(int uid) {
8568         final int appId = UserHandle.getAppId(uid);
8569         return Arrays.binarySearch(mDeviceIdleWhitelist, appId) >= 0
8570                 || Arrays.binarySearch(mDeviceIdleTempWhitelist, appId) >= 0
8571                 || mPendingTempWhitelist.indexOfKey(uid) >= 0;
8572     }
8573
8574     private ProviderInfo getProviderInfoLocked(String authority, int userHandle, int pmFlags) {
8575         ProviderInfo pi = null;
8576         ContentProviderRecord cpr = mProviderMap.getProviderByName(authority, userHandle);
8577         if (cpr != null) {
8578             pi = cpr.info;
8579         } else {
8580             try {
8581                 pi = AppGlobals.getPackageManager().resolveContentProvider(
8582                         authority, PackageManager.GET_URI_PERMISSION_PATTERNS | pmFlags,
8583                         userHandle);
8584             } catch (RemoteException ex) {
8585             }
8586         }
8587         return pi;
8588     }
8589
8590     void grantEphemeralAccessLocked(int userId, Intent intent,
8591             int targetAppId, int ephemeralAppId) {
8592         getPackageManagerInternalLocked().
8593                 grantEphemeralAccess(userId, intent, targetAppId, ephemeralAppId);
8594     }
8595
8596     private UriPermission findUriPermissionLocked(int targetUid, GrantUri grantUri) {
8597         final ArrayMap<GrantUri, UriPermission> targetUris = mGrantedUriPermissions.get(targetUid);
8598         if (targetUris != null) {
8599             return targetUris.get(grantUri);
8600         }
8601         return null;
8602     }
8603
8604     private UriPermission findOrCreateUriPermissionLocked(String sourcePkg,
8605             String targetPkg, int targetUid, GrantUri grantUri) {
8606         ArrayMap<GrantUri, UriPermission> targetUris = mGrantedUriPermissions.get(targetUid);
8607         if (targetUris == null) {
8608             targetUris = Maps.newArrayMap();
8609             mGrantedUriPermissions.put(targetUid, targetUris);
8610         }
8611
8612         UriPermission perm = targetUris.get(grantUri);
8613         if (perm == null) {
8614             perm = new UriPermission(sourcePkg, targetPkg, targetUid, grantUri);
8615             targetUris.put(grantUri, perm);
8616         }
8617
8618         return perm;
8619     }
8620
8621     private final boolean checkUriPermissionLocked(GrantUri grantUri, int uid,
8622             final int modeFlags) {
8623         final boolean persistable = (modeFlags & Intent.FLAG_GRANT_PERSISTABLE_URI_PERMISSION) != 0;
8624         final int minStrength = persistable ? UriPermission.STRENGTH_PERSISTABLE
8625                 : UriPermission.STRENGTH_OWNED;
8626
8627         // Root gets to do everything.
8628         if (uid == 0) {
8629             return true;
8630         }
8631
8632         final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.get(uid);
8633         if (perms == null) return false;
8634
8635         // First look for exact match
8636         final UriPermission exactPerm = perms.get(grantUri);
8637         if (exactPerm != null && exactPerm.getStrength(modeFlags) >= minStrength) {
8638             return true;
8639         }
8640
8641         // No exact match, look for prefixes
8642         final int N = perms.size();
8643         for (int i = 0; i < N; i++) {
8644             final UriPermission perm = perms.valueAt(i);
8645             if (perm.uri.prefix && grantUri.uri.isPathPrefixMatch(perm.uri.uri)
8646                     && perm.getStrength(modeFlags) >= minStrength) {
8647                 return true;
8648             }
8649         }
8650
8651         return false;
8652     }
8653
8654     /**
8655      * @param uri This uri must NOT contain an embedded userId.
8656      * @param userId The userId in which the uri is to be resolved.
8657      */
8658     @Override
8659     public int checkUriPermission(Uri uri, int pid, int uid,
8660             final int modeFlags, int userId, IBinder callerToken) {
8661         enforceNotIsolatedCaller("checkUriPermission");
8662
8663         // Another redirected-binder-call permissions check as in
8664         // {@link checkPermissionWithToken}.
8665         Identity tlsIdentity = sCallerIdentity.get();
8666         if (tlsIdentity != null && tlsIdentity.token == callerToken) {
8667             uid = tlsIdentity.uid;
8668             pid = tlsIdentity.pid;
8669         }
8670
8671         // Our own process gets to do everything.
8672         if (pid == MY_PID) {
8673             return PackageManager.PERMISSION_GRANTED;
8674         }
8675         synchronized (this) {
8676             return checkUriPermissionLocked(new GrantUri(userId, uri, false), uid, modeFlags)
8677                     ? PackageManager.PERMISSION_GRANTED
8678                     : PackageManager.PERMISSION_DENIED;
8679         }
8680     }
8681
8682     /**
8683      * Check if the targetPkg can be granted permission to access uri by
8684      * the callingUid using the given modeFlags.  Throws a security exception
8685      * if callingUid is not allowed to do this.  Returns the uid of the target
8686      * if the URI permission grant should be performed; returns -1 if it is not
8687      * needed (for example targetPkg already has permission to access the URI).
8688      * If you already know the uid of the target, you can supply it in
8689      * lastTargetUid else set that to -1.
8690      */
8691     int checkGrantUriPermissionLocked(int callingUid, String targetPkg, GrantUri grantUri,
8692             final int modeFlags, int lastTargetUid) {
8693         if (!Intent.isAccessUriMode(modeFlags)) {
8694             return -1;
8695         }
8696
8697         if (targetPkg != null) {
8698             if (DEBUG_URI_PERMISSION) Slog.v(TAG_URI_PERMISSION,
8699                     "Checking grant " + targetPkg + " permission to " + grantUri);
8700         }
8701
8702         final IPackageManager pm = AppGlobals.getPackageManager();
8703
8704         // If this is not a content: uri, we can't do anything with it.
8705         if (!ContentResolver.SCHEME_CONTENT.equals(grantUri.uri.getScheme())) {
8706             if (DEBUG_URI_PERMISSION) Slog.v(TAG_URI_PERMISSION,
8707                     "Can't grant URI permission for non-content URI: " + grantUri);
8708             return -1;
8709         }
8710
8711         // Bail early if system is trying to hand out permissions directly; it
8712         // must always grant permissions on behalf of someone explicit.
8713         final int callingAppId = UserHandle.getAppId(callingUid);
8714         if ((callingAppId == SYSTEM_UID) || (callingAppId == ROOT_UID)) {
8715             if ("com.android.settings.files".equals(grantUri.uri.getAuthority())) {
8716                 // Exempted authority for cropping user photos in Settings app
8717             } else {
8718                 Slog.w(TAG, "For security reasons, the system cannot issue a Uri permission"
8719                         + " grant to " + grantUri + "; use startActivityAsCaller() instead");
8720                 return -1;
8721             }
8722         }
8723
8724         final String authority = grantUri.uri.getAuthority();
8725         final ProviderInfo pi = getProviderInfoLocked(authority, grantUri.sourceUserId,
8726                 MATCH_DEBUG_TRIAGED_MISSING);
8727         if (pi == null) {
8728             Slog.w(TAG, "No content provider found for permission check: " +
8729                     grantUri.uri.toSafeString());
8730             return -1;
8731         }
8732
8733         int targetUid = lastTargetUid;
8734         if (targetUid < 0 && targetPkg != null) {
8735             try {
8736                 targetUid = pm.getPackageUid(targetPkg, MATCH_DEBUG_TRIAGED_MISSING,
8737                         UserHandle.getUserId(callingUid));
8738                 if (targetUid < 0) {
8739                     if (DEBUG_URI_PERMISSION) Slog.v(TAG_URI_PERMISSION,
8740                             "Can't grant URI permission no uid for: " + targetPkg);
8741                     return -1;
8742                 }
8743             } catch (RemoteException ex) {
8744                 return -1;
8745             }
8746         }
8747
8748         // Figure out the value returned when access is allowed
8749         final int allowedResult;
8750         if ((modeFlags & Intent.FLAG_GRANT_PERSISTABLE_URI_PERMISSION) != 0) {
8751             // If we're extending a persistable grant, then we need to return
8752             // "targetUid" so that we always create a grant data structure to
8753             // support take/release APIs
8754             allowedResult = targetUid;
8755         } else {
8756             // Otherwise, we can return "-1" to indicate that no grant data
8757             // structures need to be created
8758             allowedResult = -1;
8759         }
8760
8761         if (targetUid >= 0) {
8762             // First...  does the target actually need this permission?
8763             if (checkHoldingPermissionsLocked(pm, pi, grantUri, targetUid, modeFlags)) {
8764                 // No need to grant the target this permission.
8765                 if (DEBUG_URI_PERMISSION) Slog.v(TAG_URI_PERMISSION,
8766                         "Target " + targetPkg + " already has full permission to " + grantUri);
8767                 return allowedResult;
8768             }
8769         } else {
8770             // First...  there is no target package, so can anyone access it?
8771             boolean allowed = pi.exported;
8772             if ((modeFlags&Intent.FLAG_GRANT_READ_URI_PERMISSION) != 0) {
8773                 if (pi.readPermission != null) {
8774                     allowed = false;
8775                 }
8776             }
8777             if ((modeFlags&Intent.FLAG_GRANT_WRITE_URI_PERMISSION) != 0) {
8778                 if (pi.writePermission != null) {
8779                     allowed = false;
8780                 }
8781             }
8782             if (allowed) {
8783                 return allowedResult;
8784             }
8785         }
8786
8787         /* There is a special cross user grant if:
8788          * - The target is on another user.
8789          * - Apps on the current user can access the uri without any uid permissions.
8790          * In this case, we grant a uri permission, even if the ContentProvider does not normally
8791          * grant uri permissions.
8792          */
8793         boolean specialCrossUserGrant = UserHandle.getUserId(targetUid) != grantUri.sourceUserId
8794                 && checkHoldingPermissionsInternalLocked(pm, pi, grantUri, callingUid,
8795                 modeFlags, false /*without considering the uid permissions*/);
8796
8797         // Second...  is the provider allowing granting of URI permissions?
8798         if (!specialCrossUserGrant) {
8799             if (!pi.grantUriPermissions) {
8800                 throw new SecurityException("Provider " + pi.packageName
8801                         + "/" + pi.name
8802                         + " does not allow granting of Uri permissions (uri "
8803                         + grantUri + ")");
8804             }
8805             if (pi.uriPermissionPatterns != null) {
8806                 final int N = pi.uriPermissionPatterns.length;
8807                 boolean allowed = false;
8808                 for (int i=0; i<N; i++) {
8809                     if (pi.uriPermissionPatterns[i] != null
8810                             && pi.uriPermissionPatterns[i].match(grantUri.uri.getPath())) {
8811                         allowed = true;
8812                         break;
8813                     }
8814                 }
8815                 if (!allowed) {
8816                     throw new SecurityException("Provider " + pi.packageName
8817                             + "/" + pi.name
8818                             + " does not allow granting of permission to path of Uri "
8819                             + grantUri);
8820                 }
8821             }
8822         }
8823
8824         // Third...  does the caller itself have permission to access
8825         // this uri?
8826         if (!checkHoldingPermissionsLocked(pm, pi, grantUri, callingUid, modeFlags)) {
8827             // Require they hold a strong enough Uri permission
8828             if (!checkUriPermissionLocked(grantUri, callingUid, modeFlags)) {
8829                 if (android.Manifest.permission.MANAGE_DOCUMENTS.equals(pi.readPermission)) {
8830                     throw new SecurityException(
8831                             "UID " + callingUid + " does not have permission to " + grantUri
8832                                     + "; you could obtain access using ACTION_OPEN_DOCUMENT "
8833                                     + "or related APIs");
8834                 } else {
8835                     throw new SecurityException(
8836                             "UID " + callingUid + " does not have permission to " + grantUri);
8837                 }
8838             }
8839         }
8840         return targetUid;
8841     }
8842
8843     /**
8844      * @param uri This uri must NOT contain an embedded userId.
8845      * @param userId The userId in which the uri is to be resolved.
8846      */
8847     @Override
8848     public int checkGrantUriPermission(int callingUid, String targetPkg, Uri uri,
8849             final int modeFlags, int userId) {
8850         enforceNotIsolatedCaller("checkGrantUriPermission");
8851         synchronized(this) {
8852             return checkGrantUriPermissionLocked(callingUid, targetPkg,
8853                     new GrantUri(userId, uri, false), modeFlags, -1);
8854         }
8855     }
8856
8857     void grantUriPermissionUncheckedLocked(int targetUid, String targetPkg, GrantUri grantUri,
8858             final int modeFlags, UriPermissionOwner owner) {
8859         if (!Intent.isAccessUriMode(modeFlags)) {
8860             return;
8861         }
8862
8863         // So here we are: the caller has the assumed permission
8864         // to the uri, and the target doesn't.  Let's now give this to
8865         // the target.
8866
8867         if (DEBUG_URI_PERMISSION) Slog.v(TAG_URI_PERMISSION,
8868                 "Granting " + targetPkg + "/" + targetUid + " permission to " + grantUri);
8869
8870         final String authority = grantUri.uri.getAuthority();
8871         final ProviderInfo pi = getProviderInfoLocked(authority, grantUri.sourceUserId,
8872                 MATCH_DEBUG_TRIAGED_MISSING);
8873         if (pi == null) {
8874             Slog.w(TAG, "No content provider found for grant: " + grantUri.toSafeString());
8875             return;
8876         }
8877
8878         if ((modeFlags & Intent.FLAG_GRANT_PREFIX_URI_PERMISSION) != 0) {
8879             grantUri.prefix = true;
8880         }
8881         final UriPermission perm = findOrCreateUriPermissionLocked(
8882                 pi.packageName, targetPkg, targetUid, grantUri);
8883         perm.grantModes(modeFlags, owner);
8884     }
8885
8886     void grantUriPermissionLocked(int callingUid, String targetPkg, GrantUri grantUri,
8887             final int modeFlags, UriPermissionOwner owner, int targetUserId) {
8888         if (targetPkg == null) {
8889             throw new NullPointerException("targetPkg");
8890         }
8891         int targetUid;
8892         final IPackageManager pm = AppGlobals.getPackageManager();
8893         try {
8894             targetUid = pm.getPackageUid(targetPkg, MATCH_DEBUG_TRIAGED_MISSING, targetUserId);
8895         } catch (RemoteException ex) {
8896             return;
8897         }
8898
8899         targetUid = checkGrantUriPermissionLocked(callingUid, targetPkg, grantUri, modeFlags,
8900                 targetUid);
8901         if (targetUid < 0) {
8902             return;
8903         }
8904
8905         grantUriPermissionUncheckedLocked(targetUid, targetPkg, grantUri, modeFlags,
8906                 owner);
8907     }
8908
8909     static class NeededUriGrants extends ArrayList<GrantUri> {
8910         final String targetPkg;
8911         final int targetUid;
8912         final int flags;
8913
8914         NeededUriGrants(String targetPkg, int targetUid, int flags) {
8915             this.targetPkg = targetPkg;
8916             this.targetUid = targetUid;
8917             this.flags = flags;
8918         }
8919     }
8920
8921     /**
8922      * Like checkGrantUriPermissionLocked, but takes an Intent.
8923      */
8924     NeededUriGrants checkGrantUriPermissionFromIntentLocked(int callingUid,
8925             String targetPkg, Intent intent, int mode, NeededUriGrants needed, int targetUserId) {
8926         if (DEBUG_URI_PERMISSION) Slog.v(TAG_URI_PERMISSION,
8927                 "Checking URI perm to data=" + (intent != null ? intent.getData() : null)
8928                 + " clip=" + (intent != null ? intent.getClipData() : null)
8929                 + " from " + intent + "; flags=0x"
8930                 + Integer.toHexString(intent != null ? intent.getFlags() : 0));
8931
8932         if (targetPkg == null) {
8933             throw new NullPointerException("targetPkg");
8934         }
8935
8936         if (intent == null) {
8937             return null;
8938         }
8939         Uri data = intent.getData();
8940         ClipData clip = intent.getClipData();
8941         if (data == null && clip == null) {
8942             return null;
8943         }
8944         // Default userId for uris in the intent (if they don't specify it themselves)
8945         int contentUserHint = intent.getContentUserHint();
8946         if (contentUserHint == UserHandle.USER_CURRENT) {
8947             contentUserHint = UserHandle.getUserId(callingUid);
8948         }
8949         final IPackageManager pm = AppGlobals.getPackageManager();
8950         int targetUid;
8951         if (needed != null) {
8952             targetUid = needed.targetUid;
8953         } else {
8954             try {
8955                 targetUid = pm.getPackageUid(targetPkg, MATCH_DEBUG_TRIAGED_MISSING,
8956                         targetUserId);
8957             } catch (RemoteException ex) {
8958                 return null;
8959             }
8960             if (targetUid < 0) {
8961                 if (DEBUG_URI_PERMISSION) Slog.v(TAG_URI_PERMISSION,
8962                         "Can't grant URI permission no uid for: " + targetPkg
8963                         + " on user " + targetUserId);
8964                 return null;
8965             }
8966         }
8967         if (data != null) {
8968             GrantUri grantUri = GrantUri.resolve(contentUserHint, data);
8969             targetUid = checkGrantUriPermissionLocked(callingUid, targetPkg, grantUri, mode,
8970                     targetUid);
8971             if (targetUid > 0) {
8972                 if (needed == null) {
8973                     needed = new NeededUriGrants(targetPkg, targetUid, mode);
8974                 }
8975                 needed.add(grantUri);
8976             }
8977         }
8978         if (clip != null) {
8979             for (int i=0; i<clip.getItemCount(); i++) {
8980                 Uri uri = clip.getItemAt(i).getUri();
8981                 if (uri != null) {
8982                     GrantUri grantUri = GrantUri.resolve(contentUserHint, uri);
8983                     targetUid = checkGrantUriPermissionLocked(callingUid, targetPkg, grantUri, mode,
8984                             targetUid);
8985                     if (targetUid > 0) {
8986                         if (needed == null) {
8987                             needed = new NeededUriGrants(targetPkg, targetUid, mode);
8988                         }
8989                         needed.add(grantUri);
8990                     }
8991                 } else {
8992                     Intent clipIntent = clip.getItemAt(i).getIntent();
8993                     if (clipIntent != null) {
8994                         NeededUriGrants newNeeded = checkGrantUriPermissionFromIntentLocked(
8995                                 callingUid, targetPkg, clipIntent, mode, needed, targetUserId);
8996                         if (newNeeded != null) {
8997                             needed = newNeeded;
8998                         }
8999                     }
9000                 }
9001             }
9002         }
9003
9004         return needed;
9005     }
9006
9007     /**
9008      * Like grantUriPermissionUncheckedLocked, but takes an Intent.
9009      */
9010     void grantUriPermissionUncheckedFromIntentLocked(NeededUriGrants needed,
9011             UriPermissionOwner owner) {
9012         if (needed != null) {
9013             for (int i=0; i<needed.size(); i++) {
9014                 GrantUri grantUri = needed.get(i);
9015                 grantUriPermissionUncheckedLocked(needed.targetUid, needed.targetPkg,
9016                         grantUri, needed.flags, owner);
9017             }
9018         }
9019     }
9020
9021     void grantUriPermissionFromIntentLocked(int callingUid,
9022             String targetPkg, Intent intent, UriPermissionOwner owner, int targetUserId) {
9023         NeededUriGrants needed = checkGrantUriPermissionFromIntentLocked(callingUid, targetPkg,
9024                 intent, intent != null ? intent.getFlags() : 0, null, targetUserId);
9025         if (needed == null) {
9026             return;
9027         }
9028
9029         grantUriPermissionUncheckedFromIntentLocked(needed, owner);
9030     }
9031
9032     /**
9033      * @param uri This uri must NOT contain an embedded userId.
9034      * @param userId The userId in which the uri is to be resolved.
9035      */
9036     @Override
9037     public void grantUriPermission(IApplicationThread caller, String targetPkg, Uri uri,
9038             final int modeFlags, int userId) {
9039         enforceNotIsolatedCaller("grantUriPermission");
9040         GrantUri grantUri = new GrantUri(userId, uri, false);
9041         synchronized(this) {
9042             final ProcessRecord r = getRecordForAppLocked(caller);
9043             if (r == null) {
9044                 throw new SecurityException("Unable to find app for caller "
9045                         + caller
9046                         + " when granting permission to uri " + grantUri);
9047             }
9048             if (targetPkg == null) {
9049                 throw new IllegalArgumentException("null target");
9050             }
9051             if (grantUri == null) {
9052                 throw new IllegalArgumentException("null uri");
9053             }
9054
9055             Preconditions.checkFlagsArgument(modeFlags, Intent.FLAG_GRANT_READ_URI_PERMISSION
9056                     | Intent.FLAG_GRANT_WRITE_URI_PERMISSION
9057                     | Intent.FLAG_GRANT_PERSISTABLE_URI_PERMISSION
9058                     | Intent.FLAG_GRANT_PREFIX_URI_PERMISSION);
9059
9060             grantUriPermissionLocked(r.uid, targetPkg, grantUri, modeFlags, null,
9061                     UserHandle.getUserId(r.uid));
9062         }
9063     }
9064
9065     void removeUriPermissionIfNeededLocked(UriPermission perm) {
9066         if (perm.modeFlags == 0) {
9067             final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.get(
9068                     perm.targetUid);
9069             if (perms != null) {
9070                 if (DEBUG_URI_PERMISSION) Slog.v(TAG_URI_PERMISSION,
9071                         "Removing " + perm.targetUid + " permission to " + perm.uri);
9072
9073                 perms.remove(perm.uri);
9074                 if (perms.isEmpty()) {
9075                     mGrantedUriPermissions.remove(perm.targetUid);
9076                 }
9077             }
9078         }
9079     }
9080
9081     private void revokeUriPermissionLocked(String targetPackage, int callingUid, GrantUri grantUri,
9082             final int modeFlags) {
9083         if (DEBUG_URI_PERMISSION) Slog.v(TAG_URI_PERMISSION,
9084                 "Revoking all granted permissions to " + grantUri);
9085
9086         final IPackageManager pm = AppGlobals.getPackageManager();
9087         final String authority = grantUri.uri.getAuthority();
9088         final ProviderInfo pi = getProviderInfoLocked(authority, grantUri.sourceUserId,
9089                 MATCH_DIRECT_BOOT_AWARE | MATCH_DIRECT_BOOT_UNAWARE);
9090         if (pi == null) {
9091             Slog.w(TAG, "No content provider found for permission revoke: "
9092                     + grantUri.toSafeString());
9093             return;
9094         }
9095
9096         // Does the caller have this permission on the URI?
9097         if (!checkHoldingPermissionsLocked(pm, pi, grantUri, callingUid, modeFlags)) {
9098             // If they don't have direct access to the URI, then revoke any
9099             // ownerless URI permissions that have been granted to them.
9100             final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.get(callingUid);
9101             if (perms != null) {
9102                 boolean persistChanged = false;
9103                 for (int i = perms.size()-1; i >= 0; i--) {
9104                     final UriPermission perm = perms.valueAt(i);
9105                     if (targetPackage != null && !targetPackage.equals(perm.targetPkg)) {
9106                         continue;
9107                     }
9108                     if (perm.uri.sourceUserId == grantUri.sourceUserId
9109                             && perm.uri.uri.isPathPrefixMatch(grantUri.uri)) {
9110                         if (DEBUG_URI_PERMISSION) Slog.v(TAG_URI_PERMISSION,
9111                                 "Revoking non-owned " + perm.targetUid
9112                                 + " permission to " + perm.uri);
9113                         persistChanged |= perm.revokeModes(
9114                                 modeFlags | Intent.FLAG_GRANT_PERSISTABLE_URI_PERMISSION, false);
9115                         if (perm.modeFlags == 0) {
9116                             perms.removeAt(i);
9117                         }
9118                     }
9119                 }
9120                 if (perms.isEmpty()) {
9121                     mGrantedUriPermissions.remove(callingUid);
9122                 }
9123                 if (persistChanged) {
9124                     schedulePersistUriGrants();
9125                 }
9126             }
9127             return;
9128         }
9129
9130         boolean persistChanged = false;
9131
9132         // Go through all of the permissions and remove any that match.
9133         for (int i = mGrantedUriPermissions.size()-1; i >= 0; i--) {
9134             final int targetUid = mGrantedUriPermissions.keyAt(i);
9135             final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.valueAt(i);
9136
9137             for (int j = perms.size()-1; j >= 0; j--) {
9138                 final UriPermission perm = perms.valueAt(j);
9139                 if (targetPackage != null && !targetPackage.equals(perm.targetPkg)) {
9140                     continue;
9141                 }
9142                 if (perm.uri.sourceUserId == grantUri.sourceUserId
9143                         && perm.uri.uri.isPathPrefixMatch(grantUri.uri)) {
9144                     if (DEBUG_URI_PERMISSION) Slog.v(TAG_URI_PERMISSION,
9145                                 "Revoking " + perm.targetUid + " permission to " + perm.uri);
9146                     persistChanged |= perm.revokeModes(
9147                             modeFlags | Intent.FLAG_GRANT_PERSISTABLE_URI_PERMISSION,
9148                             targetPackage == null);
9149                     if (perm.modeFlags == 0) {
9150                         perms.removeAt(j);
9151                     }
9152                 }
9153             }
9154
9155             if (perms.isEmpty()) {
9156                 mGrantedUriPermissions.removeAt(i);
9157             }
9158         }
9159
9160         if (persistChanged) {
9161             schedulePersistUriGrants();
9162         }
9163     }
9164
9165     /**
9166      * @param uri This uri must NOT contain an embedded userId.
9167      * @param userId The userId in which the uri is to be resolved.
9168      */
9169     @Override
9170     public void revokeUriPermission(IApplicationThread caller, String targetPackage, Uri uri,
9171             final int modeFlags, int userId) {
9172         enforceNotIsolatedCaller("revokeUriPermission");
9173         synchronized(this) {
9174             final ProcessRecord r = getRecordForAppLocked(caller);
9175             if (r == null) {
9176                 throw new SecurityException("Unable to find app for caller "
9177                         + caller
9178                         + " when revoking permission to uri " + uri);
9179             }
9180             if (uri == null) {
9181                 Slog.w(TAG, "revokeUriPermission: null uri");
9182                 return;
9183             }
9184
9185             if (!Intent.isAccessUriMode(modeFlags)) {
9186                 return;
9187             }
9188
9189             final String authority = uri.getAuthority();
9190             final ProviderInfo pi = getProviderInfoLocked(authority, userId,
9191                     MATCH_DIRECT_BOOT_AWARE | MATCH_DIRECT_BOOT_UNAWARE);
9192             if (pi == null) {
9193                 Slog.w(TAG, "No content provider found for permission revoke: "
9194                         + uri.toSafeString());
9195                 return;
9196             }
9197
9198             revokeUriPermissionLocked(targetPackage, r.uid, new GrantUri(userId, uri, false),
9199                     modeFlags);
9200         }
9201     }
9202
9203     /**
9204      * Remove any {@link UriPermission} granted <em>from</em> or <em>to</em> the
9205      * given package.
9206      *
9207      * @param packageName Package name to match, or {@code null} to apply to all
9208      *            packages.
9209      * @param userHandle User to match, or {@link UserHandle#USER_ALL} to apply
9210      *            to all users.
9211      * @param persistable If persistable grants should be removed.
9212      */
9213     private void removeUriPermissionsForPackageLocked(
9214             String packageName, int userHandle, boolean persistable) {
9215         if (userHandle == UserHandle.USER_ALL && packageName == null) {
9216             throw new IllegalArgumentException("Must narrow by either package or user");
9217         }
9218
9219         boolean persistChanged = false;
9220
9221         int N = mGrantedUriPermissions.size();
9222         for (int i = 0; i < N; i++) {
9223             final int targetUid = mGrantedUriPermissions.keyAt(i);
9224             final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.valueAt(i);
9225
9226             // Only inspect grants matching user
9227             if (userHandle == UserHandle.USER_ALL
9228                     || userHandle == UserHandle.getUserId(targetUid)) {
9229                 for (Iterator<UriPermission> it = perms.values().iterator(); it.hasNext();) {
9230                     final UriPermission perm = it.next();
9231
9232                     // Only inspect grants matching package
9233                     if (packageName == null || perm.sourcePkg.equals(packageName)
9234                             || perm.targetPkg.equals(packageName)) {
9235                         // Hacky solution as part of fixing a security bug; ignore
9236                         // grants associated with DownloadManager so we don't have
9237                         // to immediately launch it to regrant the permissions
9238                         if (Downloads.Impl.AUTHORITY.equals(perm.uri.uri.getAuthority())
9239                                 && !persistable) continue;
9240
9241                         persistChanged |= perm.revokeModes(persistable
9242                                 ? ~0 : ~Intent.FLAG_GRANT_PERSISTABLE_URI_PERMISSION, true);
9243
9244                         // Only remove when no modes remain; any persisted grants
9245                         // will keep this alive.
9246                         if (perm.modeFlags == 0) {
9247                             it.remove();
9248                         }
9249                     }
9250                 }
9251
9252                 if (perms.isEmpty()) {
9253                     mGrantedUriPermissions.remove(targetUid);
9254                     N--;
9255                     i--;
9256                 }
9257             }
9258         }
9259
9260         if (persistChanged) {
9261             schedulePersistUriGrants();
9262         }
9263     }
9264
9265     @Override
9266     public IBinder newUriPermissionOwner(String name) {
9267         enforceNotIsolatedCaller("newUriPermissionOwner");
9268         synchronized(this) {
9269             UriPermissionOwner owner = new UriPermissionOwner(this, name);
9270             return owner.getExternalTokenLocked();
9271         }
9272     }
9273
9274     @Override
9275     public IBinder getUriPermissionOwnerForActivity(IBinder activityToken) {
9276         enforceNotIsolatedCaller("getUriPermissionOwnerForActivity");
9277         synchronized(this) {
9278             ActivityRecord r = ActivityRecord.isInStackLocked(activityToken);
9279             if (r == null) {
9280                 throw new IllegalArgumentException("Activity does not exist; token="
9281                         + activityToken);
9282             }
9283             return r.getUriPermissionsLocked().getExternalTokenLocked();
9284         }
9285     }
9286     /**
9287      * @param uri This uri must NOT contain an embedded userId.
9288      * @param sourceUserId The userId in which the uri is to be resolved.
9289      * @param targetUserId The userId of the app that receives the grant.
9290      */
9291     @Override
9292     public void grantUriPermissionFromOwner(IBinder token, int fromUid, String targetPkg, Uri uri,
9293             final int modeFlags, int sourceUserId, int targetUserId) {
9294         targetUserId = mUserController.handleIncomingUser(Binder.getCallingPid(),
9295                 Binder.getCallingUid(), targetUserId, false, ALLOW_FULL_ONLY,
9296                 "grantUriPermissionFromOwner", null);
9297         synchronized(this) {
9298             UriPermissionOwner owner = UriPermissionOwner.fromExternalToken(token);
9299             if (owner == null) {
9300                 throw new IllegalArgumentException("Unknown owner: " + token);
9301             }
9302             if (fromUid != Binder.getCallingUid()) {
9303                 if (Binder.getCallingUid() != myUid()) {
9304                     // Only system code can grant URI permissions on behalf
9305                     // of other users.
9306                     throw new SecurityException("nice try");
9307                 }
9308             }
9309             if (targetPkg == null) {
9310                 throw new IllegalArgumentException("null target");
9311             }
9312             if (uri == null) {
9313                 throw new IllegalArgumentException("null uri");
9314             }
9315
9316             grantUriPermissionLocked(fromUid, targetPkg, new GrantUri(sourceUserId, uri, false),
9317                     modeFlags, owner, targetUserId);
9318         }
9319     }
9320
9321     /**
9322      * @param uri This uri must NOT contain an embedded userId.
9323      * @param userId The userId in which the uri is to be resolved.
9324      */
9325     @Override
9326     public void revokeUriPermissionFromOwner(IBinder token, Uri uri, int mode, int userId) {
9327         synchronized(this) {
9328             UriPermissionOwner owner = UriPermissionOwner.fromExternalToken(token);
9329             if (owner == null) {
9330                 throw new IllegalArgumentException("Unknown owner: " + token);
9331             }
9332
9333             if (uri == null) {
9334                 owner.removeUriPermissionsLocked(mode);
9335             } else {
9336                 final boolean prefix = (mode & Intent.FLAG_GRANT_PREFIX_URI_PERMISSION) != 0;
9337                 owner.removeUriPermissionLocked(new GrantUri(userId, uri, prefix), mode);
9338             }
9339         }
9340     }
9341
9342     private void schedulePersistUriGrants() {
9343         if (!mHandler.hasMessages(PERSIST_URI_GRANTS_MSG)) {
9344             mHandler.sendMessageDelayed(mHandler.obtainMessage(PERSIST_URI_GRANTS_MSG),
9345                     10 * DateUtils.SECOND_IN_MILLIS);
9346         }
9347     }
9348
9349     private void writeGrantedUriPermissions() {
9350         if (DEBUG_URI_PERMISSION) Slog.v(TAG_URI_PERMISSION, "writeGrantedUriPermissions()");
9351
9352         // Snapshot permissions so we can persist without lock
9353         ArrayList<UriPermission.Snapshot> persist = Lists.newArrayList();
9354         synchronized (this) {
9355             final int size = mGrantedUriPermissions.size();
9356             for (int i = 0; i < size; i++) {
9357                 final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.valueAt(i);
9358                 for (UriPermission perm : perms.values()) {
9359                     if (perm.persistedModeFlags != 0) {
9360                         persist.add(perm.snapshot());
9361                     }
9362                 }
9363             }
9364         }
9365
9366         FileOutputStream fos = null;
9367         try {
9368             fos = mGrantFile.startWrite();
9369
9370             XmlSerializer out = new FastXmlSerializer();
9371             out.setOutput(fos, StandardCharsets.UTF_8.name());
9372             out.startDocument(null, true);
9373             out.startTag(null, TAG_URI_GRANTS);
9374             for (UriPermission.Snapshot perm : persist) {
9375                 out.startTag(null, TAG_URI_GRANT);
9376                 writeIntAttribute(out, ATTR_SOURCE_USER_ID, perm.uri.sourceUserId);
9377                 writeIntAttribute(out, ATTR_TARGET_USER_ID, perm.targetUserId);
9378                 out.attribute(null, ATTR_SOURCE_PKG, perm.sourcePkg);
9379                 out.attribute(null, ATTR_TARGET_PKG, perm.targetPkg);
9380                 out.attribute(null, ATTR_URI, String.valueOf(perm.uri.uri));
9381                 writeBooleanAttribute(out, ATTR_PREFIX, perm.uri.prefix);
9382                 writeIntAttribute(out, ATTR_MODE_FLAGS, perm.persistedModeFlags);
9383                 writeLongAttribute(out, ATTR_CREATED_TIME, perm.persistedCreateTime);
9384                 out.endTag(null, TAG_URI_GRANT);
9385             }
9386             out.endTag(null, TAG_URI_GRANTS);
9387             out.endDocument();
9388
9389             mGrantFile.finishWrite(fos);
9390         } catch (IOException e) {
9391             if (fos != null) {
9392                 mGrantFile.failWrite(fos);
9393             }
9394         }
9395     }
9396
9397     private void readGrantedUriPermissionsLocked() {
9398         if (DEBUG_URI_PERMISSION) Slog.v(TAG_URI_PERMISSION, "readGrantedUriPermissions()");
9399
9400         final long now = System.currentTimeMillis();
9401
9402         FileInputStream fis = null;
9403         try {
9404             fis = mGrantFile.openRead();
9405             final XmlPullParser in = Xml.newPullParser();
9406             in.setInput(fis, StandardCharsets.UTF_8.name());
9407
9408             int type;
9409             while ((type = in.next()) != END_DOCUMENT) {
9410                 final String tag = in.getName();
9411                 if (type == START_TAG) {
9412                     if (TAG_URI_GRANT.equals(tag)) {
9413                         final int sourceUserId;
9414                         final int targetUserId;
9415                         final int userHandle = readIntAttribute(in,
9416                                 ATTR_USER_HANDLE, UserHandle.USER_NULL);
9417                         if (userHandle != UserHandle.USER_NULL) {
9418                             // For backwards compatibility.
9419                             sourceUserId = userHandle;
9420                             targetUserId = userHandle;
9421                         } else {
9422                             sourceUserId = readIntAttribute(in, ATTR_SOURCE_USER_ID);
9423                             targetUserId = readIntAttribute(in, ATTR_TARGET_USER_ID);
9424                         }
9425                         final String sourcePkg = in.getAttributeValue(null, ATTR_SOURCE_PKG);
9426                         final String targetPkg = in.getAttributeValue(null, ATTR_TARGET_PKG);
9427                         final Uri uri = Uri.parse(in.getAttributeValue(null, ATTR_URI));
9428                         final boolean prefix = readBooleanAttribute(in, ATTR_PREFIX);
9429                         final int modeFlags = readIntAttribute(in, ATTR_MODE_FLAGS);
9430                         final long createdTime = readLongAttribute(in, ATTR_CREATED_TIME, now);
9431
9432                         // Sanity check that provider still belongs to source package
9433                         // Both direct boot aware and unaware packages are fine as we
9434                         // will do filtering at query time to avoid multiple parsing.
9435                         final ProviderInfo pi = getProviderInfoLocked(
9436                                 uri.getAuthority(), sourceUserId, MATCH_DIRECT_BOOT_AWARE
9437                                         | MATCH_DIRECT_BOOT_UNAWARE);
9438                         if (pi != null && sourcePkg.equals(pi.packageName)) {
9439                             int targetUid = -1;
9440                             try {
9441                                 targetUid = AppGlobals.getPackageManager().getPackageUid(
9442                                         targetPkg, MATCH_UNINSTALLED_PACKAGES, targetUserId);
9443                             } catch (RemoteException e) {
9444                             }
9445                             if (targetUid != -1) {
9446                                 final UriPermission perm = findOrCreateUriPermissionLocked(
9447                                         sourcePkg, targetPkg, targetUid,
9448                                         new GrantUri(sourceUserId, uri, prefix));
9449                                 perm.initPersistedModes(modeFlags, createdTime);
9450                             }
9451                         } else {
9452                             Slog.w(TAG, "Persisted grant for " + uri + " had source " + sourcePkg
9453                                     + " but instead found " + pi);
9454                         }
9455                     }
9456                 }
9457             }
9458         } catch (FileNotFoundException e) {
9459             // Missing grants is okay
9460         } catch (IOException e) {
9461             Slog.wtf(TAG, "Failed reading Uri grants", e);
9462         } catch (XmlPullParserException e) {
9463             Slog.wtf(TAG, "Failed reading Uri grants", e);
9464         } finally {
9465             IoUtils.closeQuietly(fis);
9466         }
9467     }
9468
9469     /**
9470      * @param uri This uri must NOT contain an embedded userId.
9471      * @param userId The userId in which the uri is to be resolved.
9472      */
9473     @Override
9474     public void takePersistableUriPermission(Uri uri, final int modeFlags, int userId) {
9475         enforceNotIsolatedCaller("takePersistableUriPermission");
9476
9477         Preconditions.checkFlagsArgument(modeFlags,
9478                 Intent.FLAG_GRANT_READ_URI_PERMISSION | Intent.FLAG_GRANT_WRITE_URI_PERMISSION);
9479
9480         synchronized (this) {
9481             final int callingUid = Binder.getCallingUid();
9482             boolean persistChanged = false;
9483             GrantUri grantUri = new GrantUri(userId, uri, false);
9484
9485             UriPermission exactPerm = findUriPermissionLocked(callingUid,
9486                     new GrantUri(userId, uri, false));
9487             UriPermission prefixPerm = findUriPermissionLocked(callingUid,
9488                     new GrantUri(userId, uri, true));
9489
9490             final boolean exactValid = (exactPerm != null)
9491                     && ((modeFlags & exactPerm.persistableModeFlags) == modeFlags);
9492             final boolean prefixValid = (prefixPerm != null)
9493                     && ((modeFlags & prefixPerm.persistableModeFlags) == modeFlags);
9494
9495             if (!(exactValid || prefixValid)) {
9496                 throw new SecurityException("No persistable permission grants found for UID "
9497                         + callingUid + " and Uri " + grantUri.toSafeString());
9498             }
9499
9500             if (exactValid) {
9501                 persistChanged |= exactPerm.takePersistableModes(modeFlags);
9502             }
9503             if (prefixValid) {
9504                 persistChanged |= prefixPerm.takePersistableModes(modeFlags);
9505             }
9506
9507             persistChanged |= maybePrunePersistedUriGrantsLocked(callingUid);
9508
9509             if (persistChanged) {
9510                 schedulePersistUriGrants();
9511             }
9512         }
9513     }
9514
9515     /**
9516      * @param uri This uri must NOT contain an embedded userId.
9517      * @param userId The userId in which the uri is to be resolved.
9518      */
9519     @Override
9520     public void releasePersistableUriPermission(Uri uri, final int modeFlags, int userId) {
9521         enforceNotIsolatedCaller("releasePersistableUriPermission");
9522
9523         Preconditions.checkFlagsArgument(modeFlags,
9524                 Intent.FLAG_GRANT_READ_URI_PERMISSION | Intent.FLAG_GRANT_WRITE_URI_PERMISSION);
9525
9526         synchronized (this) {
9527             final int callingUid = Binder.getCallingUid();
9528             boolean persistChanged = false;
9529
9530             UriPermission exactPerm = findUriPermissionLocked(callingUid,
9531                     new GrantUri(userId, uri, false));
9532             UriPermission prefixPerm = findUriPermissionLocked(callingUid,
9533                     new GrantUri(userId, uri, true));
9534             if (exactPerm == null && prefixPerm == null) {
9535                 throw new SecurityException("No permission grants found for UID " + callingUid
9536                         + " and Uri " + uri.toSafeString());
9537             }
9538
9539             if (exactPerm != null) {
9540                 persistChanged |= exactPerm.releasePersistableModes(modeFlags);
9541                 removeUriPermissionIfNeededLocked(exactPerm);
9542             }
9543             if (prefixPerm != null) {
9544                 persistChanged |= prefixPerm.releasePersistableModes(modeFlags);
9545                 removeUriPermissionIfNeededLocked(prefixPerm);
9546             }
9547
9548             if (persistChanged) {
9549                 schedulePersistUriGrants();
9550             }
9551         }
9552     }
9553
9554     /**
9555      * Prune any older {@link UriPermission} for the given UID until outstanding
9556      * persisted grants are below {@link #MAX_PERSISTED_URI_GRANTS}.
9557      *
9558      * @return if any mutations occured that require persisting.
9559      */
9560     private boolean maybePrunePersistedUriGrantsLocked(int uid) {
9561         final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.get(uid);
9562         if (perms == null) return false;
9563         if (perms.size() < MAX_PERSISTED_URI_GRANTS) return false;
9564
9565         final ArrayList<UriPermission> persisted = Lists.newArrayList();
9566         for (UriPermission perm : perms.values()) {
9567             if (perm.persistedModeFlags != 0) {
9568                 persisted.add(perm);
9569             }
9570         }
9571
9572         final int trimCount = persisted.size() - MAX_PERSISTED_URI_GRANTS;
9573         if (trimCount <= 0) return false;
9574
9575         Collections.sort(persisted, new UriPermission.PersistedTimeComparator());
9576         for (int i = 0; i < trimCount; i++) {
9577             final UriPermission perm = persisted.get(i);
9578
9579             if (DEBUG_URI_PERMISSION) Slog.v(TAG_URI_PERMISSION,
9580                     "Trimming grant created at " + perm.persistedCreateTime);
9581
9582             perm.releasePersistableModes(~0);
9583             removeUriPermissionIfNeededLocked(perm);
9584         }
9585
9586         return true;
9587     }
9588
9589     @Override
9590     public ParceledListSlice<android.content.UriPermission> getPersistedUriPermissions(
9591             String packageName, boolean incoming) {
9592         enforceNotIsolatedCaller("getPersistedUriPermissions");
9593         Preconditions.checkNotNull(packageName, "packageName");
9594
9595         final int callingUid = Binder.getCallingUid();
9596         final int callingUserId = UserHandle.getUserId(callingUid);
9597         final IPackageManager pm = AppGlobals.getPackageManager();
9598         try {
9599             final int packageUid = pm.getPackageUid(packageName,
9600                     MATCH_DIRECT_BOOT_AWARE | MATCH_DIRECT_BOOT_UNAWARE, callingUserId);
9601             if (packageUid != callingUid) {
9602                 throw new SecurityException(
9603                         "Package " + packageName + " does not belong to calling UID " + callingUid);
9604             }
9605         } catch (RemoteException e) {
9606             throw new SecurityException("Failed to verify package name ownership");
9607         }
9608
9609         final ArrayList<android.content.UriPermission> result = Lists.newArrayList();
9610         synchronized (this) {
9611             if (incoming) {
9612                 final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.get(
9613                         callingUid);
9614                 if (perms == null) {
9615                     Slog.w(TAG, "No permission grants found for " + packageName);
9616                 } else {
9617                     for (UriPermission perm : perms.values()) {
9618                         if (packageName.equals(perm.targetPkg) && perm.persistedModeFlags != 0) {
9619                             result.add(perm.buildPersistedPublicApiObject());
9620                         }
9621                     }
9622                 }
9623             } else {
9624                 final int size = mGrantedUriPermissions.size();
9625                 for (int i = 0; i < size; i++) {
9626                     final ArrayMap<GrantUri, UriPermission> perms =
9627                             mGrantedUriPermissions.valueAt(i);
9628                     for (UriPermission perm : perms.values()) {
9629                         if (packageName.equals(perm.sourcePkg) && perm.persistedModeFlags != 0) {
9630                             result.add(perm.buildPersistedPublicApiObject());
9631                         }
9632                     }
9633                 }
9634             }
9635         }
9636         return new ParceledListSlice<android.content.UriPermission>(result);
9637     }
9638
9639     @Override
9640     public ParceledListSlice<android.content.UriPermission> getGrantedUriPermissions(
9641             String packageName, int userId) {
9642         enforceCallingPermission(android.Manifest.permission.GET_APP_GRANTED_URI_PERMISSIONS,
9643                 "getGrantedUriPermissions");
9644
9645         final ArrayList<android.content.UriPermission> result = Lists.newArrayList();
9646         synchronized (this) {
9647             final int size = mGrantedUriPermissions.size();
9648             for (int i = 0; i < size; i++) {
9649                 final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.valueAt(i);
9650                 for (UriPermission perm : perms.values()) {
9651                     if (packageName.equals(perm.targetPkg) && perm.targetUserId == userId
9652                             && perm.persistedModeFlags != 0) {
9653                         result.add(perm.buildPersistedPublicApiObject());
9654                     }
9655                 }
9656             }
9657         }
9658         return new ParceledListSlice<android.content.UriPermission>(result);
9659     }
9660
9661     @Override
9662     public void clearGrantedUriPermissions(String packageName, int userId) {
9663         enforceCallingPermission(android.Manifest.permission.CLEAR_APP_GRANTED_URI_PERMISSIONS,
9664                 "clearGrantedUriPermissions");
9665         removeUriPermissionsForPackageLocked(packageName, userId, true);
9666     }
9667
9668     @Override
9669     public void showWaitingForDebugger(IApplicationThread who, boolean waiting) {
9670         synchronized (this) {
9671             ProcessRecord app =
9672                 who != null ? getRecordForAppLocked(who) : null;
9673             if (app == null) return;
9674
9675             Message msg = Message.obtain();
9676             msg.what = WAIT_FOR_DEBUGGER_UI_MSG;
9677             msg.obj = app;
9678             msg.arg1 = waiting ? 1 : 0;
9679             mUiHandler.sendMessage(msg);
9680         }
9681     }
9682
9683     @Override
9684     public void getMemoryInfo(ActivityManager.MemoryInfo outInfo) {
9685         final long homeAppMem = mProcessList.getMemLevel(ProcessList.HOME_APP_ADJ);
9686         final long cachedAppMem = mProcessList.getMemLevel(ProcessList.CACHED_APP_MIN_ADJ);
9687         outInfo.availMem = getFreeMemory();
9688         outInfo.totalMem = getTotalMemory();
9689         outInfo.threshold = homeAppMem;
9690         outInfo.lowMemory = outInfo.availMem < (homeAppMem + ((cachedAppMem-homeAppMem)/2));
9691         outInfo.hiddenAppThreshold = cachedAppMem;
9692         outInfo.secondaryServerThreshold = mProcessList.getMemLevel(
9693                 ProcessList.SERVICE_ADJ);
9694         outInfo.visibleAppThreshold = mProcessList.getMemLevel(
9695                 ProcessList.VISIBLE_APP_ADJ);
9696         outInfo.foregroundAppThreshold = mProcessList.getMemLevel(
9697                 ProcessList.FOREGROUND_APP_ADJ);
9698     }
9699
9700     // =========================================================
9701     // TASK MANAGEMENT
9702     // =========================================================
9703
9704     @Override
9705     public List<IBinder> getAppTasks(String callingPackage) {
9706         int callingUid = Binder.getCallingUid();
9707         long ident = Binder.clearCallingIdentity();
9708
9709         synchronized(this) {
9710             ArrayList<IBinder> list = new ArrayList<IBinder>();
9711             try {
9712                 if (DEBUG_ALL) Slog.v(TAG, "getAppTasks");
9713
9714                 final int N = mRecentTasks.size();
9715                 for (int i = 0; i < N; i++) {
9716                     TaskRecord tr = mRecentTasks.get(i);
9717                     // Skip tasks that do not match the caller.  We don't need to verify
9718                     // callingPackage, because we are also limiting to callingUid and know
9719                     // that will limit to the correct security sandbox.
9720                     if (tr.effectiveUid != callingUid) {
9721                         continue;
9722                     }
9723                     Intent intent = tr.getBaseIntent();
9724                     if (intent == null ||
9725                             !callingPackage.equals(intent.getComponent().getPackageName())) {
9726                         continue;
9727                     }
9728                     ActivityManager.RecentTaskInfo taskInfo =
9729                             createRecentTaskInfoFromTaskRecord(tr);
9730                     AppTaskImpl taskImpl = new AppTaskImpl(taskInfo.persistentId, callingUid);
9731                     list.add(taskImpl.asBinder());
9732                 }
9733             } finally {
9734                 Binder.restoreCallingIdentity(ident);
9735             }
9736             return list;
9737         }
9738     }
9739
9740     @Override
9741     public List<RunningTaskInfo> getTasks(int maxNum, int flags) {
9742         final int callingUid = Binder.getCallingUid();
9743         ArrayList<RunningTaskInfo> list = new ArrayList<RunningTaskInfo>();
9744
9745         synchronized(this) {
9746             if (DEBUG_ALL) Slog.v(
9747                 TAG, "getTasks: max=" + maxNum + ", flags=" + flags);
9748
9749             final boolean allowed = isGetTasksAllowed("getTasks", Binder.getCallingPid(),
9750                     callingUid);
9751
9752             // TODO: Improve with MRU list from all ActivityStacks.
9753             mStackSupervisor.getTasksLocked(maxNum, list, callingUid, allowed);
9754         }
9755
9756         return list;
9757     }
9758
9759     /**
9760      * Creates a new RecentTaskInfo from a TaskRecord.
9761      */
9762     private ActivityManager.RecentTaskInfo createRecentTaskInfoFromTaskRecord(TaskRecord tr) {
9763         // Update the task description to reflect any changes in the task stack
9764         tr.updateTaskDescription();
9765
9766         // Compose the recent task info
9767         ActivityManager.RecentTaskInfo rti = new ActivityManager.RecentTaskInfo();
9768         rti.id = tr.getTopActivity() == null ? INVALID_TASK_ID : tr.taskId;
9769         rti.persistentId = tr.taskId;
9770         rti.baseIntent = new Intent(tr.getBaseIntent());
9771         rti.origActivity = tr.origActivity;
9772         rti.realActivity = tr.realActivity;
9773         rti.description = tr.lastDescription;
9774         rti.stackId = tr.getStackId();
9775         rti.userId = tr.userId;
9776         rti.taskDescription = new ActivityManager.TaskDescription(tr.lastTaskDescription);
9777         rti.firstActiveTime = tr.firstActiveTime;
9778         rti.lastActiveTime = tr.lastActiveTime;
9779         rti.affiliatedTaskId = tr.mAffiliatedTaskId;
9780         rti.affiliatedTaskColor = tr.mAffiliatedTaskColor;
9781         rti.numActivities = 0;
9782         if (tr.mBounds != null) {
9783             rti.bounds = new Rect(tr.mBounds);
9784         }
9785         rti.supportsSplitScreenMultiWindow = tr.supportsSplitScreen();
9786         rti.resizeMode = tr.mResizeMode;
9787
9788         ActivityRecord base = null;
9789         ActivityRecord top = null;
9790         ActivityRecord tmp;
9791
9792         for (int i = tr.mActivities.size() - 1; i >= 0; --i) {
9793             tmp = tr.mActivities.get(i);
9794             if (tmp.finishing) {
9795                 continue;
9796             }
9797             base = tmp;
9798             if (top == null || (top.state == ActivityState.INITIALIZING)) {
9799                 top = base;
9800             }
9801             rti.numActivities++;
9802         }
9803
9804         rti.baseActivity = (base != null) ? base.intent.getComponent() : null;
9805         rti.topActivity = (top != null) ? top.intent.getComponent() : null;
9806
9807         return rti;
9808     }
9809
9810     private boolean isGetTasksAllowed(String caller, int callingPid, int callingUid) {
9811         boolean allowed = checkPermission(android.Manifest.permission.REAL_GET_TASKS,
9812                 callingPid, callingUid) == PackageManager.PERMISSION_GRANTED;
9813         if (!allowed) {
9814             if (checkPermission(android.Manifest.permission.GET_TASKS,
9815                     callingPid, callingUid) == PackageManager.PERMISSION_GRANTED) {
9816                 // Temporary compatibility: some existing apps on the system image may
9817                 // still be requesting the old permission and not switched to the new
9818                 // one; if so, we'll still allow them full access.  This means we need
9819                 // to see if they are holding the old permission and are a system app.
9820                 try {
9821                     if (AppGlobals.getPackageManager().isUidPrivileged(callingUid)) {
9822                         allowed = true;
9823                         if (DEBUG_TASKS) Slog.w(TAG, caller + ": caller " + callingUid
9824                                 + " is using old GET_TASKS but privileged; allowing");
9825                     }
9826                 } catch (RemoteException e) {
9827                 }
9828             }
9829         }
9830         if (!allowed) {
9831             if (DEBUG_TASKS) Slog.w(TAG, caller + ": caller " + callingUid
9832                     + " does not hold REAL_GET_TASKS; limiting output");
9833         }
9834         return allowed;
9835     }
9836
9837     @Override
9838     public ParceledListSlice<ActivityManager.RecentTaskInfo> getRecentTasks(int maxNum, int flags,
9839             int userId) {
9840         final int callingUid = Binder.getCallingUid();
9841         userId = mUserController.handleIncomingUser(Binder.getCallingPid(), callingUid, userId,
9842                 false, ALLOW_FULL_ONLY, "getRecentTasks", null);
9843
9844         final boolean includeProfiles = (flags & ActivityManager.RECENT_INCLUDE_PROFILES) != 0;
9845         final boolean withExcluded = (flags&ActivityManager.RECENT_WITH_EXCLUDED) != 0;
9846         synchronized (this) {
9847             final boolean allowed = isGetTasksAllowed("getRecentTasks", Binder.getCallingPid(),
9848                     callingUid);
9849             final boolean detailed = checkCallingPermission(
9850                     android.Manifest.permission.GET_DETAILED_TASKS)
9851                     == PackageManager.PERMISSION_GRANTED;
9852
9853             if (!isUserRunning(userId, ActivityManager.FLAG_AND_UNLOCKED)) {
9854                 Slog.i(TAG, "user " + userId + " is still locked. Cannot load recents");
9855                 return ParceledListSlice.emptyList();
9856             }
9857             mRecentTasks.loadUserRecentsLocked(userId);
9858
9859             final int recentsCount = mRecentTasks.size();
9860             ArrayList<ActivityManager.RecentTaskInfo> res =
9861                     new ArrayList<>(maxNum < recentsCount ? maxNum : recentsCount);
9862
9863             final Set<Integer> includedUsers;
9864             if (includeProfiles) {
9865                 includedUsers = mUserController.getProfileIds(userId);
9866             } else {
9867                 includedUsers = new HashSet<>();
9868             }
9869             includedUsers.add(Integer.valueOf(userId));
9870
9871             for (int i = 0; i < recentsCount && maxNum > 0; i++) {
9872                 TaskRecord tr = mRecentTasks.get(i);
9873                 // Only add calling user or related users recent tasks
9874                 if (!includedUsers.contains(Integer.valueOf(tr.userId))) {
9875                     if (DEBUG_RECENTS) Slog.d(TAG_RECENTS, "Skipping, not user: " + tr);
9876                     continue;
9877                 }
9878
9879                 if (tr.realActivitySuspended) {
9880                     if (DEBUG_RECENTS) Slog.d(TAG_RECENTS, "Skipping, activity suspended: " + tr);
9881                     continue;
9882                 }
9883
9884                 // Return the entry if desired by the caller.  We always return
9885                 // the first entry, because callers always expect this to be the
9886                 // foreground app.  We may filter others if the caller has
9887                 // not supplied RECENT_WITH_EXCLUDED and there is some reason
9888                 // we should exclude the entry.
9889
9890                 if (i == 0
9891                         || withExcluded
9892                         || (tr.intent == null)
9893                         || ((tr.intent.getFlags() & Intent.FLAG_ACTIVITY_EXCLUDE_FROM_RECENTS)
9894                                 == 0)) {
9895                     if (!allowed) {
9896                         // If the caller doesn't have the GET_TASKS permission, then only
9897                         // allow them to see a small subset of tasks -- their own and home.
9898                         if (!tr.isHomeTask() && tr.effectiveUid != callingUid) {
9899                             if (DEBUG_RECENTS) Slog.d(TAG_RECENTS, "Skipping, not allowed: " + tr);
9900                             continue;
9901                         }
9902                     }
9903                     final ActivityStack stack = tr.getStack();
9904                     if ((flags & ActivityManager.RECENT_IGNORE_HOME_AND_RECENTS_STACK_TASKS) != 0) {
9905                         if (stack != null && stack.isHomeOrRecentsStack()) {
9906                             if (DEBUG_RECENTS) Slog.d(TAG_RECENTS,
9907                                     "Skipping, home or recents stack task: " + tr);
9908                             continue;
9909                         }
9910                     }
9911                     if ((flags & ActivityManager.RECENT_INGORE_DOCKED_STACK_TOP_TASK) != 0) {
9912                         if (stack != null && stack.isDockedStack() && stack.topTask() == tr) {
9913                             if (DEBUG_RECENTS) Slog.d(TAG_RECENTS,
9914                                     "Skipping, top task in docked stack: " + tr);
9915                             continue;
9916                         }
9917                     }
9918                     if ((flags & ActivityManager.RECENT_INGORE_PINNED_STACK_TASKS) != 0) {
9919                         if (stack != null && stack.isPinnedStack()) {
9920                             if (DEBUG_RECENTS) Slog.d(TAG_RECENTS,
9921                                     "Skipping, pinned stack task: " + tr);
9922                             continue;
9923                         }
9924                     }
9925                     if (tr.autoRemoveRecents && tr.getTopActivity() == null) {
9926                         // Don't include auto remove tasks that are finished or finishing.
9927                         if (DEBUG_RECENTS) Slog.d(TAG_RECENTS,
9928                                 "Skipping, auto-remove without activity: " + tr);
9929                         continue;
9930                     }
9931                     if ((flags&ActivityManager.RECENT_IGNORE_UNAVAILABLE) != 0
9932                             && !tr.isAvailable) {
9933                         if (DEBUG_RECENTS) Slog.d(TAG_RECENTS,
9934                                 "Skipping, unavail real act: " + tr);
9935                         continue;
9936                     }
9937
9938                     if (!tr.mUserSetupComplete) {
9939                         // Don't include task launched while user is not done setting-up.
9940                         if (DEBUG_RECENTS) Slog.d(TAG_RECENTS,
9941                                 "Skipping, user setup not complete: " + tr);
9942                         continue;
9943                     }
9944
9945                     ActivityManager.RecentTaskInfo rti = createRecentTaskInfoFromTaskRecord(tr);
9946                     if (!detailed) {
9947                         rti.baseIntent.replaceExtras((Bundle)null);
9948                     }
9949
9950                     res.add(rti);
9951                     maxNum--;
9952                 }
9953             }
9954             return new ParceledListSlice<>(res);
9955         }
9956     }
9957
9958     @Override
9959     public ActivityManager.TaskThumbnail getTaskThumbnail(int id) {
9960         synchronized (this) {
9961             enforceCallingPermission(android.Manifest.permission.READ_FRAME_BUFFER,
9962                     "getTaskThumbnail()");
9963             final TaskRecord tr = mStackSupervisor.anyTaskForIdLocked(
9964                     id, MATCH_TASK_IN_STACKS_OR_RECENT_TASKS, INVALID_STACK_ID);
9965             if (tr != null) {
9966                 return tr.getTaskThumbnailLocked();
9967             }
9968         }
9969         return null;
9970     }
9971
9972     @Override
9973     public ActivityManager.TaskDescription getTaskDescription(int id) {
9974         synchronized (this) {
9975             enforceCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS,
9976                     "getTaskDescription()");
9977             final TaskRecord tr = mStackSupervisor.anyTaskForIdLocked(id,
9978                     MATCH_TASK_IN_STACKS_OR_RECENT_TASKS, INVALID_STACK_ID);
9979             if (tr != null) {
9980                 return tr.lastTaskDescription;
9981             }
9982         }
9983         return null;
9984     }
9985
9986     @Override
9987     public int addAppTask(IBinder activityToken, Intent intent,
9988             ActivityManager.TaskDescription description, Bitmap thumbnail) throws RemoteException {
9989         final int callingUid = Binder.getCallingUid();
9990         final long callingIdent = Binder.clearCallingIdentity();
9991
9992         try {
9993             synchronized (this) {
9994                 ActivityRecord r = ActivityRecord.isInStackLocked(activityToken);
9995                 if (r == null) {
9996                     throw new IllegalArgumentException("Activity does not exist; token="
9997                             + activityToken);
9998                 }
9999                 ComponentName comp = intent.getComponent();
10000                 if (comp == null) {
10001                     throw new IllegalArgumentException("Intent " + intent
10002                             + " must specify explicit component");
10003                 }
10004                 if (thumbnail.getWidth() != mThumbnailWidth
10005                         || thumbnail.getHeight() != mThumbnailHeight) {
10006                     throw new IllegalArgumentException("Bad thumbnail size: got "
10007                             + thumbnail.getWidth() + "x" + thumbnail.getHeight() + ", require "
10008                             + mThumbnailWidth + "x" + mThumbnailHeight);
10009                 }
10010                 if (intent.getSelector() != null) {
10011                     intent.setSelector(null);
10012                 }
10013                 if (intent.getSourceBounds() != null) {
10014                     intent.setSourceBounds(null);
10015                 }
10016                 if ((intent.getFlags()&Intent.FLAG_ACTIVITY_NEW_DOCUMENT) != 0) {
10017                     if ((intent.getFlags()&Intent.FLAG_ACTIVITY_RETAIN_IN_RECENTS) == 0) {
10018                         // The caller has added this as an auto-remove task...  that makes no
10019                         // sense, so turn off auto-remove.
10020                         intent.addFlags(Intent.FLAG_ACTIVITY_RETAIN_IN_RECENTS);
10021                     }
10022                 }
10023                 if (!comp.equals(mLastAddedTaskComponent) || callingUid != mLastAddedTaskUid) {
10024                     mLastAddedTaskActivity = null;
10025                 }
10026                 ActivityInfo ainfo = mLastAddedTaskActivity;
10027                 if (ainfo == null) {
10028                     ainfo = mLastAddedTaskActivity = AppGlobals.getPackageManager().getActivityInfo(
10029                             comp, 0, UserHandle.getUserId(callingUid));
10030                     if (ainfo.applicationInfo.uid != callingUid) {
10031                         throw new SecurityException(
10032                                 "Can't add task for another application: target uid="
10033                                 + ainfo.applicationInfo.uid + ", calling uid=" + callingUid);
10034                     }
10035                 }
10036
10037                 TaskRecord task = new TaskRecord(this,
10038                         mStackSupervisor.getNextTaskIdForUserLocked(r.userId),
10039                         ainfo, intent, description, new TaskThumbnailInfo());
10040
10041                 int trimIdx = mRecentTasks.trimForTaskLocked(task, false);
10042                 if (trimIdx >= 0) {
10043                     // If this would have caused a trim, then we'll abort because that
10044                     // means it would be added at the end of the list but then just removed.
10045                     return INVALID_TASK_ID;
10046                 }
10047
10048                 final int N = mRecentTasks.size();
10049                 if (N >= (ActivityManager.getMaxRecentTasksStatic()-1)) {
10050                     final TaskRecord tr = mRecentTasks.remove(N - 1);
10051                     tr.removedFromRecents();
10052                 }
10053
10054                 task.inRecents = true;
10055                 mRecentTasks.add(task);
10056                 r.getStack().addTask(task, false, "addAppTask");
10057
10058                 task.setLastThumbnailLocked(thumbnail);
10059                 task.freeLastThumbnail();
10060                 return task.taskId;
10061             }
10062         } finally {
10063             Binder.restoreCallingIdentity(callingIdent);
10064         }
10065     }
10066
10067     @Override
10068     public Point getAppTaskThumbnailSize() {
10069         synchronized (this) {
10070             return new Point(mThumbnailWidth,  mThumbnailHeight);
10071         }
10072     }
10073
10074     @Override
10075     public void setTaskDescription(IBinder token, ActivityManager.TaskDescription td) {
10076         synchronized (this) {
10077             ActivityRecord r = ActivityRecord.isInStackLocked(token);
10078             if (r != null) {
10079                 r.setTaskDescription(td);
10080                 final TaskRecord task = r.getTask();
10081                 task.updateTaskDescription();
10082                 mTaskChangeNotificationController.notifyTaskDescriptionChanged(task.taskId, td);
10083             }
10084         }
10085     }
10086
10087     @Override
10088     public void setTaskResizeable(int taskId, int resizeableMode) {
10089         synchronized (this) {
10090             final TaskRecord task = mStackSupervisor.anyTaskForIdLocked(
10091                     taskId, MATCH_TASK_IN_STACKS_OR_RECENT_TASKS, INVALID_STACK_ID);
10092             if (task == null) {
10093                 Slog.w(TAG, "setTaskResizeable: taskId=" + taskId + " not found");
10094                 return;
10095             }
10096             task.setResizeMode(resizeableMode);
10097         }
10098     }
10099
10100     @Override
10101     public void resizeTask(int taskId, Rect bounds, int resizeMode) {
10102         enforceCallingPermission(MANAGE_ACTIVITY_STACKS, "resizeTask()");
10103         long ident = Binder.clearCallingIdentity();
10104         try {
10105             synchronized (this) {
10106                 TaskRecord task = mStackSupervisor.anyTaskForIdLocked(taskId);
10107                 if (task == null) {
10108                     Slog.w(TAG, "resizeTask: taskId=" + taskId + " not found");
10109                     return;
10110                 }
10111                 // Place the task in the right stack if it isn't there already based on
10112                 // the requested bounds.
10113                 // The stack transition logic is:
10114                 // - a null bounds on a freeform task moves that task to fullscreen
10115                 // - a non-null bounds on a non-freeform (fullscreen OR docked) task moves
10116                 //   that task to freeform
10117                 // - otherwise the task is not moved
10118                 int stackId = task.getStackId();
10119                 if (!StackId.isTaskResizeAllowed(stackId)) {
10120                     throw new IllegalArgumentException("resizeTask not allowed on task=" + task);
10121                 }
10122                 if (bounds == null && stackId == FREEFORM_WORKSPACE_STACK_ID) {
10123                     stackId = FULLSCREEN_WORKSPACE_STACK_ID;
10124                 } else if (bounds != null && stackId != FREEFORM_WORKSPACE_STACK_ID ) {
10125                     stackId = FREEFORM_WORKSPACE_STACK_ID;
10126                 }
10127
10128                 // Reparent the task to the right stack if necessary
10129                 boolean preserveWindow = (resizeMode & RESIZE_MODE_PRESERVE_WINDOW) != 0;
10130                 if (stackId != task.getStackId()) {
10131                     // Defer resume until the task is resized below
10132                     task.reparent(stackId, ON_TOP, REPARENT_KEEP_STACK_AT_FRONT, ANIMATE,
10133                             DEFER_RESUME, "resizeTask");
10134                     preserveWindow = false;
10135                 }
10136
10137                 // After reparenting (which only resizes the task to the stack bounds), resize the
10138                 // task to the actual bounds provided
10139                 task.resize(bounds, resizeMode, preserveWindow, !DEFER_RESUME);
10140             }
10141         } finally {
10142             Binder.restoreCallingIdentity(ident);
10143         }
10144     }
10145
10146     @Override
10147     public Rect getTaskBounds(int taskId) {
10148         enforceCallingPermission(MANAGE_ACTIVITY_STACKS, "getTaskBounds()");
10149         long ident = Binder.clearCallingIdentity();
10150         Rect rect = new Rect();
10151         try {
10152             synchronized (this) {
10153                 final TaskRecord task = mStackSupervisor.anyTaskForIdLocked(taskId,
10154                         MATCH_TASK_IN_STACKS_OR_RECENT_TASKS, INVALID_STACK_ID);
10155                 if (task == null) {
10156                     Slog.w(TAG, "getTaskBounds: taskId=" + taskId + " not found");
10157                     return rect;
10158                 }
10159                 if (task.getStack() != null) {
10160                     // Return the bounds from window manager since it will be adjusted for various
10161                     // things like the presense of a docked stack for tasks that aren't resizeable.
10162                     task.getWindowContainerBounds(rect);
10163                 } else {
10164                     // Task isn't in window manager yet since it isn't associated with a stack.
10165                     // Return the persist value from activity manager
10166                     if (task.mBounds != null) {
10167                         rect.set(task.mBounds);
10168                     } else if (task.mLastNonFullscreenBounds != null) {
10169                         rect.set(task.mLastNonFullscreenBounds);
10170                     }
10171                 }
10172             }
10173         } finally {
10174             Binder.restoreCallingIdentity(ident);
10175         }
10176         return rect;
10177     }
10178
10179     @Override
10180     public void cancelTaskWindowTransition(int taskId) {
10181         enforceCallingPermission(MANAGE_ACTIVITY_STACKS, "cancelTaskWindowTransition()");
10182         final long ident = Binder.clearCallingIdentity();
10183         try {
10184             synchronized (this) {
10185                 final TaskRecord task = mStackSupervisor.anyTaskForIdLocked(taskId,
10186                         MATCH_TASK_IN_STACKS_ONLY, INVALID_STACK_ID);
10187                 if (task == null) {
10188                     Slog.w(TAG, "cancelTaskWindowTransition: taskId=" + taskId + " not found");
10189                     return;
10190                 }
10191                 task.cancelWindowTransition();
10192             }
10193         } finally {
10194             Binder.restoreCallingIdentity(ident);
10195         }
10196     }
10197
10198     @Override
10199     public void cancelTaskThumbnailTransition(int taskId) {
10200         enforceCallingPermission(MANAGE_ACTIVITY_STACKS, "cancelTaskThumbnailTransition()");
10201         final long ident = Binder.clearCallingIdentity();
10202         try {
10203             synchronized (this) {
10204                 final TaskRecord task = mStackSupervisor.anyTaskForIdLocked(taskId,
10205                         MATCH_TASK_IN_STACKS_ONLY, INVALID_STACK_ID);
10206                 if (task == null) {
10207                     Slog.w(TAG, "cancelTaskThumbnailTransition: taskId=" + taskId + " not found");
10208                     return;
10209                 }
10210                 task.cancelThumbnailTransition();
10211             }
10212         } finally {
10213             Binder.restoreCallingIdentity(ident);
10214         }
10215     }
10216
10217     @Override
10218     public TaskSnapshot getTaskSnapshot(int taskId, boolean reducedResolution) {
10219         enforceCallingPermission(READ_FRAME_BUFFER, "getTaskSnapshot()");
10220         final long ident = Binder.clearCallingIdentity();
10221         try {
10222             final TaskRecord task;
10223             synchronized (this) {
10224                 task = mStackSupervisor.anyTaskForIdLocked(taskId,
10225                         MATCH_TASK_IN_STACKS_OR_RECENT_TASKS, INVALID_STACK_ID);
10226                 if (task == null) {
10227                     Slog.w(TAG, "getTaskSnapshot: taskId=" + taskId + " not found");
10228                     return null;
10229                 }
10230             }
10231             // Don't call this while holding the lock as this operation might hit the disk.
10232             return task.getSnapshot(reducedResolution);
10233         } finally {
10234             Binder.restoreCallingIdentity(ident);
10235         }
10236     }
10237
10238     @Override
10239     public Bitmap getTaskDescriptionIcon(String filePath, int userId) {
10240         if (userId != UserHandle.getCallingUserId()) {
10241             enforceCallingPermission(android.Manifest.permission.INTERACT_ACROSS_USERS_FULL,
10242                     "getTaskDescriptionIcon");
10243         }
10244         final File passedIconFile = new File(filePath);
10245         final File legitIconFile = new File(TaskPersister.getUserImagesDir(userId),
10246                 passedIconFile.getName());
10247         if (!legitIconFile.getPath().equals(filePath)
10248                 || !filePath.contains(ActivityRecord.ACTIVITY_ICON_SUFFIX)) {
10249             throw new IllegalArgumentException("Bad file path: " + filePath
10250                     + " passed for userId " + userId);
10251         }
10252         return mRecentTasks.getTaskDescriptionIcon(filePath);
10253     }
10254
10255     @Override
10256     public void startInPlaceAnimationOnFrontMostApplication(Bundle opts)
10257             throws RemoteException {
10258         final ActivityOptions activityOptions = ActivityOptions.fromBundle(opts);
10259         if (activityOptions.getAnimationType() != ActivityOptions.ANIM_CUSTOM_IN_PLACE ||
10260                 activityOptions.getCustomInPlaceResId() == 0) {
10261             throw new IllegalArgumentException("Expected in-place ActivityOption " +
10262                     "with valid animation");
10263         }
10264         mWindowManager.prepareAppTransition(TRANSIT_TASK_IN_PLACE, false);
10265         mWindowManager.overridePendingAppTransitionInPlace(activityOptions.getPackageName(),
10266                 activityOptions.getCustomInPlaceResId());
10267         mWindowManager.executeAppTransition();
10268     }
10269
10270     private void removeTasksByPackageNameLocked(String packageName, int userId) {
10271         // Remove all tasks with activities in the specified package from the list of recent tasks
10272         for (int i = mRecentTasks.size() - 1; i >= 0; i--) {
10273             TaskRecord tr = mRecentTasks.get(i);
10274             if (tr.userId != userId) continue;
10275
10276             ComponentName cn = tr.intent.getComponent();
10277             if (cn != null && cn.getPackageName().equals(packageName)) {
10278                 // If the package name matches, remove the task.
10279                 mStackSupervisor.removeTaskByIdLocked(tr.taskId, true, REMOVE_FROM_RECENTS);
10280             }
10281         }
10282     }
10283
10284     private void cleanupDisabledPackageTasksLocked(String packageName, Set<String> filterByClasses,
10285             int userId) {
10286
10287         for (int i = mRecentTasks.size() - 1; i >= 0; i--) {
10288             TaskRecord tr = mRecentTasks.get(i);
10289             if (userId != UserHandle.USER_ALL && tr.userId != userId) {
10290                 continue;
10291             }
10292
10293             ComponentName cn = tr.intent.getComponent();
10294             final boolean sameComponent = cn != null && cn.getPackageName().equals(packageName)
10295                     && (filterByClasses == null || filterByClasses.contains(cn.getClassName()));
10296             if (sameComponent) {
10297                 mStackSupervisor.removeTaskByIdLocked(tr.taskId, false, REMOVE_FROM_RECENTS);
10298             }
10299         }
10300     }
10301
10302     @Override
10303     public void removeStack(int stackId) {
10304         enforceCallingPermission(Manifest.permission.MANAGE_ACTIVITY_STACKS, "removeStack()");
10305         if (StackId.isHomeOrRecentsStack(stackId)) {
10306             throw new IllegalArgumentException("Removing home or recents stack is not allowed.");
10307         }
10308
10309         synchronized (this) {
10310             final long ident = Binder.clearCallingIdentity();
10311             try {
10312                 mStackSupervisor.removeStackLocked(stackId);
10313             } finally {
10314                 Binder.restoreCallingIdentity(ident);
10315             }
10316         }
10317     }
10318
10319     @Override
10320     public void moveStackToDisplay(int stackId, int displayId) {
10321         enforceCallingPermission(INTERNAL_SYSTEM_WINDOW, "moveStackToDisplay()");
10322
10323         synchronized (this) {
10324             final long ident = Binder.clearCallingIdentity();
10325             try {
10326                 if (DEBUG_STACK) Slog.d(TAG_STACK, "moveStackToDisplay: moving stackId=" + stackId
10327                         + " to displayId=" + displayId);
10328                 mStackSupervisor.moveStackToDisplayLocked(stackId, displayId, ON_TOP);
10329             } finally {
10330                 Binder.restoreCallingIdentity(ident);
10331             }
10332         }
10333     }
10334
10335     @Override
10336     public boolean removeTask(int taskId) {
10337         enforceCallingPermission(android.Manifest.permission.REMOVE_TASKS, "removeTask()");
10338         synchronized (this) {
10339             final long ident = Binder.clearCallingIdentity();
10340             try {
10341                 return mStackSupervisor.removeTaskByIdLocked(taskId, true, REMOVE_FROM_RECENTS);
10342             } finally {
10343                 Binder.restoreCallingIdentity(ident);
10344             }
10345         }
10346     }
10347
10348     /**
10349      * TODO: Add mController hook
10350      */
10351     @Override
10352     public void moveTaskToFront(int taskId, int flags, Bundle bOptions) {
10353         enforceCallingPermission(android.Manifest.permission.REORDER_TASKS, "moveTaskToFront()");
10354
10355         if (DEBUG_STACK) Slog.d(TAG_STACK, "moveTaskToFront: moving taskId=" + taskId);
10356         synchronized(this) {
10357             moveTaskToFrontLocked(taskId, flags, bOptions, false /* fromRecents */);
10358         }
10359     }
10360
10361     void moveTaskToFrontLocked(int taskId, int flags, Bundle bOptions, boolean fromRecents) {
10362         ActivityOptions options = ActivityOptions.fromBundle(bOptions);
10363
10364         if (!checkAppSwitchAllowedLocked(Binder.getCallingPid(),
10365                 Binder.getCallingUid(), -1, -1, "Task to front")) {
10366             ActivityOptions.abort(options);
10367             return;
10368         }
10369         final long origId = Binder.clearCallingIdentity();
10370         try {
10371             final TaskRecord task = mStackSupervisor.anyTaskForIdLocked(taskId);
10372             if (task == null) {
10373                 Slog.d(TAG, "Could not find task for id: "+ taskId);
10374                 return;
10375             }
10376             if (mStackSupervisor.isLockTaskModeViolation(task)) {
10377                 mStackSupervisor.showLockTaskToast();
10378                 Slog.e(TAG, "moveTaskToFront: Attempt to violate Lock Task Mode");
10379                 return;
10380             }
10381             final ActivityRecord prev = mStackSupervisor.topRunningActivityLocked();
10382             if (prev != null) {
10383                 task.setTaskToReturnTo(prev);
10384             }
10385             mStackSupervisor.findTaskToMoveToFrontLocked(task, flags, options, "moveTaskToFront",
10386                     false /* forceNonResizable */);
10387
10388             final ActivityRecord topActivity = task.getTopActivity();
10389             if (topActivity != null) {
10390
10391                 // We are reshowing a task, use a starting window to hide the initial draw delay
10392                 // so the transition can start earlier.
10393                 topActivity.showStartingWindow(null /* prev */, false /* newTask */,
10394                         true /* taskSwitch */, fromRecents);
10395             }
10396         } finally {
10397             Binder.restoreCallingIdentity(origId);
10398         }
10399         ActivityOptions.abort(options);
10400     }
10401
10402     /**
10403      * Attempts to move a task backwards in z-order (the order of activities within the task is
10404      * unchanged).
10405      *
10406      * There are several possible results of this call:
10407      * - if the task is locked, then we will show the lock toast
10408      * - if there is a task behind the provided task, then that task is made visible and resumed as
10409      *   this task is moved to the back
10410      * - otherwise, if there are no other tasks in the stack:
10411      *     - if this task is in the pinned stack, then we remove the stack completely, which will
10412      *       have the effect of moving the task to the top or bottom of the fullscreen stack
10413      *       (depending on whether it is visible)
10414      *     - otherwise, we simply return home and hide this task
10415      *
10416      * @param token A reference to the activity we wish to move
10417      * @param nonRoot If false then this only works if the activity is the root
10418      *                of a task; if true it will work for any activity in a task.
10419      * @return Returns true if the move completed, false if not.
10420      */
10421     @Override
10422     public boolean moveActivityTaskToBack(IBinder token, boolean nonRoot) {
10423         enforceNotIsolatedCaller("moveActivityTaskToBack");
10424         synchronized(this) {
10425             final long origId = Binder.clearCallingIdentity();
10426             try {
10427                 int taskId = ActivityRecord.getTaskForActivityLocked(token, !nonRoot);
10428                 final TaskRecord task = mStackSupervisor.anyTaskForIdLocked(taskId);
10429                 if (task != null) {
10430                     return ActivityRecord.getStackLocked(token).moveTaskToBackLocked(taskId);
10431                 }
10432             } finally {
10433                 Binder.restoreCallingIdentity(origId);
10434             }
10435         }
10436         return false;
10437     }
10438
10439     @Override
10440     public void moveTaskBackwards(int task) {
10441         enforceCallingPermission(android.Manifest.permission.REORDER_TASKS,
10442                 "moveTaskBackwards()");
10443
10444         synchronized(this) {
10445             if (!checkAppSwitchAllowedLocked(Binder.getCallingPid(),
10446                     Binder.getCallingUid(), -1, -1, "Task backwards")) {
10447                 return;
10448             }
10449             final long origId = Binder.clearCallingIdentity();
10450             moveTaskBackwardsLocked(task);
10451             Binder.restoreCallingIdentity(origId);
10452         }
10453     }
10454
10455     private final void moveTaskBackwardsLocked(int task) {
10456         Slog.e(TAG, "moveTaskBackwards not yet implemented!");
10457     }
10458
10459     @Override
10460     public IActivityContainer createVirtualActivityContainer(IBinder parentActivityToken,
10461             IActivityContainerCallback callback) throws RemoteException {
10462         enforceCallingPermission(MANAGE_ACTIVITY_STACKS, "createActivityContainer()");
10463         synchronized (this) {
10464             if (parentActivityToken == null) {
10465                 throw new IllegalArgumentException("parent token must not be null");
10466             }
10467             ActivityRecord r = ActivityRecord.forTokenLocked(parentActivityToken);
10468             if (r == null) {
10469                 return null;
10470             }
10471             if (callback == null) {
10472                 throw new IllegalArgumentException("callback must not be null");
10473             }
10474             return mStackSupervisor.createVirtualActivityContainer(r, callback);
10475         }
10476     }
10477
10478     @Override
10479     public IActivityContainer createStackOnDisplay(int displayId) throws RemoteException {
10480         enforceCallingPermission(MANAGE_ACTIVITY_STACKS, "createStackOnDisplay()");
10481         synchronized (this) {
10482             final int stackId = mStackSupervisor.getNextStackId();
10483             final ActivityStack stack =
10484                     mStackSupervisor.createStackOnDisplay(stackId, displayId, true /*onTop*/);
10485             if (stack == null) {
10486                 return null;
10487             }
10488             return stack.mActivityContainer;
10489         }
10490     }
10491
10492     @Override
10493     public int getActivityDisplayId(IBinder activityToken) throws RemoteException {
10494         synchronized (this) {
10495             ActivityStack stack = ActivityRecord.getStackLocked(activityToken);
10496             if (stack != null && stack.mActivityContainer.isAttachedLocked()) {
10497                 return stack.mActivityContainer.getDisplayId();
10498             }
10499             return DEFAULT_DISPLAY;
10500         }
10501     }
10502
10503     @Override
10504     public int getActivityStackId(IBinder token) throws RemoteException {
10505         synchronized (this) {
10506             ActivityStack stack = ActivityRecord.getStackLocked(token);
10507             if (stack == null) {
10508                 return INVALID_STACK_ID;
10509             }
10510             return stack.mStackId;
10511         }
10512     }
10513
10514     @Override
10515     public void exitFreeformMode(IBinder token) throws RemoteException {
10516         synchronized (this) {
10517             long ident = Binder.clearCallingIdentity();
10518             try {
10519                 final ActivityRecord r = ActivityRecord.forTokenLocked(token);
10520                 if (r == null) {
10521                     throw new IllegalArgumentException(
10522                             "exitFreeformMode: No activity record matching token=" + token);
10523                 }
10524
10525                 final ActivityStack stack = r.getStack();
10526                 if (stack == null || stack.mStackId != FREEFORM_WORKSPACE_STACK_ID) {
10527                     throw new IllegalStateException(
10528                             "exitFreeformMode: You can only go fullscreen from freeform.");
10529                 }
10530
10531                 if (DEBUG_STACK) Slog.d(TAG_STACK, "exitFreeformMode: " + r);
10532                 r.getTask().reparent(FULLSCREEN_WORKSPACE_STACK_ID, ON_TOP,
10533                         REPARENT_KEEP_STACK_AT_FRONT, ANIMATE, !DEFER_RESUME, "exitFreeformMode");
10534             } finally {
10535                 Binder.restoreCallingIdentity(ident);
10536             }
10537         }
10538     }
10539
10540     @Override
10541     public void moveTaskToStack(int taskId, int stackId, boolean toTop) {
10542         enforceCallingPermission(MANAGE_ACTIVITY_STACKS, "moveTaskToStack()");
10543         if (StackId.isHomeOrRecentsStack(stackId)) {
10544             throw new IllegalArgumentException(
10545                     "moveTaskToStack: Attempt to move task " + taskId + " to stack " + stackId);
10546         }
10547         synchronized (this) {
10548             long ident = Binder.clearCallingIdentity();
10549             try {
10550                 final TaskRecord task = mStackSupervisor.anyTaskForIdLocked(taskId);
10551                 if (task == null) {
10552                     Slog.w(TAG, "moveTaskToStack: No task for id=" + taskId);
10553                     return;
10554                 }
10555
10556                 if (DEBUG_STACK) Slog.d(TAG_STACK, "moveTaskToStack: moving task=" + taskId
10557                         + " to stackId=" + stackId + " toTop=" + toTop);
10558                 if (stackId == DOCKED_STACK_ID) {
10559                     mWindowManager.setDockedStackCreateState(DOCKED_STACK_CREATE_MODE_TOP_OR_LEFT,
10560                             null /* initialBounds */);
10561                 }
10562                 task.reparent(stackId, toTop,
10563                         REPARENT_KEEP_STACK_AT_FRONT, ANIMATE, !DEFER_RESUME, "moveTaskToStack");
10564             } finally {
10565                 Binder.restoreCallingIdentity(ident);
10566             }
10567         }
10568     }
10569
10570     @Override
10571     public void swapDockedAndFullscreenStack() throws RemoteException {
10572         enforceCallingPermission(MANAGE_ACTIVITY_STACKS, "swapDockedAndFullscreenStack()");
10573         synchronized (this) {
10574             long ident = Binder.clearCallingIdentity();
10575             try {
10576                 final ActivityStack fullscreenStack = mStackSupervisor.getStack(
10577                         FULLSCREEN_WORKSPACE_STACK_ID);
10578                 final TaskRecord topTask = fullscreenStack != null ? fullscreenStack.topTask()
10579                         : null;
10580                 final ActivityStack dockedStack = mStackSupervisor.getStack(DOCKED_STACK_ID);
10581                 final ArrayList<TaskRecord> tasks = dockedStack != null ? dockedStack.getAllTasks()
10582                         : null;
10583                 if (topTask == null || tasks == null || tasks.size() == 0) {
10584                     Slog.w(TAG,
10585                             "Unable to swap tasks, either docked or fullscreen stack is empty.");
10586                     return;
10587                 }
10588
10589                 // TODO: App transition
10590                 mWindowManager.prepareAppTransition(TRANSIT_ACTIVITY_RELAUNCH, false);
10591
10592                 // Defer the resume until we move all the docked tasks to the fullscreen stack below
10593                 topTask.reparent(DOCKED_STACK_ID, ON_TOP, REPARENT_KEEP_STACK_AT_FRONT, ANIMATE,
10594                         DEFER_RESUME, "swapDockedAndFullscreenStack - DOCKED_STACK");
10595                 final int size = tasks.size();
10596                 for (int i = 0; i < size; i++) {
10597                     final int id = tasks.get(i).taskId;
10598                     if (id == topTask.taskId) {
10599                         continue;
10600                     }
10601
10602                     // Defer the resume until after all the tasks have been moved
10603                     tasks.get(i).reparent(FULLSCREEN_WORKSPACE_STACK_ID, ON_TOP,
10604                             REPARENT_KEEP_STACK_AT_FRONT, ANIMATE, DEFER_RESUME,
10605                             "swapDockedAndFullscreenStack - FULLSCREEN_STACK");
10606                 }
10607
10608                 // Because we deferred the resume to avoid conflicts with stack switches while
10609                 // resuming, we need to do it after all the tasks are moved.
10610                 mStackSupervisor.ensureActivitiesVisibleLocked(null, 0, !PRESERVE_WINDOWS);
10611                 mStackSupervisor.resumeFocusedStackTopActivityLocked();
10612
10613                 mWindowManager.executeAppTransition();
10614             } finally {
10615                 Binder.restoreCallingIdentity(ident);
10616             }
10617         }
10618     }
10619
10620     /**
10621      * Moves the input task to the docked stack.
10622      *
10623      * @param taskId Id of task to move.
10624      * @param createMode The mode the docked stack should be created in if it doesn't exist
10625      *                   already. See
10626      *                   {@link android.app.ActivityManager#DOCKED_STACK_CREATE_MODE_TOP_OR_LEFT}
10627      *                   and
10628      *                   {@link android.app.ActivityManager#DOCKED_STACK_CREATE_MODE_BOTTOM_OR_RIGHT}
10629      * @param toTop If the task and stack should be moved to the top.
10630      * @param animate Whether we should play an animation for the moving the task
10631      * @param initialBounds If the docked stack gets created, it will use these bounds for the
10632      *                      docked stack. Pass {@code null} to use default bounds.
10633      */
10634     @Override
10635     public boolean moveTaskToDockedStack(int taskId, int createMode, boolean toTop, boolean animate,
10636             Rect initialBounds) {
10637         enforceCallingPermission(MANAGE_ACTIVITY_STACKS, "moveTaskToDockedStack()");
10638         synchronized (this) {
10639             long ident = Binder.clearCallingIdentity();
10640             try {
10641                 final TaskRecord task = mStackSupervisor.anyTaskForIdLocked(taskId);
10642                 if (task == null) {
10643                     Slog.w(TAG, "moveTaskToDockedStack: No task for id=" + taskId);
10644                     return false;
10645                 }
10646
10647                 if (DEBUG_STACK) Slog.d(TAG_STACK, "moveTaskToDockedStack: moving task=" + taskId
10648                         + " to createMode=" + createMode + " toTop=" + toTop);
10649                 mWindowManager.setDockedStackCreateState(createMode, initialBounds);
10650
10651                 // Defer resuming until we move the home stack to the front below
10652                 final boolean moved = task.reparent(DOCKED_STACK_ID, toTop,
10653                         REPARENT_KEEP_STACK_AT_FRONT, animate, !DEFER_RESUME,
10654                         "moveTaskToDockedStack");
10655                 if (moved) {
10656                     mStackSupervisor.ensureActivitiesVisibleLocked(null, 0, !PRESERVE_WINDOWS);
10657                 }
10658                 return moved;
10659             } finally {
10660                 Binder.restoreCallingIdentity(ident);
10661             }
10662         }
10663     }
10664
10665     /**
10666      * Moves the top activity in the input stackId to the pinned stack.
10667      *
10668      * @param stackId Id of stack to move the top activity to pinned stack.
10669      * @param bounds Bounds to use for pinned stack.
10670      *
10671      * @return True if the top activity of the input stack was successfully moved to the pinned
10672      *          stack.
10673      */
10674     @Override
10675     public boolean moveTopActivityToPinnedStack(int stackId, Rect bounds) {
10676         enforceCallingPermission(MANAGE_ACTIVITY_STACKS, "moveTopActivityToPinnedStack()");
10677         synchronized (this) {
10678             if (!mSupportsPictureInPicture) {
10679                 throw new IllegalStateException("moveTopActivityToPinnedStack:"
10680                         + "Device doesn't support picture-in-picture mode");
10681             }
10682
10683             long ident = Binder.clearCallingIdentity();
10684             try {
10685                 return mStackSupervisor.moveTopStackActivityToPinnedStackLocked(stackId, bounds);
10686             } finally {
10687                 Binder.restoreCallingIdentity(ident);
10688             }
10689         }
10690     }
10691
10692     @Override
10693     public void resizeStack(int stackId, Rect destBounds, boolean allowResizeInDockedMode,
10694             boolean preserveWindows, boolean animate, int animationDuration) {
10695         enforceCallingPermission(MANAGE_ACTIVITY_STACKS, "resizeStack()");
10696         long ident = Binder.clearCallingIdentity();
10697         try {
10698             synchronized (this) {
10699                 if (animate) {
10700                     if (stackId == PINNED_STACK_ID) {
10701                         final PinnedActivityStack pinnedStack =
10702                                 mStackSupervisor.getStack(PINNED_STACK_ID);
10703                         if (pinnedStack != null) {
10704                             pinnedStack.animateResizePinnedStack(null /* sourceHintBounds */,
10705                                     destBounds, animationDuration, false /* fromFullscreen */);
10706                         }
10707                     } else {
10708                         throw new IllegalArgumentException("Stack: " + stackId
10709                                 + " doesn't support animated resize.");
10710                     }
10711                 } else {
10712                     mStackSupervisor.resizeStackLocked(stackId, destBounds, null /* tempTaskBounds */,
10713                             null /* tempTaskInsetBounds */, preserveWindows,
10714                             allowResizeInDockedMode, !DEFER_RESUME);
10715                 }
10716             }
10717         } finally {
10718             Binder.restoreCallingIdentity(ident);
10719         }
10720     }
10721
10722     @Override
10723     public void resizeDockedStack(Rect dockedBounds, Rect tempDockedTaskBounds,
10724             Rect tempDockedTaskInsetBounds,
10725             Rect tempOtherTaskBounds, Rect tempOtherTaskInsetBounds) {
10726         enforceCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS,
10727                 "resizeDockedStack()");
10728         long ident = Binder.clearCallingIdentity();
10729         try {
10730             synchronized (this) {
10731                 mStackSupervisor.resizeDockedStackLocked(dockedBounds, tempDockedTaskBounds,
10732                         tempDockedTaskInsetBounds, tempOtherTaskBounds, tempOtherTaskInsetBounds,
10733                         PRESERVE_WINDOWS);
10734             }
10735         } finally {
10736             Binder.restoreCallingIdentity(ident);
10737         }
10738     }
10739
10740     @Override
10741     public void resizePinnedStack(Rect pinnedBounds, Rect tempPinnedTaskBounds) {
10742         enforceCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS,
10743                 "resizePinnedStack()");
10744         final long ident = Binder.clearCallingIdentity();
10745         try {
10746             synchronized (this) {
10747                 mStackSupervisor.resizePinnedStackLocked(pinnedBounds, tempPinnedTaskBounds);
10748             }
10749         } finally {
10750             Binder.restoreCallingIdentity(ident);
10751         }
10752     }
10753
10754     /**
10755      * Try to place task to provided position. The final position might be different depending on
10756      * current user and stacks state. The task will be moved to target stack if it's currently in
10757      * different stack.
10758      */
10759     @Override
10760     public void positionTaskInStack(int taskId, int stackId, int position) {
10761         enforceCallingPermission(MANAGE_ACTIVITY_STACKS, "positionTaskInStack()");
10762         if (StackId.isHomeOrRecentsStack(stackId)) {
10763             throw new IllegalArgumentException(
10764                     "positionTaskInStack: Attempt to change the position of task "
10765                     + taskId + " in/to home/recents stack");
10766         }
10767         synchronized (this) {
10768             long ident = Binder.clearCallingIdentity();
10769             try {
10770                 if (DEBUG_STACK) Slog.d(TAG_STACK, "positionTaskInStack: positioning task="
10771                         + taskId + " in stackId=" + stackId + " at position=" + position);
10772                 final TaskRecord task = mStackSupervisor.anyTaskForIdLocked(taskId);
10773                 if (task == null) {
10774                     throw new IllegalArgumentException("positionTaskInStack: no task for id="
10775                             + taskId);
10776                 }
10777
10778                 final ActivityStack stack = mStackSupervisor.getStack(stackId, CREATE_IF_NEEDED,
10779                         !ON_TOP);
10780
10781                 // TODO: Have the callers of this API call a separate reparent method if that is
10782                 // what they intended to do vs. having this method also do reparenting.
10783                 if (task.getStack() == stack) {
10784                     // Change position in current stack.
10785                     stack.positionChildAt(task, position);
10786                 } else {
10787                     // Reparent to new stack.
10788                     task.reparent(stackId, position, REPARENT_LEAVE_STACK_IN_PLACE,
10789                             !ANIMATE, !DEFER_RESUME, "positionTaskInStack");
10790                 }
10791             } finally {
10792                 Binder.restoreCallingIdentity(ident);
10793             }
10794         }
10795     }
10796
10797     @Override
10798     public List<StackInfo> getAllStackInfos() {
10799         enforceCallingPermission(MANAGE_ACTIVITY_STACKS, "getAllStackInfos()");
10800         long ident = Binder.clearCallingIdentity();
10801         try {
10802             synchronized (this) {
10803                 return mStackSupervisor.getAllStackInfosLocked();
10804             }
10805         } finally {
10806             Binder.restoreCallingIdentity(ident);
10807         }
10808     }
10809
10810     @Override
10811     public StackInfo getStackInfo(int stackId) {
10812         enforceCallingPermission(MANAGE_ACTIVITY_STACKS, "getStackInfo()");
10813         long ident = Binder.clearCallingIdentity();
10814         try {
10815             synchronized (this) {
10816                 return mStackSupervisor.getStackInfoLocked(stackId);
10817             }
10818         } finally {
10819             Binder.restoreCallingIdentity(ident);
10820         }
10821     }
10822
10823     @Override
10824     public int getTaskForActivity(IBinder token, boolean onlyRoot) {
10825         synchronized(this) {
10826             return ActivityRecord.getTaskForActivityLocked(token, onlyRoot);
10827         }
10828     }
10829
10830     @Override
10831     public void updateDeviceOwner(String packageName) {
10832         final int callingUid = Binder.getCallingUid();
10833         if (callingUid != 0 && callingUid != SYSTEM_UID) {
10834             throw new SecurityException("updateDeviceOwner called from non-system process");
10835         }
10836         synchronized (this) {
10837             mDeviceOwnerName = packageName;
10838         }
10839     }
10840
10841     @Override
10842     public void updateLockTaskPackages(int userId, String[] packages) {
10843         final int callingUid = Binder.getCallingUid();
10844         if (callingUid != 0 && callingUid != SYSTEM_UID) {
10845             enforceCallingPermission(android.Manifest.permission.UPDATE_LOCK_TASK_PACKAGES,
10846                     "updateLockTaskPackages()");
10847         }
10848         synchronized (this) {
10849             if (DEBUG_LOCKTASK) Slog.w(TAG_LOCKTASK, "Whitelisting " + userId + ":" +
10850                     Arrays.toString(packages));
10851             mLockTaskPackages.put(userId, packages);
10852             mStackSupervisor.onLockTaskPackagesUpdatedLocked();
10853         }
10854     }
10855
10856
10857     void startLockTaskModeLocked(TaskRecord task) {
10858         if (DEBUG_LOCKTASK) Slog.w(TAG_LOCKTASK, "startLockTaskModeLocked: " + task);
10859         if (task.mLockTaskAuth == LOCK_TASK_AUTH_DONT_LOCK) {
10860             return;
10861         }
10862
10863         // When a task is locked, dismiss the pinned stack if it exists
10864         final PinnedActivityStack pinnedStack = mStackSupervisor.getStack(
10865                 PINNED_STACK_ID);
10866         if (pinnedStack != null) {
10867             mStackSupervisor.removeStackLocked(PINNED_STACK_ID);
10868         }
10869
10870         // isSystemInitiated is used to distinguish between locked and pinned mode, as pinned mode
10871         // is initiated by system after the pinning request was shown and locked mode is initiated
10872         // by an authorized app directly
10873         final int callingUid = Binder.getCallingUid();
10874         boolean isSystemInitiated = callingUid == SYSTEM_UID;
10875         long ident = Binder.clearCallingIdentity();
10876         try {
10877             if (!isSystemInitiated) {
10878                 task.mLockTaskUid = callingUid;
10879                 if (task.mLockTaskAuth == LOCK_TASK_AUTH_PINNABLE) {
10880                     // startLockTask() called by app and task mode is lockTaskModeDefault.
10881                     if (DEBUG_LOCKTASK) Slog.w(TAG_LOCKTASK, "Mode default, asking user");
10882                     StatusBarManagerInternal statusBarManager =
10883                             LocalServices.getService(StatusBarManagerInternal.class);
10884                     if (statusBarManager != null) {
10885                         statusBarManager.showScreenPinningRequest(task.taskId);
10886                     }
10887                     return;
10888                 }
10889
10890                 final ActivityStack stack = mStackSupervisor.getFocusedStack();
10891                 if (stack == null || task != stack.topTask()) {
10892                     throw new IllegalArgumentException("Invalid task, not in foreground");
10893                 }
10894             }
10895             if (DEBUG_LOCKTASK) Slog.w(TAG_LOCKTASK, isSystemInitiated ? "Locking pinned" :
10896                     "Locking fully");
10897             mStackSupervisor.setLockTaskModeLocked(task, isSystemInitiated ?
10898                     ActivityManager.LOCK_TASK_MODE_PINNED :
10899                     ActivityManager.LOCK_TASK_MODE_LOCKED,
10900                     "startLockTask", true);
10901         } finally {
10902             Binder.restoreCallingIdentity(ident);
10903         }
10904     }
10905
10906     @Override
10907     public void startLockTaskModeById(int taskId) {
10908         synchronized (this) {
10909             final TaskRecord task = mStackSupervisor.anyTaskForIdLocked(taskId);
10910             if (task != null) {
10911                 startLockTaskModeLocked(task);
10912             }
10913         }
10914     }
10915
10916     @Override
10917     public void startLockTaskModeByToken(IBinder token) {
10918         synchronized (this) {
10919             final ActivityRecord r = ActivityRecord.forTokenLocked(token);
10920             if (r == null) {
10921                 return;
10922             }
10923             final TaskRecord task = r.getTask();
10924             if (task != null) {
10925                 startLockTaskModeLocked(task);
10926             }
10927         }
10928     }
10929
10930     @Override
10931     public void startSystemLockTaskMode(int taskId) throws RemoteException {
10932         enforceCallingPermission(MANAGE_ACTIVITY_STACKS, "startSystemLockTaskMode");
10933         // This makes inner call to look as if it was initiated by system.
10934         long ident = Binder.clearCallingIdentity();
10935         try {
10936             synchronized (this) {
10937                 startLockTaskModeById(taskId);
10938             }
10939         } finally {
10940             Binder.restoreCallingIdentity(ident);
10941         }
10942     }
10943
10944     @Override
10945     public void stopLockTaskMode() {
10946         final TaskRecord lockTask = mStackSupervisor.getLockedTaskLocked();
10947         if (lockTask == null) {
10948             // Our work here is done.
10949             return;
10950         }
10951
10952         final int callingUid = Binder.getCallingUid();
10953         final int lockTaskUid = lockTask.mLockTaskUid;
10954         final int lockTaskModeState = mStackSupervisor.getLockTaskModeState();
10955         if (lockTaskModeState == ActivityManager.LOCK_TASK_MODE_NONE) {
10956             // Done.
10957             return;
10958         } else {
10959             // Ensure the same caller for startLockTaskMode and stopLockTaskMode.
10960             // It is possible lockTaskMode was started by the system process because
10961             // android:lockTaskMode is set to a locking value in the application manifest
10962             // instead of the app calling startLockTaskMode. In this case
10963             // {@link TaskRecord.mLockTaskUid} will be 0, so we compare the callingUid to the
10964             // {@link TaskRecord.effectiveUid} instead. Also caller with
10965             // {@link MANAGE_ACTIVITY_STACKS} can stop any lock task.
10966             if (checkCallingPermission(MANAGE_ACTIVITY_STACKS) != PERMISSION_GRANTED
10967                     && callingUid != lockTaskUid
10968                     && (lockTaskUid != 0 || callingUid != lockTask.effectiveUid)) {
10969                 throw new SecurityException("Invalid uid, expected " + lockTaskUid
10970                         + " callingUid=" + callingUid + " effectiveUid=" + lockTask.effectiveUid);
10971             }
10972         }
10973         long ident = Binder.clearCallingIdentity();
10974         try {
10975             Log.d(TAG, "stopLockTaskMode");
10976             // Stop lock task
10977             synchronized (this) {
10978                 mStackSupervisor.setLockTaskModeLocked(null, ActivityManager.LOCK_TASK_MODE_NONE,
10979                         "stopLockTask", true);
10980             }
10981             TelecomManager tm = (TelecomManager) mContext.getSystemService(Context.TELECOM_SERVICE);
10982             if (tm != null) {
10983                 tm.showInCallScreen(false);
10984             }
10985         } finally {
10986             Binder.restoreCallingIdentity(ident);
10987         }
10988     }
10989
10990     /**
10991      * This API should be called by SystemUI only when user perform certain action to dismiss
10992      * lock task mode. We should only dismiss pinned lock task mode in this case.
10993      */
10994     @Override
10995     public void stopSystemLockTaskMode() throws RemoteException {
10996         if (mStackSupervisor.getLockTaskModeState() == ActivityManager.LOCK_TASK_MODE_PINNED) {
10997             stopLockTaskMode();
10998         } else {
10999             mStackSupervisor.showLockTaskToast();
11000         }
11001     }
11002
11003     @Override
11004     public boolean isInLockTaskMode() {
11005         return getLockTaskModeState() != ActivityManager.LOCK_TASK_MODE_NONE;
11006     }
11007
11008     @Override
11009     public int getLockTaskModeState() {
11010         synchronized (this) {
11011             return mStackSupervisor.getLockTaskModeState();
11012         }
11013     }
11014
11015     @Override
11016     public void showLockTaskEscapeMessage(IBinder token) {
11017         synchronized (this) {
11018             final ActivityRecord r = ActivityRecord.forTokenLocked(token);
11019             if (r == null) {
11020                 return;
11021             }
11022             mStackSupervisor.showLockTaskEscapeMessageLocked(r.getTask());
11023         }
11024     }
11025
11026     @Override
11027     public void setDisablePreviewScreenshots(IBinder token, boolean disable)
11028             throws RemoteException {
11029         synchronized (this) {
11030             final ActivityRecord r = ActivityRecord.isInStackLocked(token);
11031             if (r == null) {
11032                 Slog.w(TAG, "setDisablePreviewScreenshots: Unable to find activity for token="
11033                         + token);
11034                 return;
11035             }
11036             final long origId = Binder.clearCallingIdentity();
11037             try {
11038                 r.setDisablePreviewScreenshots(disable);
11039             } finally {
11040                 Binder.restoreCallingIdentity(origId);
11041             }
11042         }
11043     }
11044
11045     // =========================================================
11046     // CONTENT PROVIDERS
11047     // =========================================================
11048
11049     private final List<ProviderInfo> generateApplicationProvidersLocked(ProcessRecord app) {
11050         List<ProviderInfo> providers = null;
11051         try {
11052             providers = AppGlobals.getPackageManager()
11053                     .queryContentProviders(app.processName, app.uid,
11054                             STOCK_PM_FLAGS | PackageManager.GET_URI_PERMISSION_PATTERNS
11055                                     | MATCH_DEBUG_TRIAGED_MISSING, /*metadastaKey=*/ null)
11056                     .getList();
11057         } catch (RemoteException ex) {
11058         }
11059         if (DEBUG_MU) Slog.v(TAG_MU,
11060                 "generateApplicationProvidersLocked, app.info.uid = " + app.uid);
11061         int userId = app.userId;
11062         if (providers != null) {
11063             int N = providers.size();
11064             app.pubProviders.ensureCapacity(N + app.pubProviders.size());
11065             for (int i=0; i<N; i++) {
11066                 // TODO: keep logic in sync with installEncryptionUnawareProviders
11067                 ProviderInfo cpi =
11068                     (ProviderInfo)providers.get(i);
11069                 boolean singleton = isSingleton(cpi.processName, cpi.applicationInfo,
11070                         cpi.name, cpi.flags);
11071                 if (singleton && UserHandle.getUserId(app.uid) != UserHandle.USER_SYSTEM) {
11072                     // This is a singleton provider, but a user besides the
11073                     // default user is asking to initialize a process it runs
11074                     // in...  well, no, it doesn't actually run in this process,
11075                     // it runs in the process of the default user.  Get rid of it.
11076                     providers.remove(i);
11077                     N--;
11078                     i--;
11079                     continue;
11080                 }
11081
11082                 ComponentName comp = new ComponentName(cpi.packageName, cpi.name);
11083                 ContentProviderRecord cpr = mProviderMap.getProviderByClass(comp, userId);
11084                 if (cpr == null) {
11085                     cpr = new ContentProviderRecord(this, cpi, app.info, comp, singleton);
11086                     mProviderMap.putProviderByClass(comp, cpr);
11087                 }
11088                 if (DEBUG_MU) Slog.v(TAG_MU,
11089                         "generateApplicationProvidersLocked, cpi.uid = " + cpr.uid);
11090                 app.pubProviders.put(cpi.name, cpr);
11091                 if (!cpi.multiprocess || !"android".equals(cpi.packageName)) {
11092                     // Don't add this if it is a platform component that is marked
11093                     // to run in multiple processes, because this is actually
11094                     // part of the framework so doesn't make sense to track as a
11095                     // separate apk in the process.
11096                     app.addPackage(cpi.applicationInfo.packageName, cpi.applicationInfo.versionCode,
11097                             mProcessStats);
11098                 }
11099                 notifyPackageUse(cpi.applicationInfo.packageName,
11100                                  PackageManager.NOTIFY_PACKAGE_USE_CONTENT_PROVIDER);
11101             }
11102         }
11103         return providers;
11104     }
11105
11106     /**
11107      * Check if the calling UID has a possible chance at accessing the provider
11108      * at the given authority and user.
11109      */
11110     public String checkContentProviderAccess(String authority, int userId) {
11111         if (userId == UserHandle.USER_ALL) {
11112             mContext.enforceCallingOrSelfPermission(
11113                     Manifest.permission.INTERACT_ACROSS_USERS_FULL, TAG);
11114             userId = UserHandle.getCallingUserId();
11115         }
11116
11117         ProviderInfo cpi = null;
11118         try {
11119             cpi = AppGlobals.getPackageManager().resolveContentProvider(authority,
11120                     STOCK_PM_FLAGS | PackageManager.GET_URI_PERMISSION_PATTERNS
11121                             | PackageManager.MATCH_DISABLED_COMPONENTS
11122                             | PackageManager.MATCH_DIRECT_BOOT_AWARE
11123                             | PackageManager.MATCH_DIRECT_BOOT_UNAWARE,
11124                     userId);
11125         } catch (RemoteException ignored) {
11126         }
11127         if (cpi == null) {
11128             return "Failed to find provider " + authority + " for user " + userId
11129                     + "; expected to find a valid ContentProvider for this authority";
11130         }
11131
11132         ProcessRecord r = null;
11133         synchronized (mPidsSelfLocked) {
11134             r = mPidsSelfLocked.get(Binder.getCallingPid());
11135         }
11136         if (r == null) {
11137             return "Failed to find PID " + Binder.getCallingPid();
11138         }
11139
11140         synchronized (this) {
11141             return checkContentProviderPermissionLocked(cpi, r, userId, true);
11142         }
11143     }
11144
11145     /**
11146      * Check if {@link ProcessRecord} has a possible chance at accessing the
11147      * given {@link ProviderInfo}. Final permission checking is always done
11148      * in {@link ContentProvider}.
11149      */
11150     private final String checkContentProviderPermissionLocked(
11151             ProviderInfo cpi, ProcessRecord r, int userId, boolean checkUser) {
11152         final int callingPid = (r != null) ? r.pid : Binder.getCallingPid();
11153         final int callingUid = (r != null) ? r.uid : Binder.getCallingUid();
11154         boolean checkedGrants = false;
11155         if (checkUser) {
11156             // Looking for cross-user grants before enforcing the typical cross-users permissions
11157             int tmpTargetUserId = mUserController.unsafeConvertIncomingUserLocked(userId);
11158             if (tmpTargetUserId != UserHandle.getUserId(callingUid)) {
11159                 if (checkAuthorityGrants(callingUid, cpi, tmpTargetUserId, checkUser)) {
11160                     return null;
11161                 }
11162                 checkedGrants = true;
11163             }
11164             userId = mUserController.handleIncomingUser(callingPid, callingUid, userId, false,
11165                     ALLOW_NON_FULL, "checkContentProviderPermissionLocked " + cpi.authority, null);
11166             if (userId != tmpTargetUserId) {
11167                 // When we actually went to determine the final targer user ID, this ended
11168                 // up different than our initial check for the authority.  This is because
11169                 // they had asked for USER_CURRENT_OR_SELF and we ended up switching to
11170                 // SELF.  So we need to re-check the grants again.
11171                 checkedGrants = false;
11172             }
11173         }
11174         if (checkComponentPermission(cpi.readPermission, callingPid, callingUid,
11175                 cpi.applicationInfo.uid, cpi.exported)
11176                 == PackageManager.PERMISSION_GRANTED) {
11177             return null;
11178         }
11179         if (checkComponentPermission(cpi.writePermission, callingPid, callingUid,
11180                 cpi.applicationInfo.uid, cpi.exported)
11181                 == PackageManager.PERMISSION_GRANTED) {
11182             return null;
11183         }
11184
11185         PathPermission[] pps = cpi.pathPermissions;
11186         if (pps != null) {
11187             int i = pps.length;
11188             while (i > 0) {
11189                 i--;
11190                 PathPermission pp = pps[i];
11191                 String pprperm = pp.getReadPermission();
11192                 if (pprperm != null && checkComponentPermission(pprperm, callingPid, callingUid,
11193                         cpi.applicationInfo.uid, cpi.exported)
11194                         == PackageManager.PERMISSION_GRANTED) {
11195                     return null;
11196                 }
11197                 String ppwperm = pp.getWritePermission();
11198                 if (ppwperm != null && checkComponentPermission(ppwperm, callingPid, callingUid,
11199                         cpi.applicationInfo.uid, cpi.exported)
11200                         == PackageManager.PERMISSION_GRANTED) {
11201                     return null;
11202                 }
11203             }
11204         }
11205         if (!checkedGrants && checkAuthorityGrants(callingUid, cpi, userId, checkUser)) {
11206             return null;
11207         }
11208
11209         final String suffix;
11210         if (!cpi.exported) {
11211             suffix = " that is not exported from UID " + cpi.applicationInfo.uid;
11212         } else if (android.Manifest.permission.MANAGE_DOCUMENTS.equals(cpi.readPermission)) {
11213             suffix = " requires that you obtain access using ACTION_OPEN_DOCUMENT or related APIs";
11214         } else {
11215             suffix = " requires " + cpi.readPermission + " or " + cpi.writePermission;
11216         }
11217         final String msg = "Permission Denial: opening provider " + cpi.name
11218                 + " from " + (r != null ? r : "(null)") + " (pid=" + callingPid
11219                 + ", uid=" + callingUid + ")" + suffix;
11220         Slog.w(TAG, msg);
11221         return msg;
11222     }
11223
11224     /**
11225      * Returns if the ContentProvider has granted a uri to callingUid
11226      */
11227     boolean checkAuthorityGrants(int callingUid, ProviderInfo cpi, int userId, boolean checkUser) {
11228         final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.get(callingUid);
11229         if (perms != null) {
11230             for (int i=perms.size()-1; i>=0; i--) {
11231                 GrantUri grantUri = perms.keyAt(i);
11232                 if (grantUri.sourceUserId == userId || !checkUser) {
11233                     if (matchesProvider(grantUri.uri, cpi)) {
11234                         return true;
11235                     }
11236                 }
11237             }
11238         }
11239         return false;
11240     }
11241
11242     /**
11243      * Returns true if the uri authority is one of the authorities specified in the provider.
11244      */
11245     boolean matchesProvider(Uri uri, ProviderInfo cpi) {
11246         String uriAuth = uri.getAuthority();
11247         String cpiAuth = cpi.authority;
11248         if (cpiAuth.indexOf(';') == -1) {
11249             return cpiAuth.equals(uriAuth);
11250         }
11251         String[] cpiAuths = cpiAuth.split(";");
11252         int length = cpiAuths.length;
11253         for (int i = 0; i < length; i++) {
11254             if (cpiAuths[i].equals(uriAuth)) return true;
11255         }
11256         return false;
11257     }
11258
11259     ContentProviderConnection incProviderCountLocked(ProcessRecord r,
11260             final ContentProviderRecord cpr, IBinder externalProcessToken, boolean stable) {
11261         if (r != null) {
11262             for (int i=0; i<r.conProviders.size(); i++) {
11263                 ContentProviderConnection conn = r.conProviders.get(i);
11264                 if (conn.provider == cpr) {
11265                     if (DEBUG_PROVIDER) Slog.v(TAG_PROVIDER,
11266                             "Adding provider requested by "
11267                             + r.processName + " from process "
11268                             + cpr.info.processName + ": " + cpr.name.flattenToShortString()
11269                             + " scnt=" + conn.stableCount + " uscnt=" + conn.unstableCount);
11270                     if (stable) {
11271                         conn.stableCount++;
11272                         conn.numStableIncs++;
11273                     } else {
11274                         conn.unstableCount++;
11275                         conn.numUnstableIncs++;
11276                     }
11277                     return conn;
11278                 }
11279             }
11280             ContentProviderConnection conn = new ContentProviderConnection(cpr, r);
11281             if (stable) {
11282                 conn.stableCount = 1;
11283                 conn.numStableIncs = 1;
11284             } else {
11285                 conn.unstableCount = 1;
11286                 conn.numUnstableIncs = 1;
11287             }
11288             cpr.connections.add(conn);
11289             r.conProviders.add(conn);
11290             startAssociationLocked(r.uid, r.processName, r.curProcState,
11291                     cpr.uid, cpr.name, cpr.info.processName);
11292             return conn;
11293         }
11294         cpr.addExternalProcessHandleLocked(externalProcessToken);
11295         return null;
11296     }
11297
11298     boolean decProviderCountLocked(ContentProviderConnection conn,
11299             ContentProviderRecord cpr, IBinder externalProcessToken, boolean stable) {
11300         if (conn != null) {
11301             cpr = conn.provider;
11302             if (DEBUG_PROVIDER) Slog.v(TAG_PROVIDER,
11303                     "Removing provider requested by "
11304                     + conn.client.processName + " from process "
11305                     + cpr.info.processName + ": " + cpr.name.flattenToShortString()
11306                     + " scnt=" + conn.stableCount + " uscnt=" + conn.unstableCount);
11307             if (stable) {
11308                 conn.stableCount--;
11309             } else {
11310                 conn.unstableCount--;
11311             }
11312             if (conn.stableCount == 0 && conn.unstableCount == 0) {
11313                 cpr.connections.remove(conn);
11314                 conn.client.conProviders.remove(conn);
11315                 if (conn.client.setProcState < ActivityManager.PROCESS_STATE_LAST_ACTIVITY) {
11316                     // The client is more important than last activity -- note the time this
11317                     // is happening, so we keep the old provider process around a bit as last
11318                     // activity to avoid thrashing it.
11319                     if (cpr.proc != null) {
11320                         cpr.proc.lastProviderTime = SystemClock.uptimeMillis();
11321                     }
11322                 }
11323                 stopAssociationLocked(conn.client.uid, conn.client.processName, cpr.uid, cpr.name);
11324                 return true;
11325             }
11326             return false;
11327         }
11328         cpr.removeExternalProcessHandleLocked(externalProcessToken);
11329         return false;
11330     }
11331
11332     private void checkTime(long startTime, String where) {
11333         long now = SystemClock.uptimeMillis();
11334         if ((now-startTime) > 50) {
11335             // If we are taking more than 50ms, log about it.
11336             Slog.w(TAG, "Slow operation: " + (now-startTime) + "ms so far, now at " + where);
11337         }
11338     }
11339
11340     private static final int[] PROCESS_STATE_STATS_FORMAT = new int[] {
11341             PROC_SPACE_TERM,
11342             PROC_SPACE_TERM|PROC_PARENS,
11343             PROC_SPACE_TERM|PROC_CHAR|PROC_OUT_LONG,        // 3: process state
11344     };
11345
11346     private final long[] mProcessStateStatsLongs = new long[1];
11347
11348     boolean isProcessAliveLocked(ProcessRecord proc) {
11349         if (proc.procStatFile == null) {
11350             proc.procStatFile = "/proc/" + proc.pid + "/stat";
11351         }
11352         mProcessStateStatsLongs[0] = 0;
11353         if (!readProcFile(proc.procStatFile, PROCESS_STATE_STATS_FORMAT, null,
11354                 mProcessStateStatsLongs, null)) {
11355             if (DEBUG_OOM_ADJ) Slog.d(TAG, "UNABLE TO RETRIEVE STATE FOR " + proc.procStatFile);
11356             return false;
11357         }
11358         final long state = mProcessStateStatsLongs[0];
11359         if (DEBUG_OOM_ADJ) Slog.d(TAG, "RETRIEVED STATE FOR " + proc.procStatFile + ": "
11360                 + (char)state);
11361         return state != 'Z' && state != 'X' && state != 'x' && state != 'K';
11362     }
11363
11364     private ContentProviderHolder getContentProviderImpl(IApplicationThread caller,
11365             String name, IBinder token, boolean stable, int userId) {
11366         ContentProviderRecord cpr;
11367         ContentProviderConnection conn = null;
11368         ProviderInfo cpi = null;
11369
11370         synchronized(this) {
11371             long startTime = SystemClock.uptimeMillis();
11372
11373             ProcessRecord r = null;
11374             if (caller != null) {
11375                 r = getRecordForAppLocked(caller);
11376                 if (r == null) {
11377                     throw new SecurityException(
11378                             "Unable to find app for caller " + caller
11379                           + " (pid=" + Binder.getCallingPid()
11380                           + ") when getting content provider " + name);
11381                 }
11382             }
11383
11384             boolean checkCrossUser = true;
11385
11386             checkTime(startTime, "getContentProviderImpl: getProviderByName");
11387
11388             // First check if this content provider has been published...
11389             cpr = mProviderMap.getProviderByName(name, userId);
11390             // If that didn't work, check if it exists for user 0 and then
11391             // verify that it's a singleton provider before using it.
11392             if (cpr == null && userId != UserHandle.USER_SYSTEM) {
11393                 cpr = mProviderMap.getProviderByName(name, UserHandle.USER_SYSTEM);
11394                 if (cpr != null) {
11395                     cpi = cpr.info;
11396                     if (isSingleton(cpi.processName, cpi.applicationInfo,
11397                             cpi.name, cpi.flags)
11398                             && isValidSingletonCall(r.uid, cpi.applicationInfo.uid)) {
11399                         userId = UserHandle.USER_SYSTEM;
11400                         checkCrossUser = false;
11401                     } else {
11402                         cpr = null;
11403                         cpi = null;
11404                     }
11405                 }
11406             }
11407
11408             boolean providerRunning = cpr != null && cpr.proc != null && !cpr.proc.killed;
11409             if (providerRunning) {
11410                 cpi = cpr.info;
11411                 String msg;
11412                 checkTime(startTime, "getContentProviderImpl: before checkContentProviderPermission");
11413                 if ((msg = checkContentProviderPermissionLocked(cpi, r, userId, checkCrossUser))
11414                         != null) {
11415                     throw new SecurityException(msg);
11416                 }
11417                 checkTime(startTime, "getContentProviderImpl: after checkContentProviderPermission");
11418
11419                 if (r != null && cpr.canRunHere(r)) {
11420                     // This provider has been published or is in the process
11421                     // of being published...  but it is also allowed to run
11422                     // in the caller's process, so don't make a connection
11423                     // and just let the caller instantiate its own instance.
11424                     ContentProviderHolder holder = cpr.newHolder(null);
11425                     // don't give caller the provider object, it needs
11426                     // to make its own.
11427                     holder.provider = null;
11428                     return holder;
11429                 }
11430                 // Don't expose providers between normal apps and instant apps
11431                 try {
11432                     if (AppGlobals.getPackageManager()
11433                             .resolveContentProvider(name, 0 /*flags*/, userId) == null) {
11434                         return null;
11435                     }
11436                 } catch (RemoteException e) {
11437                 }
11438
11439                 final long origId = Binder.clearCallingIdentity();
11440
11441                 checkTime(startTime, "getContentProviderImpl: incProviderCountLocked");
11442
11443                 // In this case the provider instance already exists, so we can
11444                 // return it right away.
11445                 conn = incProviderCountLocked(r, cpr, token, stable);
11446                 if (conn != null && (conn.stableCount+conn.unstableCount) == 1) {
11447                     if (cpr.proc != null && r.setAdj <= ProcessList.PERCEPTIBLE_APP_ADJ) {
11448                         // If this is a perceptible app accessing the provider,
11449                         // make sure to count it as being accessed and thus
11450                         // back up on the LRU list.  This is good because
11451                         // content providers are often expensive to start.
11452                         checkTime(startTime, "getContentProviderImpl: before updateLruProcess");
11453                         updateLruProcessLocked(cpr.proc, false, null);
11454                         checkTime(startTime, "getContentProviderImpl: after updateLruProcess");
11455                     }
11456                 }
11457
11458                 checkTime(startTime, "getContentProviderImpl: before updateOomAdj");
11459                 final int verifiedAdj = cpr.proc.verifiedAdj;
11460                 boolean success = updateOomAdjLocked(cpr.proc, true);
11461                 // XXX things have changed so updateOomAdjLocked doesn't actually tell us
11462                 // if the process has been successfully adjusted.  So to reduce races with
11463                 // it, we will check whether the process still exists.  Note that this doesn't
11464                 // completely get rid of races with LMK killing the process, but should make
11465                 // them much smaller.
11466                 if (success && verifiedAdj != cpr.proc.setAdj && !isProcessAliveLocked(cpr.proc)) {
11467                     success = false;
11468                 }
11469                 maybeUpdateProviderUsageStatsLocked(r, cpr.info.packageName, name);
11470                 checkTime(startTime, "getContentProviderImpl: after updateOomAdj");
11471                 if (DEBUG_PROVIDER) Slog.i(TAG_PROVIDER, "Adjust success: " + success);
11472                 // NOTE: there is still a race here where a signal could be
11473                 // pending on the process even though we managed to update its
11474                 // adj level.  Not sure what to do about this, but at least
11475                 // the race is now smaller.
11476                 if (!success) {
11477                     // Uh oh...  it looks like the provider's process
11478                     // has been killed on us.  We need to wait for a new
11479                     // process to be started, and make sure its death
11480                     // doesn't kill our process.
11481                     Slog.i(TAG, "Existing provider " + cpr.name.flattenToShortString()
11482                             + " is crashing; detaching " + r);
11483                     boolean lastRef = decProviderCountLocked(conn, cpr, token, stable);
11484                     checkTime(startTime, "getContentProviderImpl: before appDied");
11485                     appDiedLocked(cpr.proc);
11486                     checkTime(startTime, "getContentProviderImpl: after appDied");
11487                     if (!lastRef) {
11488                         // This wasn't the last ref our process had on
11489                         // the provider...  we have now been killed, bail.
11490                         return null;
11491                     }
11492                     providerRunning = false;
11493                     conn = null;
11494                 } else {
11495                     cpr.proc.verifiedAdj = cpr.proc.setAdj;
11496                 }
11497
11498                 Binder.restoreCallingIdentity(origId);
11499             }
11500
11501             if (!providerRunning) {
11502                 try {
11503                     checkTime(startTime, "getContentProviderImpl: before resolveContentProvider");
11504                     cpi = AppGlobals.getPackageManager().
11505                         resolveContentProvider(name,
11506                             STOCK_PM_FLAGS | PackageManager.GET_URI_PERMISSION_PATTERNS, userId);
11507                     checkTime(startTime, "getContentProviderImpl: after resolveContentProvider");
11508                 } catch (RemoteException ex) {
11509                 }
11510                 if (cpi == null) {
11511                     return null;
11512                 }
11513                 // If the provider is a singleton AND
11514                 // (it's a call within the same user || the provider is a
11515                 // privileged app)
11516                 // Then allow connecting to the singleton provider
11517                 boolean singleton = isSingleton(cpi.processName, cpi.applicationInfo,
11518                         cpi.name, cpi.flags)
11519                         && isValidSingletonCall(r.uid, cpi.applicationInfo.uid);
11520                 if (singleton) {
11521                     userId = UserHandle.USER_SYSTEM;
11522                 }
11523                 cpi.applicationInfo = getAppInfoForUser(cpi.applicationInfo, userId);
11524                 checkTime(startTime, "getContentProviderImpl: got app info for user");
11525
11526                 String msg;
11527                 checkTime(startTime, "getContentProviderImpl: before checkContentProviderPermission");
11528                 if ((msg = checkContentProviderPermissionLocked(cpi, r, userId, !singleton))
11529                         != null) {
11530                     throw new SecurityException(msg);
11531                 }
11532                 checkTime(startTime, "getContentProviderImpl: after checkContentProviderPermission");
11533
11534                 if (!mProcessesReady
11535                         && !cpi.processName.equals("system")) {
11536                     // If this content provider does not run in the system
11537                     // process, and the system is not yet ready to run other
11538                     // processes, then fail fast instead of hanging.
11539                     throw new IllegalArgumentException(
11540                             "Attempt to launch content provider before system ready");
11541                 }
11542
11543                 // Make sure that the user who owns this provider is running.  If not,
11544                 // we don't want to allow it to run.
11545                 if (!mUserController.isUserRunningLocked(userId, 0)) {
11546                     Slog.w(TAG, "Unable to launch app "
11547                             + cpi.applicationInfo.packageName + "/"
11548                             + cpi.applicationInfo.uid + " for provider "
11549                             + name + ": user " + userId + " is stopped");
11550                     return null;
11551                 }
11552
11553                 ComponentName comp = new ComponentName(cpi.packageName, cpi.name);
11554                 checkTime(startTime, "getContentProviderImpl: before getProviderByClass");
11555                 cpr = mProviderMap.getProviderByClass(comp, userId);
11556                 checkTime(startTime, "getContentProviderImpl: after getProviderByClass");
11557                 final boolean firstClass = cpr == null;
11558                 if (firstClass) {
11559                     final long ident = Binder.clearCallingIdentity();
11560
11561                     // If permissions need a review before any of the app components can run,
11562                     // we return no provider and launch a review activity if the calling app
11563                     // is in the foreground.
11564                     if (mPermissionReviewRequired) {
11565                         if (!requestTargetProviderPermissionsReviewIfNeededLocked(cpi, r, userId)) {
11566                             return null;
11567                         }
11568                     }
11569
11570                     try {
11571                         checkTime(startTime, "getContentProviderImpl: before getApplicationInfo");
11572                         ApplicationInfo ai =
11573                             AppGlobals.getPackageManager().
11574                                 getApplicationInfo(
11575                                         cpi.applicationInfo.packageName,
11576                                         STOCK_PM_FLAGS, userId);
11577                         checkTime(startTime, "getContentProviderImpl: after getApplicationInfo");
11578                         if (ai == null) {
11579                             Slog.w(TAG, "No package info for content provider "
11580                                     + cpi.name);
11581                             return null;
11582                         }
11583                         ai = getAppInfoForUser(ai, userId);
11584                         cpr = new ContentProviderRecord(this, cpi, ai, comp, singleton);
11585                     } catch (RemoteException ex) {
11586                         // pm is in same process, this will never happen.
11587                     } finally {
11588                         Binder.restoreCallingIdentity(ident);
11589                     }
11590                 }
11591
11592                 checkTime(startTime, "getContentProviderImpl: now have ContentProviderRecord");
11593
11594                 if (r != null && cpr.canRunHere(r)) {
11595                     // If this is a multiprocess provider, then just return its
11596                     // info and allow the caller to instantiate it.  Only do
11597                     // this if the provider is the same user as the caller's
11598                     // process, or can run as root (so can be in any process).
11599                     return cpr.newHolder(null);
11600                 }
11601
11602                 if (DEBUG_PROVIDER) Slog.w(TAG_PROVIDER, "LAUNCHING REMOTE PROVIDER (myuid "
11603                             + (r != null ? r.uid : null) + " pruid " + cpr.appInfo.uid + "): "
11604                             + cpr.info.name + " callers=" + Debug.getCallers(6));
11605
11606                 // This is single process, and our app is now connecting to it.
11607                 // See if we are already in the process of launching this
11608                 // provider.
11609                 final int N = mLaunchingProviders.size();
11610                 int i;
11611                 for (i = 0; i < N; i++) {
11612                     if (mLaunchingProviders.get(i) == cpr) {
11613                         break;
11614                     }
11615                 }
11616
11617                 // If the provider is not already being launched, then get it
11618                 // started.
11619                 if (i >= N) {
11620                     final long origId = Binder.clearCallingIdentity();
11621
11622                     try {
11623                         // Content provider is now in use, its package can't be stopped.
11624                         try {
11625                             checkTime(startTime, "getContentProviderImpl: before set stopped state");
11626                             AppGlobals.getPackageManager().setPackageStoppedState(
11627                                     cpr.appInfo.packageName, false, userId);
11628                             checkTime(startTime, "getContentProviderImpl: after set stopped state");
11629                         } catch (RemoteException e) {
11630                         } catch (IllegalArgumentException e) {
11631                             Slog.w(TAG, "Failed trying to unstop package "
11632                                     + cpr.appInfo.packageName + ": " + e);
11633                         }
11634
11635                         // Use existing process if already started
11636                         checkTime(startTime, "getContentProviderImpl: looking for process record");
11637                         ProcessRecord proc = getProcessRecordLocked(
11638                                 cpi.processName, cpr.appInfo.uid, false);
11639                         if (proc != null && proc.thread != null && !proc.killed) {
11640                             if (DEBUG_PROVIDER) Slog.d(TAG_PROVIDER,
11641                                     "Installing in existing process " + proc);
11642                             if (!proc.pubProviders.containsKey(cpi.name)) {
11643                                 checkTime(startTime, "getContentProviderImpl: scheduling install");
11644                                 proc.pubProviders.put(cpi.name, cpr);
11645                                 try {
11646                                     proc.thread.scheduleInstallProvider(cpi);
11647                                 } catch (RemoteException e) {
11648                                 }
11649                             }
11650                         } else {
11651                             checkTime(startTime, "getContentProviderImpl: before start process");
11652                             proc = startProcessLocked(cpi.processName,
11653                                     cpr.appInfo, false, 0, "content provider",
11654                                     new ComponentName(cpi.applicationInfo.packageName,
11655                                             cpi.name), false, false, false);
11656                             checkTime(startTime, "getContentProviderImpl: after start process");
11657                             if (proc == null) {
11658                                 Slog.w(TAG, "Unable to launch app "
11659                                         + cpi.applicationInfo.packageName + "/"
11660                                         + cpi.applicationInfo.uid + " for provider "
11661                                         + name + ": process is bad");
11662                                 return null;
11663                             }
11664                         }
11665                         cpr.launchingApp = proc;
11666                         mLaunchingProviders.add(cpr);
11667                     } finally {
11668                         Binder.restoreCallingIdentity(origId);
11669                     }
11670                 }
11671
11672                 checkTime(startTime, "getContentProviderImpl: updating data structures");
11673
11674                 // Make sure the provider is published (the same provider class
11675                 // may be published under multiple names).
11676                 if (firstClass) {
11677                     mProviderMap.putProviderByClass(comp, cpr);
11678                 }
11679
11680                 mProviderMap.putProviderByName(name, cpr);
11681                 conn = incProviderCountLocked(r, cpr, token, stable);
11682                 if (conn != null) {
11683                     conn.waiting = true;
11684                 }
11685             }
11686             checkTime(startTime, "getContentProviderImpl: done!");
11687
11688             grantEphemeralAccessLocked(userId, null /*intent*/,
11689                     cpi.applicationInfo.uid, UserHandle.getAppId(Binder.getCallingUid()));
11690         }
11691
11692         // Wait for the provider to be published...
11693         synchronized (cpr) {
11694             while (cpr.provider == null) {
11695                 if (cpr.launchingApp == null) {
11696                     Slog.w(TAG, "Unable to launch app "
11697                             + cpi.applicationInfo.packageName + "/"
11698                             + cpi.applicationInfo.uid + " for provider "
11699                             + name + ": launching app became null");
11700                     EventLog.writeEvent(EventLogTags.AM_PROVIDER_LOST_PROCESS,
11701                             UserHandle.getUserId(cpi.applicationInfo.uid),
11702                             cpi.applicationInfo.packageName,
11703                             cpi.applicationInfo.uid, name);
11704                     return null;
11705                 }
11706                 try {
11707                     if (DEBUG_MU) Slog.v(TAG_MU,
11708                             "Waiting to start provider " + cpr
11709                             + " launchingApp=" + cpr.launchingApp);
11710                     if (conn != null) {
11711                         conn.waiting = true;
11712                     }
11713                     cpr.wait();
11714                 } catch (InterruptedException ex) {
11715                 } finally {
11716                     if (conn != null) {
11717                         conn.waiting = false;
11718                     }
11719                 }
11720             }
11721         }
11722         return cpr != null ? cpr.newHolder(conn) : null;
11723     }
11724
11725     private boolean requestTargetProviderPermissionsReviewIfNeededLocked(ProviderInfo cpi,
11726             ProcessRecord r, final int userId) {
11727         if (getPackageManagerInternalLocked().isPermissionsReviewRequired(
11728                 cpi.packageName, userId)) {
11729
11730             final boolean callerForeground = r == null || r.setSchedGroup
11731                     != ProcessList.SCHED_GROUP_BACKGROUND;
11732
11733             // Show a permission review UI only for starting from a foreground app
11734             if (!callerForeground) {
11735                 Slog.w(TAG, "u" + userId + " Instantiating a provider in package"
11736                         + cpi.packageName + " requires a permissions review");
11737                 return false;
11738             }
11739
11740             final Intent intent = new Intent(Intent.ACTION_REVIEW_PERMISSIONS);
11741             intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK
11742                     | Intent.FLAG_ACTIVITY_EXCLUDE_FROM_RECENTS);
11743             intent.putExtra(Intent.EXTRA_PACKAGE_NAME, cpi.packageName);
11744
11745             if (DEBUG_PERMISSIONS_REVIEW) {
11746                 Slog.i(TAG, "u" + userId + " Launching permission review "
11747                         + "for package " + cpi.packageName);
11748             }
11749
11750             final UserHandle userHandle = new UserHandle(userId);
11751             mHandler.post(new Runnable() {
11752                 @Override
11753                 public void run() {
11754                     mContext.startActivityAsUser(intent, userHandle);
11755                 }
11756             });
11757
11758             return false;
11759         }
11760
11761         return true;
11762     }
11763
11764     PackageManagerInternal getPackageManagerInternalLocked() {
11765         if (mPackageManagerInt == null) {
11766             mPackageManagerInt = LocalServices.getService(PackageManagerInternal.class);
11767         }
11768         return mPackageManagerInt;
11769     }
11770
11771     @Override
11772     public final ContentProviderHolder getContentProvider(
11773             IApplicationThread caller, String name, int userId, boolean stable) {
11774         enforceNotIsolatedCaller("getContentProvider");
11775         if (caller == null) {
11776             String msg = "null IApplicationThread when getting content provider "
11777                     + name;
11778             Slog.w(TAG, msg);
11779             throw new SecurityException(msg);
11780         }
11781         // The incoming user check is now handled in checkContentProviderPermissionLocked() to deal
11782         // with cross-user grant.
11783         return getContentProviderImpl(caller, name, null, stable, userId);
11784     }
11785
11786     public ContentProviderHolder getContentProviderExternal(
11787             String name, int userId, IBinder token) {
11788         enforceCallingPermission(android.Manifest.permission.ACCESS_CONTENT_PROVIDERS_EXTERNALLY,
11789             "Do not have permission in call getContentProviderExternal()");
11790         userId = mUserController.handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(),
11791                 userId, false, ALLOW_FULL_ONLY, "getContentProvider", null);
11792         return getContentProviderExternalUnchecked(name, token, userId);
11793     }
11794
11795     private ContentProviderHolder getContentProviderExternalUnchecked(String name,
11796             IBinder token, int userId) {
11797         return getContentProviderImpl(null, name, token, true, userId);
11798     }
11799
11800     /**
11801      * Drop a content provider from a ProcessRecord's bookkeeping
11802      */
11803     public void removeContentProvider(IBinder connection, boolean stable) {
11804         enforceNotIsolatedCaller("removeContentProvider");
11805         long ident = Binder.clearCallingIdentity();
11806         try {
11807             synchronized (this) {
11808                 ContentProviderConnection conn;
11809                 try {
11810                     conn = (ContentProviderConnection)connection;
11811                 } catch (ClassCastException e) {
11812                     String msg ="removeContentProvider: " + connection
11813                             + " not a ContentProviderConnection";
11814                     Slog.w(TAG, msg);
11815                     throw new IllegalArgumentException(msg);
11816                 }
11817                 if (conn == null) {
11818                     throw new NullPointerException("connection is null");
11819                 }
11820                 if (decProviderCountLocked(conn, null, null, stable)) {
11821                     updateOomAdjLocked();
11822                 }
11823             }
11824         } finally {
11825             Binder.restoreCallingIdentity(ident);
11826         }
11827     }
11828
11829     public void removeContentProviderExternal(String name, IBinder token) {
11830         enforceCallingPermission(android.Manifest.permission.ACCESS_CONTENT_PROVIDERS_EXTERNALLY,
11831             "Do not have permission in call removeContentProviderExternal()");
11832         int userId = UserHandle.getCallingUserId();
11833         long ident = Binder.clearCallingIdentity();
11834         try {
11835             removeContentProviderExternalUnchecked(name, token, userId);
11836         } finally {
11837             Binder.restoreCallingIdentity(ident);
11838         }
11839     }
11840
11841     private void removeContentProviderExternalUnchecked(String name, IBinder token, int userId) {
11842         synchronized (this) {
11843             ContentProviderRecord cpr = mProviderMap.getProviderByName(name, userId);
11844             if(cpr == null) {
11845                 //remove from mProvidersByClass
11846                 if(DEBUG_ALL) Slog.v(TAG, name+" content provider not found in providers list");
11847                 return;
11848             }
11849
11850             //update content provider record entry info
11851             ComponentName comp = new ComponentName(cpr.info.packageName, cpr.info.name);
11852             ContentProviderRecord localCpr = mProviderMap.getProviderByClass(comp, userId);
11853             if (localCpr.hasExternalProcessHandles()) {
11854                 if (localCpr.removeExternalProcessHandleLocked(token)) {
11855                     updateOomAdjLocked();
11856                 } else {
11857                     Slog.e(TAG, "Attmpt to remove content provider " + localCpr
11858                             + " with no external reference for token: "
11859                             + token + ".");
11860                 }
11861             } else {
11862                 Slog.e(TAG, "Attmpt to remove content provider: " + localCpr
11863                         + " with no external references.");
11864             }
11865         }
11866     }
11867
11868     public final void publishContentProviders(IApplicationThread caller,
11869             List<ContentProviderHolder> providers) {
11870         if (providers == null) {
11871             return;
11872         }
11873
11874         enforceNotIsolatedCaller("publishContentProviders");
11875         synchronized (this) {
11876             final ProcessRecord r = getRecordForAppLocked(caller);
11877             if (DEBUG_MU) Slog.v(TAG_MU, "ProcessRecord uid = " + r.uid);
11878             if (r == null) {
11879                 throw new SecurityException(
11880                         "Unable to find app for caller " + caller
11881                       + " (pid=" + Binder.getCallingPid()
11882                       + ") when publishing content providers");
11883             }
11884
11885             final long origId = Binder.clearCallingIdentity();
11886
11887             final int N = providers.size();
11888             for (int i = 0; i < N; i++) {
11889                 ContentProviderHolder src = providers.get(i);
11890                 if (src == null || src.info == null || src.provider == null) {
11891                     continue;
11892                 }
11893                 ContentProviderRecord dst = r.pubProviders.get(src.info.name);
11894                 if (DEBUG_MU) Slog.v(TAG_MU, "ContentProviderRecord uid = " + dst.uid);
11895                 if (dst != null) {
11896                     ComponentName comp = new ComponentName(dst.info.packageName, dst.info.name);
11897                     mProviderMap.putProviderByClass(comp, dst);
11898                     String names[] = dst.info.authority.split(";");
11899                     for (int j = 0; j < names.length; j++) {
11900                         mProviderMap.putProviderByName(names[j], dst);
11901                     }
11902
11903                     int launchingCount = mLaunchingProviders.size();
11904                     int j;
11905                     boolean wasInLaunchingProviders = false;
11906                     for (j = 0; j < launchingCount; j++) {
11907                         if (mLaunchingProviders.get(j) == dst) {
11908                             mLaunchingProviders.remove(j);
11909                             wasInLaunchingProviders = true;
11910                             j--;
11911                             launchingCount--;
11912                         }
11913                     }
11914                     if (wasInLaunchingProviders) {
11915                         mHandler.removeMessages(CONTENT_PROVIDER_PUBLISH_TIMEOUT_MSG, r);
11916                     }
11917                     synchronized (dst) {
11918                         dst.provider = src.provider;
11919                         dst.proc = r;
11920                         dst.notifyAll();
11921                     }
11922                     updateOomAdjLocked(r, true);
11923                     maybeUpdateProviderUsageStatsLocked(r, src.info.packageName,
11924                             src.info.authority);
11925                 }
11926             }
11927
11928             Binder.restoreCallingIdentity(origId);
11929         }
11930     }
11931
11932     public boolean refContentProvider(IBinder connection, int stable, int unstable) {
11933         ContentProviderConnection conn;
11934         try {
11935             conn = (ContentProviderConnection)connection;
11936         } catch (ClassCastException e) {
11937             String msg ="refContentProvider: " + connection
11938                     + " not a ContentProviderConnection";
11939             Slog.w(TAG, msg);
11940             throw new IllegalArgumentException(msg);
11941         }
11942         if (conn == null) {
11943             throw new NullPointerException("connection is null");
11944         }
11945
11946         synchronized (this) {
11947             if (stable > 0) {
11948                 conn.numStableIncs += stable;
11949             }
11950             stable = conn.stableCount + stable;
11951             if (stable < 0) {
11952                 throw new IllegalStateException("stableCount < 0: " + stable);
11953             }
11954
11955             if (unstable > 0) {
11956                 conn.numUnstableIncs += unstable;
11957             }
11958             unstable = conn.unstableCount + unstable;
11959             if (unstable < 0) {
11960                 throw new IllegalStateException("unstableCount < 0: " + unstable);
11961             }
11962
11963             if ((stable+unstable) <= 0) {
11964                 throw new IllegalStateException("ref counts can't go to zero here: stable="
11965                         + stable + " unstable=" + unstable);
11966             }
11967             conn.stableCount = stable;
11968             conn.unstableCount = unstable;
11969             return !conn.dead;
11970         }
11971     }
11972
11973     public void unstableProviderDied(IBinder connection) {
11974         ContentProviderConnection conn;
11975         try {
11976             conn = (ContentProviderConnection)connection;
11977         } catch (ClassCastException e) {
11978             String msg ="refContentProvider: " + connection
11979                     + " not a ContentProviderConnection";
11980             Slog.w(TAG, msg);
11981             throw new IllegalArgumentException(msg);
11982         }
11983         if (conn == null) {
11984             throw new NullPointerException("connection is null");
11985         }
11986
11987         // Safely retrieve the content provider associated with the connection.
11988         IContentProvider provider;
11989         synchronized (this) {
11990             provider = conn.provider.provider;
11991         }
11992
11993         if (provider == null) {
11994             // Um, yeah, we're way ahead of you.
11995             return;
11996         }
11997
11998         // Make sure the caller is being honest with us.
11999         if (provider.asBinder().pingBinder()) {
12000             // Er, no, still looks good to us.
12001             synchronized (this) {
12002                 Slog.w(TAG, "unstableProviderDied: caller " + Binder.getCallingUid()
12003                         + " says " + conn + " died, but we don't agree");
12004                 return;
12005             }
12006         }
12007
12008         // Well look at that!  It's dead!
12009         synchronized (this) {
12010             if (conn.provider.provider != provider) {
12011                 // But something changed...  good enough.
12012                 return;
12013             }
12014
12015             ProcessRecord proc = conn.provider.proc;
12016             if (proc == null || proc.thread == null) {
12017                 // Seems like the process is already cleaned up.
12018                 return;
12019             }
12020
12021             // As far as we're concerned, this is just like receiving a
12022             // death notification...  just a bit prematurely.
12023             Slog.i(TAG, "Process " + proc.processName + " (pid " + proc.pid
12024                     + ") early provider death");
12025             final long ident = Binder.clearCallingIdentity();
12026             try {
12027                 appDiedLocked(proc);
12028             } finally {
12029                 Binder.restoreCallingIdentity(ident);
12030             }
12031         }
12032     }
12033
12034     @Override
12035     public void appNotRespondingViaProvider(IBinder connection) {
12036         enforceCallingPermission(
12037                 android.Manifest.permission.REMOVE_TASKS, "appNotRespondingViaProvider()");
12038
12039         final ContentProviderConnection conn = (ContentProviderConnection) connection;
12040         if (conn == null) {
12041             Slog.w(TAG, "ContentProviderConnection is null");
12042             return;
12043         }
12044
12045         final ProcessRecord host = conn.provider.proc;
12046         if (host == null) {
12047             Slog.w(TAG, "Failed to find hosting ProcessRecord");
12048             return;
12049         }
12050
12051         mHandler.post(new Runnable() {
12052             @Override
12053             public void run() {
12054                 mAppErrors.appNotResponding(host, null, null, false,
12055                         "ContentProvider not responding");
12056             }
12057         });
12058     }
12059
12060     public final void installSystemProviders() {
12061         List<ProviderInfo> providers;
12062         synchronized (this) {
12063             ProcessRecord app = mProcessNames.get("system", SYSTEM_UID);
12064             providers = generateApplicationProvidersLocked(app);
12065             if (providers != null) {
12066                 for (int i=providers.size()-1; i>=0; i--) {
12067                     ProviderInfo pi = (ProviderInfo)providers.get(i);
12068                     if ((pi.applicationInfo.flags&ApplicationInfo.FLAG_SYSTEM) == 0) {
12069                         Slog.w(TAG, "Not installing system proc provider " + pi.name
12070                                 + ": not system .apk");
12071                         providers.remove(i);
12072                     }
12073                 }
12074             }
12075         }
12076         if (providers != null) {
12077             mSystemThread.installSystemProviders(providers);
12078         }
12079
12080         mConstants.start(mContext.getContentResolver());
12081         mCoreSettingsObserver = new CoreSettingsObserver(this);
12082         mFontScaleSettingObserver = new FontScaleSettingObserver();
12083
12084         // Now that the settings provider is published we can consider sending
12085         // in a rescue party.
12086         RescueParty.onSettingsProviderPublished(mContext);
12087
12088         //mUsageStatsService.monitorPackages();
12089     }
12090
12091     private void startPersistentApps(int matchFlags) {
12092         if (mFactoryTest == FactoryTest.FACTORY_TEST_LOW_LEVEL) return;
12093
12094         synchronized (this) {
12095             try {
12096                 final List<ApplicationInfo> apps = AppGlobals.getPackageManager()
12097                         .getPersistentApplications(STOCK_PM_FLAGS | matchFlags).getList();
12098                 for (ApplicationInfo app : apps) {
12099                     if (!"android".equals(app.packageName)) {
12100                         addAppLocked(app, null, false, null /* ABI override */);
12101                     }
12102                 }
12103             } catch (RemoteException ex) {
12104             }
12105         }
12106     }
12107
12108     /**
12109      * When a user is unlocked, we need to install encryption-unaware providers
12110      * belonging to any running apps.
12111      */
12112     private void installEncryptionUnawareProviders(int userId) {
12113         // We're only interested in providers that are encryption unaware, and
12114         // we don't care about uninstalled apps, since there's no way they're
12115         // running at this point.
12116         final int matchFlags = GET_PROVIDERS | MATCH_DIRECT_BOOT_UNAWARE;
12117
12118         synchronized (this) {
12119             final int NP = mProcessNames.getMap().size();
12120             for (int ip = 0; ip < NP; ip++) {
12121                 final SparseArray<ProcessRecord> apps = mProcessNames.getMap().valueAt(ip);
12122                 final int NA = apps.size();
12123                 for (int ia = 0; ia < NA; ia++) {
12124                     final ProcessRecord app = apps.valueAt(ia);
12125                     if (app.userId != userId || app.thread == null || app.unlocked) continue;
12126
12127                     final int NG = app.pkgList.size();
12128                     for (int ig = 0; ig < NG; ig++) {
12129                         try {
12130                             final String pkgName = app.pkgList.keyAt(ig);
12131                             final PackageInfo pkgInfo = AppGlobals.getPackageManager()
12132                                     .getPackageInfo(pkgName, matchFlags, userId);
12133                             if (pkgInfo != null && !ArrayUtils.isEmpty(pkgInfo.providers)) {
12134                                 for (ProviderInfo pi : pkgInfo.providers) {
12135                                     // TODO: keep in sync with generateApplicationProvidersLocked
12136                                     final boolean processMatch = Objects.equals(pi.processName,
12137                                             app.processName) || pi.multiprocess;
12138                                     final boolean userMatch = isSingleton(pi.processName,
12139                                             pi.applicationInfo, pi.name, pi.flags)
12140                                                     ? (app.userId == UserHandle.USER_SYSTEM) : true;
12141                                     if (processMatch && userMatch) {
12142                                         Log.v(TAG, "Installing " + pi);
12143                                         app.thread.scheduleInstallProvider(pi);
12144                                     } else {
12145                                         Log.v(TAG, "Skipping " + pi);
12146                                     }
12147                                 }
12148                             }
12149                         } catch (RemoteException ignored) {
12150                         }
12151                     }
12152                 }
12153             }
12154         }
12155     }
12156
12157     /**
12158      * Allows apps to retrieve the MIME type of a URI.
12159      * If an app is in the same user as the ContentProvider, or if it is allowed to interact across
12160      * users, then it does not need permission to access the ContentProvider.
12161      * Either, it needs cross-user uri grants.
12162      *
12163      * CTS tests for this functionality can be run with "runtest cts-appsecurity".
12164      *
12165      * Test cases are at cts/tests/appsecurity-tests/test-apps/UsePermissionDiffCert/
12166      *     src/com/android/cts/usespermissiondiffcertapp/AccessPermissionWithDiffSigTest.java
12167      */
12168     public String getProviderMimeType(Uri uri, int userId) {
12169         enforceNotIsolatedCaller("getProviderMimeType");
12170         final String name = uri.getAuthority();
12171         int callingUid = Binder.getCallingUid();
12172         int callingPid = Binder.getCallingPid();
12173         long ident = 0;
12174         boolean clearedIdentity = false;
12175         synchronized (this) {
12176             userId = mUserController.unsafeConvertIncomingUserLocked(userId);
12177         }
12178         if (canClearIdentity(callingPid, callingUid, userId)) {
12179             clearedIdentity = true;
12180             ident = Binder.clearCallingIdentity();
12181         }
12182         ContentProviderHolder holder = null;
12183         try {
12184             holder = getContentProviderExternalUnchecked(name, null, userId);
12185             if (holder != null) {
12186                 return holder.provider.getType(uri);
12187             }
12188         } catch (RemoteException e) {
12189             Log.w(TAG, "Content provider dead retrieving " + uri, e);
12190             return null;
12191         } catch (Exception e) {
12192             Log.w(TAG, "Exception while determining type of " + uri, e);
12193             return null;
12194         } finally {
12195             // We need to clear the identity to call removeContentProviderExternalUnchecked
12196             if (!clearedIdentity) {
12197                 ident = Binder.clearCallingIdentity();
12198             }
12199             try {
12200                 if (holder != null) {
12201                     removeContentProviderExternalUnchecked(name, null, userId);
12202                 }
12203             } finally {
12204                 Binder.restoreCallingIdentity(ident);
12205             }
12206         }
12207
12208         return null;
12209     }
12210
12211     private boolean canClearIdentity(int callingPid, int callingUid, int userId) {
12212         if (UserHandle.getUserId(callingUid) == userId) {
12213             return true;
12214         }
12215         if (checkComponentPermission(INTERACT_ACROSS_USERS, callingPid,
12216                 callingUid, -1, true) == PackageManager.PERMISSION_GRANTED
12217                 || checkComponentPermission(INTERACT_ACROSS_USERS_FULL, callingPid,
12218                 callingUid, -1, true) == PackageManager.PERMISSION_GRANTED) {
12219                 return true;
12220         }
12221         return false;
12222     }
12223
12224     // =========================================================
12225     // GLOBAL MANAGEMENT
12226     // =========================================================
12227
12228     final ProcessRecord newProcessRecordLocked(ApplicationInfo info, String customProcess,
12229             boolean isolated, int isolatedUid) {
12230         String proc = customProcess != null ? customProcess : info.processName;
12231         BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
12232         final int userId = UserHandle.getUserId(info.uid);
12233         int uid = info.uid;
12234         if (isolated) {
12235             if (isolatedUid == 0) {
12236                 int stepsLeft = LAST_ISOLATED_UID - FIRST_ISOLATED_UID + 1;
12237                 while (true) {
12238                     if (mNextIsolatedProcessUid < FIRST_ISOLATED_UID
12239                             || mNextIsolatedProcessUid > LAST_ISOLATED_UID) {
12240                         mNextIsolatedProcessUid = FIRST_ISOLATED_UID;
12241                     }
12242                     uid = UserHandle.getUid(userId, mNextIsolatedProcessUid);
12243                     mNextIsolatedProcessUid++;
12244                     if (mIsolatedProcesses.indexOfKey(uid) < 0) {
12245                         // No process for this uid, use it.
12246                         break;
12247                     }
12248                     stepsLeft--;
12249                     if (stepsLeft <= 0) {
12250                         return null;
12251                     }
12252                 }
12253             } else {
12254                 // Special case for startIsolatedProcess (internal only), where
12255                 // the uid of the isolated process is specified by the caller.
12256                 uid = isolatedUid;
12257             }
12258             getPackageManagerInternalLocked().addIsolatedUid(uid, info.uid);
12259
12260             // Register the isolated UID with this application so BatteryStats knows to
12261             // attribute resource usage to the application.
12262             //
12263             // NOTE: This is done here before addProcessNameLocked, which will tell BatteryStats
12264             // about the process state of the isolated UID *before* it is registered with the
12265             // owning application.
12266             mBatteryStatsService.addIsolatedUid(uid, info.uid);
12267         }
12268         final ProcessRecord r = new ProcessRecord(stats, info, proc, uid);
12269         if (!mBooted && !mBooting
12270                 && userId == UserHandle.USER_SYSTEM
12271                 && (info.flags & PERSISTENT_MASK) == PERSISTENT_MASK) {
12272             r.persistent = true;
12273             r.maxAdj = ProcessList.PERSISTENT_PROC_ADJ;
12274         }
12275         addProcessNameLocked(r);
12276         return r;
12277     }
12278
12279     private boolean uidOnBackgroundWhitelist(final int uid) {
12280         final int appId = UserHandle.getAppId(uid);
12281         final int[] whitelist = mBackgroundAppIdWhitelist;
12282         final int N = whitelist.length;
12283         for (int i = 0; i < N; i++) {
12284             if (appId == whitelist[i]) {
12285                 return true;
12286             }
12287         }
12288         return false;
12289     }
12290
12291     @Override
12292     public void backgroundWhitelistUid(final int uid) {
12293         if (Binder.getCallingUid() != Process.SYSTEM_UID) {
12294             throw new SecurityException("Only the OS may call backgroundWhitelistUid()");
12295         }
12296
12297         if (DEBUG_BACKGROUND_CHECK) {
12298             Slog.i(TAG, "Adding uid " + uid + " to bg uid whitelist");
12299         }
12300         synchronized (this) {
12301             final int N = mBackgroundAppIdWhitelist.length;
12302             int[] newList = new int[N+1];
12303             System.arraycopy(mBackgroundAppIdWhitelist, 0, newList, 0, N);
12304             newList[N] = UserHandle.getAppId(uid);
12305             mBackgroundAppIdWhitelist = newList;
12306         }
12307     }
12308
12309     final ProcessRecord addAppLocked(ApplicationInfo info, String customProcess, boolean isolated,
12310             String abiOverride) {
12311         ProcessRecord app;
12312         if (!isolated) {
12313             app = getProcessRecordLocked(customProcess != null ? customProcess : info.processName,
12314                     info.uid, true);
12315         } else {
12316             app = null;
12317         }
12318
12319         if (app == null) {
12320             app = newProcessRecordLocked(info, customProcess, isolated, 0);
12321             updateLruProcessLocked(app, false, null);
12322             updateOomAdjLocked();
12323         }
12324
12325         // This package really, really can not be stopped.
12326         try {
12327             AppGlobals.getPackageManager().setPackageStoppedState(
12328                     info.packageName, false, UserHandle.getUserId(app.uid));
12329         } catch (RemoteException e) {
12330         } catch (IllegalArgumentException e) {
12331             Slog.w(TAG, "Failed trying to unstop package "
12332                     + info.packageName + ": " + e);
12333         }
12334
12335         if ((info.flags & PERSISTENT_MASK) == PERSISTENT_MASK) {
12336             app.persistent = true;
12337             app.maxAdj = ProcessList.PERSISTENT_PROC_ADJ;
12338         }
12339         if (app.thread == null && mPersistentStartingProcesses.indexOf(app) < 0) {
12340             mPersistentStartingProcesses.add(app);
12341             startProcessLocked(app, "added application",
12342                     customProcess != null ? customProcess : app.processName, abiOverride,
12343                     null /* entryPoint */, null /* entryPointArgs */);
12344         }
12345
12346         return app;
12347     }
12348
12349     public void unhandledBack() {
12350         enforceCallingPermission(android.Manifest.permission.FORCE_BACK,
12351                 "unhandledBack()");
12352
12353         synchronized(this) {
12354             final long origId = Binder.clearCallingIdentity();
12355             try {
12356                 getFocusedStack().unhandledBackLocked();
12357             } finally {
12358                 Binder.restoreCallingIdentity(origId);
12359             }
12360         }
12361     }
12362
12363     public ParcelFileDescriptor openContentUri(String uriString) throws RemoteException {
12364         enforceNotIsolatedCaller("openContentUri");
12365         final int userId = UserHandle.getCallingUserId();
12366         final Uri uri = Uri.parse(uriString);
12367         String name = uri.getAuthority();
12368         ContentProviderHolder cph = getContentProviderExternalUnchecked(name, null, userId);
12369         ParcelFileDescriptor pfd = null;
12370         if (cph != null) {
12371             // We record the binder invoker's uid in thread-local storage before
12372             // going to the content provider to open the file.  Later, in the code
12373             // that handles all permissions checks, we look for this uid and use
12374             // that rather than the Activity Manager's own uid.  The effect is that
12375             // we do the check against the caller's permissions even though it looks
12376             // to the content provider like the Activity Manager itself is making
12377             // the request.
12378             Binder token = new Binder();
12379             sCallerIdentity.set(new Identity(
12380                     token, Binder.getCallingPid(), Binder.getCallingUid()));
12381             try {
12382                 pfd = cph.provider.openFile(null, uri, "r", null, token);
12383             } catch (FileNotFoundException e) {
12384                 // do nothing; pfd will be returned null
12385             } finally {
12386                 // Ensure that whatever happens, we clean up the identity state
12387                 sCallerIdentity.remove();
12388                 // Ensure we're done with the provider.
12389                 removeContentProviderExternalUnchecked(name, null, userId);
12390             }
12391         } else {
12392             Slog.d(TAG, "Failed to get provider for authority '" + name + "'");
12393         }
12394         return pfd;
12395     }
12396
12397     // Actually is sleeping or shutting down or whatever else in the future
12398     // is an inactive state.
12399     boolean isSleepingOrShuttingDownLocked() {
12400         return isSleepingLocked() || mShuttingDown;
12401     }
12402
12403     boolean isShuttingDownLocked() {
12404         return mShuttingDown;
12405     }
12406
12407     boolean isSleepingLocked() {
12408         return mSleeping;
12409     }
12410
12411     void onWakefulnessChanged(int wakefulness) {
12412         synchronized(this) {
12413             mWakefulness = wakefulness;
12414             updateSleepIfNeededLocked();
12415         }
12416     }
12417
12418     void finishRunningVoiceLocked() {
12419         if (mRunningVoice != null) {
12420             mRunningVoice = null;
12421             mVoiceWakeLock.release();
12422             updateSleepIfNeededLocked();
12423         }
12424     }
12425
12426     void startTimeTrackingFocusedActivityLocked() {
12427         final ActivityRecord resumedActivity = mStackSupervisor.getResumedActivityLocked();
12428         if (!mSleeping && mCurAppTimeTracker != null && resumedActivity != null) {
12429             mCurAppTimeTracker.start(resumedActivity.packageName);
12430         }
12431     }
12432
12433     void updateSleepIfNeededLocked() {
12434         final boolean shouldSleep = shouldSleepLocked();
12435         if (mSleeping && !shouldSleep) {
12436             mSleeping = false;
12437             startTimeTrackingFocusedActivityLocked();
12438             mTopProcessState = ActivityManager.PROCESS_STATE_TOP;
12439             mStackSupervisor.comeOutOfSleepIfNeededLocked();
12440             sendNotifyVrManagerOfSleepState(false);
12441             updateOomAdjLocked();
12442         } else if (!mSleeping && shouldSleep) {
12443             mSleeping = true;
12444             if (mCurAppTimeTracker != null) {
12445                 mCurAppTimeTracker.stop();
12446             }
12447             mTopProcessState = ActivityManager.PROCESS_STATE_TOP_SLEEPING;
12448             mStackSupervisor.goingToSleepLocked();
12449             sendNotifyVrManagerOfSleepState(true);
12450             updateOomAdjLocked();
12451
12452             // Initialize the wake times of all processes.
12453             checkExcessivePowerUsageLocked(false);
12454             mHandler.removeMessages(CHECK_EXCESSIVE_WAKE_LOCKS_MSG);
12455             Message nmsg = mHandler.obtainMessage(CHECK_EXCESSIVE_WAKE_LOCKS_MSG);
12456             mHandler.sendMessageDelayed(nmsg, mConstants.POWER_CHECK_DELAY);
12457         }
12458
12459         // Also update state in a special way for running foreground services UI.
12460         switch (mWakefulness) {
12461             case PowerManagerInternal.WAKEFULNESS_ASLEEP:
12462             case PowerManagerInternal.WAKEFULNESS_DREAMING:
12463             case PowerManagerInternal.WAKEFULNESS_DOZING:
12464                 mServices.updateScreenStateLocked(false);
12465                 break;
12466             case PowerManagerInternal.WAKEFULNESS_AWAKE:
12467             default:
12468                 mServices.updateScreenStateLocked(true);
12469                 break;
12470         }
12471     }
12472
12473     private boolean shouldSleepLocked() {
12474         // Resume applications while running a voice interactor.
12475         if (mRunningVoice != null) {
12476             return false;
12477         }
12478
12479         // TODO: Transform the lock screen state into a sleep token instead.
12480         switch (mWakefulness) {
12481             case PowerManagerInternal.WAKEFULNESS_AWAKE:
12482             case PowerManagerInternal.WAKEFULNESS_DREAMING:
12483                 // Pause applications whenever the lock screen is shown or any sleep
12484                 // tokens have been acquired.
12485                 return mKeyguardController.isKeyguardShowing() || !mSleepTokens.isEmpty();
12486             case PowerManagerInternal.WAKEFULNESS_DOZING:
12487             case PowerManagerInternal.WAKEFULNESS_ASLEEP:
12488             default:
12489                 // If we're asleep then pause applications unconditionally.
12490                 return true;
12491         }
12492     }
12493
12494     /** Pokes the task persister. */
12495     void notifyTaskPersisterLocked(TaskRecord task, boolean flush) {
12496         mRecentTasks.notifyTaskPersisterLocked(task, flush);
12497     }
12498
12499     /**
12500      * Notifies all listeners when the pinned stack animation starts.
12501      */
12502     @Override
12503     public void notifyPinnedStackAnimationStarted() {
12504         mTaskChangeNotificationController.notifyPinnedStackAnimationStarted();
12505     }
12506
12507     /**
12508      * Notifies all listeners when the pinned stack animation ends.
12509      */
12510     @Override
12511     public void notifyPinnedStackAnimationEnded() {
12512         mTaskChangeNotificationController.notifyPinnedStackAnimationEnded();
12513     }
12514
12515     @Override
12516     public void notifyCleartextNetwork(int uid, byte[] firstPacket) {
12517         mHandler.obtainMessage(NOTIFY_CLEARTEXT_NETWORK_MSG, uid, 0, firstPacket).sendToTarget();
12518     }
12519
12520     @Override
12521     public boolean shutdown(int timeout) {
12522         if (checkCallingPermission(android.Manifest.permission.SHUTDOWN)
12523                 != PackageManager.PERMISSION_GRANTED) {
12524             throw new SecurityException("Requires permission "
12525                     + android.Manifest.permission.SHUTDOWN);
12526         }
12527
12528         boolean timedout = false;
12529
12530         synchronized(this) {
12531             mShuttingDown = true;
12532             updateEventDispatchingLocked();
12533             timedout = mStackSupervisor.shutdownLocked(timeout);
12534         }
12535
12536         mAppOpsService.shutdown();
12537         if (mUsageStatsService != null) {
12538             mUsageStatsService.prepareShutdown();
12539         }
12540         mBatteryStatsService.shutdown();
12541         synchronized (this) {
12542             mProcessStats.shutdownLocked();
12543             notifyTaskPersisterLocked(null, true);
12544         }
12545
12546         return timedout;
12547     }
12548
12549     public final void activitySlept(IBinder token) {
12550         if (DEBUG_ALL) Slog.v(TAG, "Activity slept: token=" + token);
12551
12552         final long origId = Binder.clearCallingIdentity();
12553
12554         synchronized (this) {
12555             final ActivityRecord r = ActivityRecord.isInStackLocked(token);
12556             if (r != null) {
12557                 mStackSupervisor.activitySleptLocked(r);
12558             }
12559         }
12560
12561         Binder.restoreCallingIdentity(origId);
12562     }
12563
12564     void startRunningVoiceLocked(IVoiceInteractionSession session, int targetUid) {
12565         Slog.d(TAG, "<<<  startRunningVoiceLocked()");
12566         mVoiceWakeLock.setWorkSource(new WorkSource(targetUid));
12567         if (mRunningVoice == null || mRunningVoice.asBinder() != session.asBinder()) {
12568             boolean wasRunningVoice = mRunningVoice != null;
12569             mRunningVoice = session;
12570             if (!wasRunningVoice) {
12571                 mVoiceWakeLock.acquire();
12572                 updateSleepIfNeededLocked();
12573             }
12574         }
12575     }
12576
12577     private void updateEventDispatchingLocked() {
12578         mWindowManager.setEventDispatching(mBooted && !mShuttingDown);
12579     }
12580
12581     @Override
12582     public void setLockScreenShown(boolean showing) {
12583         if (checkCallingPermission(android.Manifest.permission.DEVICE_POWER)
12584                 != PackageManager.PERMISSION_GRANTED) {
12585             throw new SecurityException("Requires permission "
12586                     + android.Manifest.permission.DEVICE_POWER);
12587         }
12588
12589         synchronized(this) {
12590             long ident = Binder.clearCallingIdentity();
12591             try {
12592                 mKeyguardController.setKeyguardShown(showing);
12593             } finally {
12594                 Binder.restoreCallingIdentity(ident);
12595             }
12596         }
12597     }
12598
12599     @Override
12600     public void notifyLockedProfile(@UserIdInt int userId) {
12601         try {
12602             if (!AppGlobals.getPackageManager().isUidPrivileged(Binder.getCallingUid())) {
12603                 throw new SecurityException("Only privileged app can call notifyLockedProfile");
12604             }
12605         } catch (RemoteException ex) {
12606             throw new SecurityException("Fail to check is caller a privileged app", ex);
12607         }
12608
12609         synchronized (this) {
12610             final long ident = Binder.clearCallingIdentity();
12611             try {
12612                 if (mUserController.shouldConfirmCredentials(userId)) {
12613                     if (mKeyguardController.isKeyguardLocked()) {
12614                         // Showing launcher to avoid user entering credential twice.
12615                         final int currentUserId = mUserController.getCurrentUserIdLocked();
12616                         startHomeActivityLocked(currentUserId, "notifyLockedProfile");
12617                     }
12618                     mStackSupervisor.lockAllProfileTasks(userId);
12619                 }
12620             } finally {
12621                 Binder.restoreCallingIdentity(ident);
12622             }
12623         }
12624     }
12625
12626     @Override
12627     public void startConfirmDeviceCredentialIntent(Intent intent, Bundle options) {
12628         enforceCallingPermission(MANAGE_ACTIVITY_STACKS, "startConfirmDeviceCredentialIntent");
12629         synchronized (this) {
12630             final long ident = Binder.clearCallingIdentity();
12631             try {
12632                 mActivityStarter.startConfirmCredentialIntent(intent, options);
12633             } finally {
12634                 Binder.restoreCallingIdentity(ident);
12635             }
12636         }
12637     }
12638
12639     @Override
12640     public void stopAppSwitches() {
12641         if (checkCallingPermission(android.Manifest.permission.STOP_APP_SWITCHES)
12642                 != PackageManager.PERMISSION_GRANTED) {
12643             throw new SecurityException("viewquires permission "
12644                     + android.Manifest.permission.STOP_APP_SWITCHES);
12645         }
12646
12647         synchronized(this) {
12648             mAppSwitchesAllowedTime = SystemClock.uptimeMillis()
12649                     + APP_SWITCH_DELAY_TIME;
12650             mDidAppSwitch = false;
12651             mHandler.removeMessages(DO_PENDING_ACTIVITY_LAUNCHES_MSG);
12652             Message msg = mHandler.obtainMessage(DO_PENDING_ACTIVITY_LAUNCHES_MSG);
12653             mHandler.sendMessageDelayed(msg, APP_SWITCH_DELAY_TIME);
12654         }
12655     }
12656
12657     public void resumeAppSwitches() {
12658         if (checkCallingPermission(android.Manifest.permission.STOP_APP_SWITCHES)
12659                 != PackageManager.PERMISSION_GRANTED) {
12660             throw new SecurityException("Requires permission "
12661                     + android.Manifest.permission.STOP_APP_SWITCHES);
12662         }
12663
12664         synchronized(this) {
12665             // Note that we don't execute any pending app switches... we will
12666             // let those wait until either the timeout, or the next start
12667             // activity request.
12668             mAppSwitchesAllowedTime = 0;
12669         }
12670     }
12671
12672     boolean checkAppSwitchAllowedLocked(int sourcePid, int sourceUid,
12673             int callingPid, int callingUid, String name) {
12674         if (mAppSwitchesAllowedTime < SystemClock.uptimeMillis()) {
12675             return true;
12676         }
12677
12678         int perm = checkComponentPermission(
12679                 android.Manifest.permission.STOP_APP_SWITCHES, sourcePid,
12680                 sourceUid, -1, true);
12681         if (perm == PackageManager.PERMISSION_GRANTED) {
12682             return true;
12683         }
12684
12685         // If the actual IPC caller is different from the logical source, then
12686         // also see if they are allowed to control app switches.
12687         if (callingUid != -1 && callingUid != sourceUid) {
12688             perm = checkComponentPermission(
12689                     android.Manifest.permission.STOP_APP_SWITCHES, callingPid,
12690                     callingUid, -1, true);
12691             if (perm == PackageManager.PERMISSION_GRANTED) {
12692                 return true;
12693             }
12694         }
12695
12696         Slog.w(TAG, name + " request from " + sourceUid + " stopped");
12697         return false;
12698     }
12699
12700     public void setDebugApp(String packageName, boolean waitForDebugger,
12701             boolean persistent) {
12702         enforceCallingPermission(android.Manifest.permission.SET_DEBUG_APP,
12703                 "setDebugApp()");
12704
12705         long ident = Binder.clearCallingIdentity();
12706         try {
12707             // Note that this is not really thread safe if there are multiple
12708             // callers into it at the same time, but that's not a situation we
12709             // care about.
12710             if (persistent) {
12711                 final ContentResolver resolver = mContext.getContentResolver();
12712                 Settings.Global.putString(
12713                     resolver, Settings.Global.DEBUG_APP,
12714                     packageName);
12715                 Settings.Global.putInt(
12716                     resolver, Settings.Global.WAIT_FOR_DEBUGGER,
12717                     waitForDebugger ? 1 : 0);
12718             }
12719
12720             synchronized (this) {
12721                 if (!persistent) {
12722                     mOrigDebugApp = mDebugApp;
12723                     mOrigWaitForDebugger = mWaitForDebugger;
12724                 }
12725                 mDebugApp = packageName;
12726                 mWaitForDebugger = waitForDebugger;
12727                 mDebugTransient = !persistent;
12728                 if (packageName != null) {
12729                     forceStopPackageLocked(packageName, -1, false, false, true, true,
12730                             false, UserHandle.USER_ALL, "set debug app");
12731                 }
12732             }
12733         } finally {
12734             Binder.restoreCallingIdentity(ident);
12735         }
12736     }
12737
12738     void setTrackAllocationApp(ApplicationInfo app, String processName) {
12739         synchronized (this) {
12740             boolean isDebuggable = "1".equals(SystemProperties.get(SYSTEM_DEBUGGABLE, "0"));
12741             if (!isDebuggable) {
12742                 if ((app.flags & ApplicationInfo.FLAG_DEBUGGABLE) == 0) {
12743                     throw new SecurityException("Process not debuggable: " + app.packageName);
12744                 }
12745             }
12746
12747             mTrackAllocationApp = processName;
12748         }
12749     }
12750
12751     void setProfileApp(ApplicationInfo app, String processName, ProfilerInfo profilerInfo) {
12752         synchronized (this) {
12753             boolean isDebuggable = "1".equals(SystemProperties.get(SYSTEM_DEBUGGABLE, "0"));
12754             if (!isDebuggable) {
12755                 if ((app.flags & ApplicationInfo.FLAG_DEBUGGABLE) == 0) {
12756                     throw new SecurityException("Process not debuggable: " + app.packageName);
12757                 }
12758             }
12759             mProfileApp = processName;
12760             mProfileFile = profilerInfo.profileFile;
12761             if (mProfileFd != null) {
12762                 try {
12763                     mProfileFd.close();
12764                 } catch (IOException e) {
12765                 }
12766                 mProfileFd = null;
12767             }
12768             mProfileFd = profilerInfo.profileFd;
12769             mSamplingInterval = profilerInfo.samplingInterval;
12770             mAutoStopProfiler = profilerInfo.autoStopProfiler;
12771             mStreamingOutput = profilerInfo.streamingOutput;
12772             mProfileType = 0;
12773         }
12774     }
12775
12776     void setNativeDebuggingAppLocked(ApplicationInfo app, String processName) {
12777         boolean isDebuggable = "1".equals(SystemProperties.get(SYSTEM_DEBUGGABLE, "0"));
12778         if (!isDebuggable) {
12779             if ((app.flags & ApplicationInfo.FLAG_DEBUGGABLE) == 0) {
12780                 throw new SecurityException("Process not debuggable: " + app.packageName);
12781             }
12782         }
12783         mNativeDebuggingApp = processName;
12784     }
12785
12786     @Override
12787     public void setAlwaysFinish(boolean enabled) {
12788         enforceCallingPermission(android.Manifest.permission.SET_ALWAYS_FINISH,
12789                 "setAlwaysFinish()");
12790
12791         long ident = Binder.clearCallingIdentity();
12792         try {
12793             Settings.Global.putInt(
12794                     mContext.getContentResolver(),
12795                     Settings.Global.ALWAYS_FINISH_ACTIVITIES, enabled ? 1 : 0);
12796
12797             synchronized (this) {
12798                 mAlwaysFinishActivities = enabled;
12799             }
12800         } finally {
12801             Binder.restoreCallingIdentity(ident);
12802         }
12803     }
12804
12805     @Override
12806     public void setActivityController(IActivityController controller, boolean imAMonkey) {
12807         enforceCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER,
12808                 "setActivityController()");
12809         synchronized (this) {
12810             mController = controller;
12811             mControllerIsAMonkey = imAMonkey;
12812             Watchdog.getInstance().setActivityController(controller);
12813         }
12814     }
12815
12816     @Override
12817     public void setUserIsMonkey(boolean userIsMonkey) {
12818         synchronized (this) {
12819             synchronized (mPidsSelfLocked) {
12820                 final int callingPid = Binder.getCallingPid();
12821                 ProcessRecord proc = mPidsSelfLocked.get(callingPid);
12822                 if (proc == null) {
12823                     throw new SecurityException("Unknown process: " + callingPid);
12824                 }
12825                 if (proc.instr == null || proc.instr.mUiAutomationConnection == null) {
12826                     throw new SecurityException("Only an instrumentation process "
12827                             + "with a UiAutomation can call setUserIsMonkey");
12828                 }
12829             }
12830             mUserIsMonkey = userIsMonkey;
12831         }
12832     }
12833
12834     @Override
12835     public boolean isUserAMonkey() {
12836         synchronized (this) {
12837             // If there is a controller also implies the user is a monkey.
12838             return (mUserIsMonkey || (mController != null && mControllerIsAMonkey));
12839         }
12840     }
12841
12842     /**
12843      * @deprecated This method is only used by a few internal components and it will soon be
12844      * replaced by a proper bug report API (which will be restricted to a few, pre-defined apps).
12845      * No new code should be calling it.
12846      */
12847     @Deprecated
12848     @Override
12849     public void requestBugReport(int bugreportType) {
12850         String extraOptions = null;
12851         switch (bugreportType) {
12852             case ActivityManager.BUGREPORT_OPTION_FULL:
12853                 // Default options.
12854                 break;
12855             case ActivityManager.BUGREPORT_OPTION_INTERACTIVE:
12856                 extraOptions = "bugreportplus";
12857                 break;
12858             case ActivityManager.BUGREPORT_OPTION_REMOTE:
12859                 extraOptions = "bugreportremote";
12860                 break;
12861             case ActivityManager.BUGREPORT_OPTION_WEAR:
12862                 extraOptions = "bugreportwear";
12863                 break;
12864             case ActivityManager.BUGREPORT_OPTION_TELEPHONY:
12865                 extraOptions = "bugreporttelephony";
12866                 break;
12867             default:
12868                 throw new IllegalArgumentException("Provided bugreport type is not correct, value: "
12869                         + bugreportType);
12870         }
12871         enforceCallingPermission(android.Manifest.permission.DUMP, "requestBugReport");
12872         if (extraOptions != null) {
12873             SystemProperties.set("dumpstate.options", extraOptions);
12874         }
12875         SystemProperties.set("ctl.start", "bugreport");
12876     }
12877
12878     /**
12879      * @deprecated This method is only used by a few internal components and it will soon be
12880      * replaced by a proper bug report API (which will be restricted to a few, pre-defined apps).
12881      * No new code should be calling it.
12882      */
12883     @Deprecated
12884     @Override
12885     public void requestTelephonyBugReport(String shareTitle, String shareDescription) {
12886
12887         if (!TextUtils.isEmpty(shareTitle)) {
12888             if (shareTitle.length() > MAX_BUGREPORT_TITLE_SIZE) {
12889                 String errorStr = "shareTitle should be less than " +
12890                         MAX_BUGREPORT_TITLE_SIZE + " characters";
12891                 throw new IllegalArgumentException(errorStr);
12892             } else {
12893                 if (!TextUtils.isEmpty(shareDescription)) {
12894                     int length;
12895                     try {
12896                         length = shareDescription.getBytes("UTF-8").length;
12897                     } catch (UnsupportedEncodingException e) {
12898                         String errorStr = "shareDescription: UnsupportedEncodingException";
12899                         throw new IllegalArgumentException(errorStr);
12900                     }
12901                     if (length > SystemProperties.PROP_VALUE_MAX) {
12902                         String errorStr = "shareTitle should be less than " +
12903                                 SystemProperties.PROP_VALUE_MAX + " bytes";
12904                         throw new IllegalArgumentException(errorStr);
12905                     } else {
12906                         SystemProperties.set("dumpstate.options.description", shareDescription);
12907                     }
12908                 }
12909                 SystemProperties.set("dumpstate.options.title", shareTitle);
12910             }
12911         }
12912
12913         Slog.d(TAG, "Bugreport notification title " + shareTitle
12914                 + " description " + shareDescription);
12915         requestBugReport(ActivityManager.BUGREPORT_OPTION_TELEPHONY);
12916     }
12917
12918     public static long getInputDispatchingTimeoutLocked(ActivityRecord r) {
12919         return r != null ? getInputDispatchingTimeoutLocked(r.app) : KEY_DISPATCHING_TIMEOUT;
12920     }
12921
12922     public static long getInputDispatchingTimeoutLocked(ProcessRecord r) {
12923         if (r != null && (r.instr != null || r.usingWrapper)) {
12924             return INSTRUMENTATION_KEY_DISPATCHING_TIMEOUT;
12925         }
12926         return KEY_DISPATCHING_TIMEOUT;
12927     }
12928
12929     @Override
12930     public long inputDispatchingTimedOut(int pid, final boolean aboveSystem, String reason) {
12931         if (checkCallingPermission(android.Manifest.permission.FILTER_EVENTS)
12932                 != PackageManager.PERMISSION_GRANTED) {
12933             throw new SecurityException("Requires permission "
12934                     + android.Manifest.permission.FILTER_EVENTS);
12935         }
12936         ProcessRecord proc;
12937         long timeout;
12938         synchronized (this) {
12939             synchronized (mPidsSelfLocked) {
12940                 proc = mPidsSelfLocked.get(pid);
12941             }
12942             timeout = getInputDispatchingTimeoutLocked(proc);
12943         }
12944
12945         if (inputDispatchingTimedOut(proc, null, null, aboveSystem, reason)) {
12946             return -1;
12947         }
12948
12949         return timeout;
12950     }
12951
12952     /**
12953      * Handle input dispatching timeouts.
12954      * Returns whether input dispatching should be aborted or not.
12955      */
12956     public boolean inputDispatchingTimedOut(final ProcessRecord proc,
12957             final ActivityRecord activity, final ActivityRecord parent,
12958             final boolean aboveSystem, String reason) {
12959         if (checkCallingPermission(android.Manifest.permission.FILTER_EVENTS)
12960                 != PackageManager.PERMISSION_GRANTED) {
12961             throw new SecurityException("Requires permission "
12962                     + android.Manifest.permission.FILTER_EVENTS);
12963         }
12964
12965         final String annotation;
12966         if (reason == null) {
12967             annotation = "Input dispatching timed out";
12968         } else {
12969             annotation = "Input dispatching timed out (" + reason + ")";
12970         }
12971
12972         if (proc != null) {
12973             synchronized (this) {
12974                 if (proc.debugging) {
12975                     return false;
12976                 }
12977
12978                 if (proc.instr != null) {
12979                     Bundle info = new Bundle();
12980                     info.putString("shortMsg", "keyDispatchingTimedOut");
12981                     info.putString("longMsg", annotation);
12982                     finishInstrumentationLocked(proc, Activity.RESULT_CANCELED, info);
12983                     return true;
12984                 }
12985             }
12986             mHandler.post(new Runnable() {
12987                 @Override
12988                 public void run() {
12989                     mAppErrors.appNotResponding(proc, activity, parent, aboveSystem, annotation);
12990                 }
12991             });
12992         }
12993
12994         return true;
12995     }
12996
12997     @Override
12998     public Bundle getAssistContextExtras(int requestType) {
12999         PendingAssistExtras pae = enqueueAssistContext(requestType, null, null, null,
13000                 null, null, true /* focused */, true /* newSessionId */,
13001                 UserHandle.getCallingUserId(), null, PENDING_ASSIST_EXTRAS_TIMEOUT, 0);
13002         if (pae == null) {
13003             return null;
13004         }
13005         synchronized (pae) {
13006             while (!pae.haveResult) {
13007                 try {
13008                     pae.wait();
13009                 } catch (InterruptedException e) {
13010                 }
13011             }
13012         }
13013         synchronized (this) {
13014             buildAssistBundleLocked(pae, pae.result);
13015             mPendingAssistExtras.remove(pae);
13016             mUiHandler.removeCallbacks(pae);
13017         }
13018         return pae.extras;
13019     }
13020
13021     @Override
13022     public boolean isAssistDataAllowedOnCurrentActivity() {
13023         int userId;
13024         synchronized (this) {
13025             final ActivityStack focusedStack = getFocusedStack();
13026             if (focusedStack == null || focusedStack.isAssistantStack()) {
13027                 return false;
13028             }
13029
13030             final ActivityRecord activity = focusedStack.topActivity();
13031             if (activity == null) {
13032                 return false;
13033             }
13034             userId = activity.userId;
13035         }
13036         DevicePolicyManager dpm = (DevicePolicyManager) mContext.getSystemService(
13037                 Context.DEVICE_POLICY_SERVICE);
13038         return (dpm == null) || (!dpm.getScreenCaptureDisabled(null, userId));
13039     }
13040
13041     @Override
13042     public boolean showAssistFromActivity(IBinder token, Bundle args) {
13043         long ident = Binder.clearCallingIdentity();
13044         try {
13045             synchronized (this) {
13046                 ActivityRecord caller = ActivityRecord.forTokenLocked(token);
13047                 ActivityRecord top = getFocusedStack().topActivity();
13048                 if (top != caller) {
13049                     Slog.w(TAG, "showAssistFromActivity failed: caller " + caller
13050                             + " is not current top " + top);
13051                     return false;
13052                 }
13053                 if (!top.nowVisible) {
13054                     Slog.w(TAG, "showAssistFromActivity failed: caller " + caller
13055                             + " is not visible");
13056                     return false;
13057                 }
13058             }
13059             return mAssistUtils.showSessionForActiveService(args, SHOW_SOURCE_APPLICATION, null,
13060                     token);
13061         } finally {
13062             Binder.restoreCallingIdentity(ident);
13063         }
13064     }
13065
13066     @Override
13067     public boolean requestAssistContextExtras(int requestType, IResultReceiver receiver,
13068             Bundle receiverExtras, IBinder activityToken, boolean focused, boolean newSessionId) {
13069         return enqueueAssistContext(requestType, null, null, receiver, receiverExtras,
13070                 activityToken, focused, newSessionId, UserHandle.getCallingUserId(), null,
13071                 PENDING_ASSIST_EXTRAS_LONG_TIMEOUT, 0) != null;
13072     }
13073
13074     @Override
13075     public boolean requestAutofillData(IResultReceiver receiver, Bundle receiverExtras,
13076             IBinder activityToken, int flags) {
13077         return enqueueAssistContext(ActivityManager.ASSIST_CONTEXT_AUTOFILL, null, null,
13078                 receiver, receiverExtras, activityToken, true, true, UserHandle.getCallingUserId(),
13079                 null, PENDING_AUTOFILL_ASSIST_STRUCTURE_TIMEOUT, flags) != null;
13080     }
13081
13082     private PendingAssistExtras enqueueAssistContext(int requestType, Intent intent, String hint,
13083             IResultReceiver receiver, Bundle receiverExtras, IBinder activityToken,
13084             boolean focused, boolean newSessionId, int userHandle, Bundle args, long timeout,
13085             int flags) {
13086         enforceCallingPermission(android.Manifest.permission.GET_TOP_ACTIVITY_INFO,
13087                 "enqueueAssistContext()");
13088
13089         synchronized (this) {
13090             ActivityRecord activity = getFocusedStack().topActivity();
13091             if (activity == null) {
13092                 Slog.w(TAG, "getAssistContextExtras failed: no top activity");
13093                 return null;
13094             }
13095             if (activity.app == null || activity.app.thread == null) {
13096                 Slog.w(TAG, "getAssistContextExtras failed: no process for " + activity);
13097                 return null;
13098             }
13099             if (focused) {
13100                 if (activityToken != null) {
13101                     ActivityRecord caller = ActivityRecord.forTokenLocked(activityToken);
13102                     if (activity != caller) {
13103                         Slog.w(TAG, "enqueueAssistContext failed: caller " + caller
13104                                 + " is not current top " + activity);
13105                         return null;
13106                     }
13107                 }
13108             } else {
13109                 activity = ActivityRecord.forTokenLocked(activityToken);
13110                 if (activity == null) {
13111                     Slog.w(TAG, "enqueueAssistContext failed: activity for token=" + activityToken
13112                             + " couldn't be found");
13113                     return null;
13114                 }
13115             }
13116
13117             PendingAssistExtras pae;
13118             Bundle extras = new Bundle();
13119             if (args != null) {
13120                 extras.putAll(args);
13121             }
13122             extras.putString(Intent.EXTRA_ASSIST_PACKAGE, activity.packageName);
13123             extras.putInt(Intent.EXTRA_ASSIST_UID, activity.app.uid);
13124
13125             pae = new PendingAssistExtras(activity, extras, intent, hint, receiver, receiverExtras,
13126                     userHandle);
13127             pae.isHome = activity.isHomeActivity();
13128
13129             // Increment the sessionId if necessary
13130             if (newSessionId) {
13131                 mViSessionId++;
13132             }
13133             try {
13134                 activity.app.thread.requestAssistContextExtras(activity.appToken, pae, requestType,
13135                         mViSessionId, flags);
13136                 mPendingAssistExtras.add(pae);
13137                 mUiHandler.postDelayed(pae, timeout);
13138             } catch (RemoteException e) {
13139                 Slog.w(TAG, "getAssistContextExtras failed: crash calling " + activity);
13140                 return null;
13141             }
13142             return pae;
13143         }
13144     }
13145
13146     void pendingAssistExtrasTimedOut(PendingAssistExtras pae) {
13147         IResultReceiver receiver;
13148         synchronized (this) {
13149             mPendingAssistExtras.remove(pae);
13150             receiver = pae.receiver;
13151         }
13152         if (receiver != null) {
13153             // Caller wants result sent back to them.
13154             Bundle sendBundle = new Bundle();
13155             // At least return the receiver extras
13156             sendBundle.putBundle(VoiceInteractionSession.KEY_RECEIVER_EXTRAS,
13157                     pae.receiverExtras);
13158             try {
13159                 pae.receiver.send(0, sendBundle);
13160             } catch (RemoteException e) {
13161             }
13162         }
13163     }
13164
13165     private void buildAssistBundleLocked(PendingAssistExtras pae, Bundle result) {
13166         if (result != null) {
13167             pae.extras.putBundle(Intent.EXTRA_ASSIST_CONTEXT, result);
13168         }
13169         if (pae.hint != null) {
13170             pae.extras.putBoolean(pae.hint, true);
13171         }
13172     }
13173
13174     /** Called from an app when assist data is ready. */
13175     @Override
13176     public void reportAssistContextExtras(IBinder token, Bundle extras, AssistStructure structure,
13177             AssistContent content, Uri referrer) {
13178         PendingAssistExtras pae = (PendingAssistExtras)token;
13179         synchronized (pae) {
13180             pae.result = extras;
13181             pae.structure = structure;
13182             pae.content = content;
13183             if (referrer != null) {
13184                 pae.extras.putParcelable(Intent.EXTRA_REFERRER, referrer);
13185             }
13186             if (structure != null) {
13187                 structure.setHomeActivity(pae.isHome);
13188             }
13189             pae.haveResult = true;
13190             pae.notifyAll();
13191             if (pae.intent == null && pae.receiver == null) {
13192                 // Caller is just waiting for the result.
13193                 return;
13194             }
13195         }
13196
13197         // We are now ready to launch the assist activity.
13198         IResultReceiver sendReceiver = null;
13199         Bundle sendBundle = null;
13200         synchronized (this) {
13201             buildAssistBundleLocked(pae, extras);
13202             boolean exists = mPendingAssistExtras.remove(pae);
13203             mUiHandler.removeCallbacks(pae);
13204             if (!exists) {
13205                 // Timed out.
13206                 return;
13207             }
13208             if ((sendReceiver=pae.receiver) != null) {
13209                 // Caller wants result sent back to them.
13210                 sendBundle = new Bundle();
13211                 sendBundle.putBundle(VoiceInteractionSession.KEY_DATA, pae.extras);
13212                 sendBundle.putParcelable(VoiceInteractionSession.KEY_STRUCTURE, pae.structure);
13213                 sendBundle.putParcelable(VoiceInteractionSession.KEY_CONTENT, pae.content);
13214                 sendBundle.putBundle(VoiceInteractionSession.KEY_RECEIVER_EXTRAS,
13215                         pae.receiverExtras);
13216             }
13217         }
13218         if (sendReceiver != null) {
13219             try {
13220                 sendReceiver.send(0, sendBundle);
13221             } catch (RemoteException e) {
13222             }
13223             return;
13224         }
13225
13226         long ident = Binder.clearCallingIdentity();
13227         try {
13228             pae.intent.replaceExtras(pae.extras);
13229             pae.intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK
13230                     | Intent.FLAG_ACTIVITY_SINGLE_TOP
13231                     | Intent.FLAG_ACTIVITY_CLEAR_TOP);
13232             closeSystemDialogs("assist");
13233             try {
13234                 mContext.startActivityAsUser(pae.intent, new UserHandle(pae.userHandle));
13235             } catch (ActivityNotFoundException e) {
13236                 Slog.w(TAG, "No activity to handle assist action.", e);
13237             }
13238         } finally {
13239             Binder.restoreCallingIdentity(ident);
13240         }
13241     }
13242
13243     public boolean launchAssistIntent(Intent intent, int requestType, String hint, int userHandle,
13244             Bundle args) {
13245         return enqueueAssistContext(requestType, intent, hint, null, null, null,
13246                 true /* focused */, true /* newSessionId */, userHandle, args,
13247                 PENDING_ASSIST_EXTRAS_TIMEOUT, 0) != null;
13248     }
13249
13250     public void registerProcessObserver(IProcessObserver observer) {
13251         enforceCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER,
13252                 "registerProcessObserver()");
13253         synchronized (this) {
13254             mProcessObservers.register(observer);
13255         }
13256     }
13257
13258     @Override
13259     public void unregisterProcessObserver(IProcessObserver observer) {
13260         synchronized (this) {
13261             mProcessObservers.unregister(observer);
13262         }
13263     }
13264
13265     @Override
13266     public int getUidProcessState(int uid, String callingPackage) {
13267         if (!hasUsageStatsPermission(callingPackage)) {
13268             enforceCallingPermission(android.Manifest.permission.PACKAGE_USAGE_STATS,
13269                     "getUidProcessState");
13270         }
13271
13272         synchronized (this) {
13273             UidRecord uidRec = mActiveUids.get(uid);
13274             return uidRec != null ? uidRec.curProcState : ActivityManager.PROCESS_STATE_NONEXISTENT;
13275         }
13276     }
13277
13278     @Override
13279     public void registerUidObserver(IUidObserver observer, int which, int cutpoint,
13280             String callingPackage) {
13281         if (!hasUsageStatsPermission(callingPackage)) {
13282             enforceCallingPermission(android.Manifest.permission.PACKAGE_USAGE_STATS,
13283                     "registerUidObserver");
13284         }
13285         synchronized (this) {
13286             mUidObservers.register(observer, new UidObserverRegistration(Binder.getCallingUid(),
13287                     callingPackage, which, cutpoint));
13288         }
13289     }
13290
13291     @Override
13292     public void unregisterUidObserver(IUidObserver observer) {
13293         synchronized (this) {
13294             mUidObservers.unregister(observer);
13295         }
13296     }
13297
13298     @Override
13299     public boolean convertFromTranslucent(IBinder token) {
13300         final long origId = Binder.clearCallingIdentity();
13301         try {
13302             synchronized (this) {
13303                 final ActivityRecord r = ActivityRecord.isInStackLocked(token);
13304                 if (r == null) {
13305                     return false;
13306                 }
13307                 final boolean translucentChanged = r.changeWindowTranslucency(true);
13308                 if (translucentChanged) {
13309                     r.getStack().releaseBackgroundResources(r);
13310                     mStackSupervisor.ensureActivitiesVisibleLocked(null, 0, !PRESERVE_WINDOWS);
13311                 }
13312                 mWindowManager.setAppFullscreen(token, true);
13313                 return translucentChanged;
13314             }
13315         } finally {
13316             Binder.restoreCallingIdentity(origId);
13317         }
13318     }
13319
13320     @Override
13321     public boolean convertToTranslucent(IBinder token, Bundle options) {
13322         final long origId = Binder.clearCallingIdentity();
13323         try {
13324             synchronized (this) {
13325                 final ActivityRecord r = ActivityRecord.isInStackLocked(token);
13326                 if (r == null) {
13327                     return false;
13328                 }
13329                 final TaskRecord task = r.getTask();
13330                 int index = task.mActivities.lastIndexOf(r);
13331                 if (index > 0) {
13332                     ActivityRecord under = task.mActivities.get(index - 1);
13333                     under.returningOptions = ActivityOptions.fromBundle(options);
13334                 }
13335                 final boolean translucentChanged = r.changeWindowTranslucency(false);
13336                 if (translucentChanged) {
13337                     r.getStack().convertActivityToTranslucent(r);
13338                 }
13339                 mStackSupervisor.ensureActivitiesVisibleLocked(null, 0, !PRESERVE_WINDOWS);
13340                 mWindowManager.setAppFullscreen(token, false);
13341                 return translucentChanged;
13342             }
13343         } finally {
13344             Binder.restoreCallingIdentity(origId);
13345         }
13346     }
13347
13348     @Override
13349     public boolean requestVisibleBehind(IBinder token, boolean visible) {
13350         final long origId = Binder.clearCallingIdentity();
13351         try {
13352             synchronized (this) {
13353                 final ActivityRecord r = ActivityRecord.isInStackLocked(token);
13354                 if (r != null) {
13355                     return mStackSupervisor.requestVisibleBehindLocked(r, visible);
13356                 }
13357             }
13358             return false;
13359         } finally {
13360             Binder.restoreCallingIdentity(origId);
13361         }
13362     }
13363
13364     @Override
13365     public boolean isBackgroundVisibleBehind(IBinder token) {
13366         final long origId = Binder.clearCallingIdentity();
13367         try {
13368             synchronized (this) {
13369                 final ActivityStack stack = ActivityRecord.getStackLocked(token);
13370                 final boolean visible = stack == null ? false : stack.hasVisibleBehindActivity();
13371                 if (DEBUG_VISIBLE_BEHIND) Slog.d(TAG_VISIBLE_BEHIND,
13372                         "isBackgroundVisibleBehind: stack=" + stack + " visible=" + visible);
13373                 return visible;
13374             }
13375         } finally {
13376             Binder.restoreCallingIdentity(origId);
13377         }
13378     }
13379
13380     @Override
13381     public Bundle getActivityOptions(IBinder token) {
13382         final long origId = Binder.clearCallingIdentity();
13383         try {
13384             synchronized (this) {
13385                 final ActivityRecord r = ActivityRecord.isInStackLocked(token);
13386                 if (r != null) {
13387                     final ActivityOptions activityOptions = r.pendingOptions;
13388                     return activityOptions == null ? null : activityOptions.toBundle();
13389                 }
13390                 return null;
13391             }
13392         } finally {
13393             Binder.restoreCallingIdentity(origId);
13394         }
13395     }
13396
13397     @Override
13398     public void setImmersive(IBinder token, boolean immersive) {
13399         synchronized(this) {
13400             final ActivityRecord r = ActivityRecord.isInStackLocked(token);
13401             if (r == null) {
13402                 throw new IllegalArgumentException();
13403             }
13404             r.immersive = immersive;
13405
13406             // update associated state if we're frontmost
13407             if (r == mStackSupervisor.getResumedActivityLocked()) {
13408                 if (DEBUG_IMMERSIVE) Slog.d(TAG_IMMERSIVE, "Frontmost changed immersion: "+ r);
13409                 applyUpdateLockStateLocked(r);
13410             }
13411         }
13412     }
13413
13414     @Override
13415     public boolean isImmersive(IBinder token) {
13416         synchronized (this) {
13417             ActivityRecord r = ActivityRecord.isInStackLocked(token);
13418             if (r == null) {
13419                 throw new IllegalArgumentException();
13420             }
13421             return r.immersive;
13422         }
13423     }
13424
13425     @Override
13426     public void setVrThread(int tid) {
13427         enforceSystemHasVrFeature();
13428         synchronized (this) {
13429             synchronized (mPidsSelfLocked) {
13430                 final int pid = Binder.getCallingPid();
13431                 final ProcessRecord proc = mPidsSelfLocked.get(pid);
13432                 mVrController.setVrThreadLocked(tid, pid, proc);
13433             }
13434         }
13435     }
13436
13437     @Override
13438     public void setPersistentVrThread(int tid) {
13439         if (checkCallingPermission(permission.RESTRICTED_VR_ACCESS) != PERMISSION_GRANTED) {
13440             final String msg = "Permission Denial: setPersistentVrThread() from pid="
13441                     + Binder.getCallingPid()
13442                     + ", uid=" + Binder.getCallingUid()
13443                     + " requires " + permission.RESTRICTED_VR_ACCESS;
13444             Slog.w(TAG, msg);
13445             throw new SecurityException(msg);
13446         }
13447         enforceSystemHasVrFeature();
13448         synchronized (this) {
13449             synchronized (mPidsSelfLocked) {
13450                 final int pid = Binder.getCallingPid();
13451                 final ProcessRecord proc = mPidsSelfLocked.get(pid);
13452                 mVrController.setPersistentVrThreadLocked(tid, pid, proc);
13453             }
13454         }
13455     }
13456
13457     /**
13458      * Schedule the given thread a normal scheduling priority.
13459      *
13460      * @param newTid the tid of the thread to adjust the scheduling of.
13461      * @param suppressLogs {@code true} if any error logging should be disabled.
13462      *
13463      * @return {@code true} if this succeeded.
13464      */
13465     static boolean scheduleAsRegularPriority(int tid, boolean suppressLogs) {
13466         try {
13467             Process.setThreadScheduler(tid, Process.SCHED_OTHER, 0);
13468             return true;
13469         } catch (IllegalArgumentException e) {
13470             if (!suppressLogs) {
13471                 Slog.w(TAG, "Failed to set scheduling policy, thread does not exist:\n" + e);
13472             }
13473         }
13474         return false;
13475     }
13476
13477     /**
13478      * Schedule the given thread an FIFO scheduling priority.
13479      *
13480      * @param newTid the tid of the thread to adjust the scheduling of.
13481      * @param suppressLogs {@code true} if any error logging should be disabled.
13482      *
13483      * @return {@code true} if this succeeded.
13484      */
13485     static boolean scheduleAsFifoPriority(int tid, boolean suppressLogs) {
13486         try {
13487             Process.setThreadScheduler(tid, Process.SCHED_FIFO | Process.SCHED_RESET_ON_FORK, 1);
13488             return true;
13489         } catch (IllegalArgumentException e) {
13490             if (!suppressLogs) {
13491                 Slog.w(TAG, "Failed to set scheduling policy, thread does not exist:\n" + e);
13492             }
13493         }
13494         return false;
13495     }
13496
13497     /**
13498      * Check that we have the features required for VR-related API calls, and throw an exception if
13499      * not.
13500      */
13501     private void enforceSystemHasVrFeature() {
13502         if (!mContext.getPackageManager().hasSystemFeature(PackageManager.FEATURE_VR_MODE)) {
13503             throw new UnsupportedOperationException("VR mode not supported on this device!");
13504         }
13505     }
13506
13507     @Override
13508     public void setRenderThread(int tid) {
13509         synchronized (this) {
13510             ProcessRecord proc;
13511             int pid = Binder.getCallingPid();
13512             if (pid == Process.myPid()) {
13513                 demoteSystemServerRenderThread(tid);
13514                 return;
13515             }
13516             synchronized (mPidsSelfLocked) {
13517                 proc = mPidsSelfLocked.get(pid);
13518                 if (proc != null && proc.renderThreadTid == 0 && tid > 0) {
13519                     // ensure the tid belongs to the process
13520                     if (!isThreadInProcess(pid, tid)) {
13521                         throw new IllegalArgumentException(
13522                             "Render thread does not belong to process");
13523                     }
13524                     proc.renderThreadTid = tid;
13525                     if (DEBUG_OOM_ADJ) {
13526                         Slog.d("UI_FIFO", "Set RenderThread tid " + tid + " for pid " + pid);
13527                     }
13528                     // promote to FIFO now
13529                     if (proc.curSchedGroup == ProcessList.SCHED_GROUP_TOP_APP) {
13530                         if (DEBUG_OOM_ADJ) Slog.d("UI_FIFO", "Promoting " + tid + "out of band");
13531                         if (mUseFifoUiScheduling) {
13532                             setThreadScheduler(proc.renderThreadTid,
13533                                 SCHED_FIFO | SCHED_RESET_ON_FORK, 1);
13534                         } else {
13535                             setThreadPriority(proc.renderThreadTid, TOP_APP_PRIORITY_BOOST);
13536                         }
13537                     }
13538                 } else {
13539                     if (DEBUG_OOM_ADJ) {
13540                         Slog.d("UI_FIFO", "Didn't set thread from setRenderThread? " +
13541                                "PID: " + pid + ", TID: " + tid + " FIFO: " +
13542                                mUseFifoUiScheduling);
13543                     }
13544                 }
13545             }
13546         }
13547     }
13548
13549     /**
13550      * We only use RenderThread in system_server to store task snapshots to the disk, which should
13551      * happen in the background. Thus, demote render thread from system_server to a lower priority.
13552      *
13553      * @param tid the tid of the RenderThread
13554      */
13555     private void demoteSystemServerRenderThread(int tid) {
13556         setThreadPriority(tid, Process.THREAD_PRIORITY_BACKGROUND);
13557     }
13558
13559     @Override
13560     public int setVrMode(IBinder token, boolean enabled, ComponentName packageName) {
13561         if (!mContext.getPackageManager().hasSystemFeature(PackageManager.FEATURE_VR_MODE)) {
13562             throw new UnsupportedOperationException("VR mode not supported on this device!");
13563         }
13564
13565         final VrManagerInternal vrService = LocalServices.getService(VrManagerInternal.class);
13566
13567         ActivityRecord r;
13568         synchronized (this) {
13569             r = ActivityRecord.isInStackLocked(token);
13570         }
13571
13572         if (r == null) {
13573             throw new IllegalArgumentException();
13574         }
13575
13576         int err;
13577         if ((err = vrService.hasVrPackage(packageName, r.userId)) !=
13578                 VrManagerInternal.NO_ERROR) {
13579             return err;
13580         }
13581
13582         synchronized(this) {
13583             r.requestedVrComponent = (enabled) ? packageName : null;
13584
13585             // Update associated state if this activity is currently focused
13586             if (r == mStackSupervisor.getResumedActivityLocked()) {
13587                 applyUpdateVrModeLocked(r);
13588             }
13589             return 0;
13590         }
13591     }
13592
13593     @Override
13594     public boolean isVrModePackageEnabled(ComponentName packageName) {
13595         if (!mContext.getPackageManager().hasSystemFeature(PackageManager.FEATURE_VR_MODE)) {
13596             throw new UnsupportedOperationException("VR mode not supported on this device!");
13597         }
13598
13599         final VrManagerInternal vrService = LocalServices.getService(VrManagerInternal.class);
13600
13601         return vrService.hasVrPackage(packageName, UserHandle.getCallingUserId()) ==
13602                 VrManagerInternal.NO_ERROR;
13603     }
13604
13605     public boolean isTopActivityImmersive() {
13606         enforceNotIsolatedCaller("startActivity");
13607         synchronized (this) {
13608             ActivityRecord r = getFocusedStack().topRunningActivityLocked();
13609             return (r != null) ? r.immersive : false;
13610         }
13611     }
13612
13613     /**
13614      * @return whether the system should disable UI modes incompatible with VR mode.
13615      */
13616     boolean shouldDisableNonVrUiLocked() {
13617         return mVrController.shouldDisableNonVrUiLocked();
13618     }
13619
13620     @Override
13621     public boolean isTopOfTask(IBinder token) {
13622         synchronized (this) {
13623             ActivityRecord r = ActivityRecord.isInStackLocked(token);
13624             if (r == null) {
13625                 throw new IllegalArgumentException();
13626             }
13627             return r.getTask().getTopActivity() == r;
13628         }
13629     }
13630
13631     @Override
13632     public void setHasTopUi(boolean hasTopUi) throws RemoteException {
13633         if (checkCallingPermission(permission.INTERNAL_SYSTEM_WINDOW) != PERMISSION_GRANTED) {
13634             String msg = "Permission Denial: setHasTopUi() from pid="
13635                     + Binder.getCallingPid()
13636                     + ", uid=" + Binder.getCallingUid()
13637                     + " requires " + permission.INTERNAL_SYSTEM_WINDOW;
13638             Slog.w(TAG, msg);
13639             throw new SecurityException(msg);
13640         }
13641         final int pid = Binder.getCallingPid();
13642         final long origId = Binder.clearCallingIdentity();
13643         try {
13644             synchronized (this) {
13645                 boolean changed = false;
13646                 ProcessRecord pr;
13647                 synchronized (mPidsSelfLocked) {
13648                     pr = mPidsSelfLocked.get(pid);
13649                     if (pr == null) {
13650                         Slog.w(TAG, "setHasTopUi called on unknown pid: " + pid);
13651                         return;
13652                     }
13653                     if (pr.hasTopUi != hasTopUi) {
13654                         if (DEBUG_OOM_ADJ) {
13655                             Slog.d(TAG, "Setting hasTopUi=" + hasTopUi + " for pid=" + pid);
13656                         }
13657                         pr.hasTopUi = hasTopUi;
13658                         changed = true;
13659                     }
13660                 }
13661                 if (changed) {
13662                     updateOomAdjLocked(pr, true);
13663                 }
13664             }
13665         } finally {
13666             Binder.restoreCallingIdentity(origId);
13667         }
13668     }
13669
13670     public final void enterSafeMode() {
13671         synchronized(this) {
13672             // It only makes sense to do this before the system is ready
13673             // and started launching other packages.
13674             if (!mSystemReady) {
13675                 try {
13676                     AppGlobals.getPackageManager().enterSafeMode();
13677                 } catch (RemoteException e) {
13678                 }
13679             }
13680
13681             mSafeMode = true;
13682         }
13683     }
13684
13685     public final void showSafeModeOverlay() {
13686         View v = LayoutInflater.from(mContext).inflate(
13687                 com.android.internal.R.layout.safe_mode, null);
13688         WindowManager.LayoutParams lp = new WindowManager.LayoutParams();
13689         lp.type = WindowManager.LayoutParams.TYPE_SECURE_SYSTEM_OVERLAY;
13690         lp.width = WindowManager.LayoutParams.WRAP_CONTENT;
13691         lp.height = WindowManager.LayoutParams.WRAP_CONTENT;
13692         lp.gravity = Gravity.BOTTOM | Gravity.START;
13693         lp.format = v.getBackground().getOpacity();
13694         lp.flags = WindowManager.LayoutParams.FLAG_NOT_FOCUSABLE
13695                 | WindowManager.LayoutParams.FLAG_NOT_TOUCHABLE;
13696         lp.privateFlags |= WindowManager.LayoutParams.PRIVATE_FLAG_SHOW_FOR_ALL_USERS;
13697         ((WindowManager)mContext.getSystemService(
13698                 Context.WINDOW_SERVICE)).addView(v, lp);
13699     }
13700
13701     public void noteWakeupAlarm(IIntentSender sender, int sourceUid, String sourcePkg, String tag) {
13702         if (sender != null && !(sender instanceof PendingIntentRecord)) {
13703             return;
13704         }
13705         final PendingIntentRecord rec = (PendingIntentRecord)sender;
13706         final BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
13707         synchronized (stats) {
13708             if (mBatteryStatsService.isOnBattery()) {
13709                 mBatteryStatsService.enforceCallingPermission();
13710                 int MY_UID = Binder.getCallingUid();
13711                 final int uid;
13712                 if (sender == null) {
13713                     uid = sourceUid;
13714                 } else {
13715                     uid = rec.uid == MY_UID ? SYSTEM_UID : rec.uid;
13716                 }
13717                 BatteryStatsImpl.Uid.Pkg pkg =
13718                     stats.getPackageStatsLocked(sourceUid >= 0 ? sourceUid : uid,
13719                             sourcePkg != null ? sourcePkg : rec.key.packageName);
13720                 pkg.noteWakeupAlarmLocked(tag);
13721             }
13722         }
13723     }
13724
13725     public void noteAlarmStart(IIntentSender sender, int sourceUid, String tag) {
13726         if (sender != null && !(sender instanceof PendingIntentRecord)) {
13727             return;
13728         }
13729         final PendingIntentRecord rec = (PendingIntentRecord)sender;
13730         final BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
13731         synchronized (stats) {
13732             mBatteryStatsService.enforceCallingPermission();
13733             int MY_UID = Binder.getCallingUid();
13734             final int uid;
13735             if (sender == null) {
13736                 uid = sourceUid;
13737             } else {
13738                 uid = rec.uid == MY_UID ? SYSTEM_UID : rec.uid;
13739             }
13740             mBatteryStatsService.noteAlarmStart(tag, sourceUid >= 0 ? sourceUid : uid);
13741         }
13742     }
13743
13744     public void noteAlarmFinish(IIntentSender sender, int sourceUid, String tag) {
13745         if (sender != null && !(sender instanceof PendingIntentRecord)) {
13746             return;
13747         }
13748         final PendingIntentRecord rec = (PendingIntentRecord)sender;
13749         final BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
13750         synchronized (stats) {
13751             mBatteryStatsService.enforceCallingPermission();
13752             int MY_UID = Binder.getCallingUid();
13753             final int uid;
13754             if (sender == null) {
13755                 uid = sourceUid;
13756             } else {
13757                 uid = rec.uid == MY_UID ? SYSTEM_UID : rec.uid;
13758             }
13759             mBatteryStatsService.noteAlarmFinish(tag, sourceUid >= 0 ? sourceUid : uid);
13760         }
13761     }
13762
13763     public boolean killPids(int[] pids, String pReason, boolean secure) {
13764         if (Binder.getCallingUid() != SYSTEM_UID) {
13765             throw new SecurityException("killPids only available to the system");
13766         }
13767         String reason = (pReason == null) ? "Unknown" : pReason;
13768         // XXX Note: don't acquire main activity lock here, because the window
13769         // manager calls in with its locks held.
13770
13771         boolean killed = false;
13772         synchronized (mPidsSelfLocked) {
13773             int worstType = 0;
13774             for (int i=0; i<pids.length; i++) {
13775                 ProcessRecord proc = mPidsSelfLocked.get(pids[i]);
13776                 if (proc != null) {
13777                     int type = proc.setAdj;
13778                     if (type > worstType) {
13779                         worstType = type;
13780                     }
13781                 }
13782             }
13783
13784             // If the worst oom_adj is somewhere in the cached proc LRU range,
13785             // then constrain it so we will kill all cached procs.
13786             if (worstType < ProcessList.CACHED_APP_MAX_ADJ
13787                     && worstType > ProcessList.CACHED_APP_MIN_ADJ) {
13788                 worstType = ProcessList.CACHED_APP_MIN_ADJ;
13789             }
13790
13791             // If this is not a secure call, don't let it kill processes that
13792             // are important.
13793             if (!secure && worstType < ProcessList.SERVICE_ADJ) {
13794                 worstType = ProcessList.SERVICE_ADJ;
13795             }
13796
13797             Slog.w(TAG, "Killing processes " + reason + " at adjustment " + worstType);
13798             for (int i=0; i<pids.length; i++) {
13799                 ProcessRecord proc = mPidsSelfLocked.get(pids[i]);
13800                 if (proc == null) {
13801                     continue;
13802                 }
13803                 int adj = proc.setAdj;
13804                 if (adj >= worstType && !proc.killedByAm) {
13805                     proc.kill(reason, true);
13806                     killed = true;
13807                 }
13808             }
13809         }
13810         return killed;
13811     }
13812
13813     @Override
13814     public void killUid(int appId, int userId, String reason) {
13815         enforceCallingPermission(Manifest.permission.KILL_UID, "killUid");
13816         synchronized (this) {
13817             final long identity = Binder.clearCallingIdentity();
13818             try {
13819                 killPackageProcessesLocked(null, appId, userId,
13820                         ProcessList.PERSISTENT_PROC_ADJ, false, true, true, true,
13821                         reason != null ? reason : "kill uid");
13822             } finally {
13823                 Binder.restoreCallingIdentity(identity);
13824             }
13825         }
13826     }
13827
13828     @Override
13829     public boolean killProcessesBelowForeground(String reason) {
13830         if (Binder.getCallingUid() != SYSTEM_UID) {
13831             throw new SecurityException("killProcessesBelowForeground() only available to system");
13832         }
13833
13834         return killProcessesBelowAdj(ProcessList.FOREGROUND_APP_ADJ, reason);
13835     }
13836
13837     private boolean killProcessesBelowAdj(int belowAdj, String reason) {
13838         if (Binder.getCallingUid() != SYSTEM_UID) {
13839             throw new SecurityException("killProcessesBelowAdj() only available to system");
13840         }
13841
13842         boolean killed = false;
13843         synchronized (mPidsSelfLocked) {
13844             final int size = mPidsSelfLocked.size();
13845             for (int i = 0; i < size; i++) {
13846                 final int pid = mPidsSelfLocked.keyAt(i);
13847                 final ProcessRecord proc = mPidsSelfLocked.valueAt(i);
13848                 if (proc == null) continue;
13849
13850                 final int adj = proc.setAdj;
13851                 if (adj > belowAdj && !proc.killedByAm) {
13852                     proc.kill(reason, true);
13853                     killed = true;
13854                 }
13855             }
13856         }
13857         return killed;
13858     }
13859
13860     @Override
13861     public void hang(final IBinder who, boolean allowRestart) {
13862         if (checkCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER)
13863                 != PackageManager.PERMISSION_GRANTED) {
13864             throw new SecurityException("Requires permission "
13865                     + android.Manifest.permission.SET_ACTIVITY_WATCHER);
13866         }
13867
13868         final IBinder.DeathRecipient death = new DeathRecipient() {
13869             @Override
13870             public void binderDied() {
13871                 synchronized (this) {
13872                     notifyAll();
13873                 }
13874             }
13875         };
13876
13877         try {
13878             who.linkToDeath(death, 0);
13879         } catch (RemoteException e) {
13880             Slog.w(TAG, "hang: given caller IBinder is already dead.");
13881             return;
13882         }
13883
13884         synchronized (this) {
13885             Watchdog.getInstance().setAllowRestart(allowRestart);
13886             Slog.i(TAG, "Hanging system process at request of pid " + Binder.getCallingPid());
13887             synchronized (death) {
13888                 while (who.isBinderAlive()) {
13889                     try {
13890                         death.wait();
13891                     } catch (InterruptedException e) {
13892                     }
13893                 }
13894             }
13895             Watchdog.getInstance().setAllowRestart(true);
13896         }
13897     }
13898
13899     @Override
13900     public void restart() {
13901         if (checkCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER)
13902                 != PackageManager.PERMISSION_GRANTED) {
13903             throw new SecurityException("Requires permission "
13904                     + android.Manifest.permission.SET_ACTIVITY_WATCHER);
13905         }
13906
13907         Log.i(TAG, "Sending shutdown broadcast...");
13908
13909         BroadcastReceiver br = new BroadcastReceiver() {
13910             @Override public void onReceive(Context context, Intent intent) {
13911                 // Now the broadcast is done, finish up the low-level shutdown.
13912                 Log.i(TAG, "Shutting down activity manager...");
13913                 shutdown(10000);
13914                 Log.i(TAG, "Shutdown complete, restarting!");
13915                 killProcess(myPid());
13916                 System.exit(10);
13917             }
13918         };
13919
13920         // First send the high-level shut down broadcast.
13921         Intent intent = new Intent(Intent.ACTION_SHUTDOWN);
13922         intent.addFlags(Intent.FLAG_RECEIVER_FOREGROUND);
13923         intent.putExtra(Intent.EXTRA_SHUTDOWN_USERSPACE_ONLY, true);
13924         /* For now we are not doing a clean shutdown, because things seem to get unhappy.
13925         mContext.sendOrderedBroadcastAsUser(intent,
13926                 UserHandle.ALL, null, br, mHandler, 0, null, null);
13927         */
13928         br.onReceive(mContext, intent);
13929     }
13930
13931     private long getLowRamTimeSinceIdle(long now) {
13932         return mLowRamTimeSinceLastIdle + (mLowRamStartTime > 0 ? (now-mLowRamStartTime) : 0);
13933     }
13934
13935     @Override
13936     public void performIdleMaintenance() {
13937         if (checkCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER)
13938                 != PackageManager.PERMISSION_GRANTED) {
13939             throw new SecurityException("Requires permission "
13940                     + android.Manifest.permission.SET_ACTIVITY_WATCHER);
13941         }
13942
13943         synchronized (this) {
13944             final long now = SystemClock.uptimeMillis();
13945             final long timeSinceLastIdle = now - mLastIdleTime;
13946             final long lowRamSinceLastIdle = getLowRamTimeSinceIdle(now);
13947             mLastIdleTime = now;
13948             mLowRamTimeSinceLastIdle = 0;
13949             if (mLowRamStartTime != 0) {
13950                 mLowRamStartTime = now;
13951             }
13952
13953             StringBuilder sb = new StringBuilder(128);
13954             sb.append("Idle maintenance over ");
13955             TimeUtils.formatDuration(timeSinceLastIdle, sb);
13956             sb.append(" low RAM for ");
13957             TimeUtils.formatDuration(lowRamSinceLastIdle, sb);
13958             Slog.i(TAG, sb.toString());
13959
13960             // If at least 1/3 of our time since the last idle period has been spent
13961             // with RAM low, then we want to kill processes.
13962             boolean doKilling = lowRamSinceLastIdle > (timeSinceLastIdle/3);
13963
13964             for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) {
13965                 ProcessRecord proc = mLruProcesses.get(i);
13966                 if (proc.notCachedSinceIdle) {
13967                     if (proc.setProcState != ActivityManager.PROCESS_STATE_TOP_SLEEPING
13968                             && proc.setProcState >= ActivityManager.PROCESS_STATE_FOREGROUND_SERVICE
13969                             && proc.setProcState <= ActivityManager.PROCESS_STATE_SERVICE) {
13970                         if (doKilling && proc.initialIdlePss != 0
13971                                 && proc.lastPss > ((proc.initialIdlePss*3)/2)) {
13972                             sb = new StringBuilder(128);
13973                             sb.append("Kill");
13974                             sb.append(proc.processName);
13975                             sb.append(" in idle maint: pss=");
13976                             sb.append(proc.lastPss);
13977                             sb.append(", swapPss=");
13978                             sb.append(proc.lastSwapPss);
13979                             sb.append(", initialPss=");
13980                             sb.append(proc.initialIdlePss);
13981                             sb.append(", period=");
13982                             TimeUtils.formatDuration(timeSinceLastIdle, sb);
13983                             sb.append(", lowRamPeriod=");
13984                             TimeUtils.formatDuration(lowRamSinceLastIdle, sb);
13985                             Slog.wtfQuiet(TAG, sb.toString());
13986                             proc.kill("idle maint (pss " + proc.lastPss
13987                                     + " from " + proc.initialIdlePss + ")", true);
13988                         }
13989                     }
13990                 } else if (proc.setProcState < ActivityManager.PROCESS_STATE_HOME
13991                         && proc.setProcState >= ActivityManager.PROCESS_STATE_PERSISTENT) {
13992                     proc.notCachedSinceIdle = true;
13993                     proc.initialIdlePss = 0;
13994                     proc.nextPssTime = ProcessList.computeNextPssTime(proc.setProcState, true,
13995                             mTestPssMode, isSleepingLocked(), now);
13996                 }
13997             }
13998
13999             mHandler.removeMessages(REQUEST_ALL_PSS_MSG);
14000             mHandler.sendEmptyMessageDelayed(REQUEST_ALL_PSS_MSG, 2*60*1000);
14001         }
14002     }
14003
14004     @Override
14005     public void sendIdleJobTrigger() {
14006         if (checkCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER)
14007                 != PackageManager.PERMISSION_GRANTED) {
14008             throw new SecurityException("Requires permission "
14009                     + android.Manifest.permission.SET_ACTIVITY_WATCHER);
14010         }
14011
14012         final long ident = Binder.clearCallingIdentity();
14013         try {
14014             Intent intent = new Intent(ACTION_TRIGGER_IDLE)
14015                     .setPackage("android")
14016                     .addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY);
14017             broadcastIntent(null, intent, null, null, 0, null, null, null,
14018                     android.app.AppOpsManager.OP_NONE, null, true, false, UserHandle.USER_ALL);
14019         } finally {
14020             Binder.restoreCallingIdentity(ident);
14021         }
14022     }
14023
14024     private void retrieveSettings() {
14025         final ContentResolver resolver = mContext.getContentResolver();
14026         final boolean freeformWindowManagement =
14027                 mContext.getPackageManager().hasSystemFeature(FEATURE_FREEFORM_WINDOW_MANAGEMENT)
14028                         || Settings.Global.getInt(
14029                                 resolver, DEVELOPMENT_ENABLE_FREEFORM_WINDOWS_SUPPORT, 0) != 0;
14030         final boolean supportsPictureInPicture =
14031                 mContext.getPackageManager().hasSystemFeature(FEATURE_PICTURE_IN_PICTURE);
14032
14033         final boolean supportsMultiWindow = ActivityManager.supportsMultiWindow(mContext);
14034         final boolean supportsSplitScreenMultiWindow =
14035                 ActivityManager.supportsSplitScreenMultiWindow(mContext);
14036         final boolean supportsMultiDisplay = mContext.getPackageManager()
14037                 .hasSystemFeature(FEATURE_ACTIVITIES_ON_SECONDARY_DISPLAYS);
14038         final String debugApp = Settings.Global.getString(resolver, DEBUG_APP);
14039         final boolean waitForDebugger = Settings.Global.getInt(resolver, WAIT_FOR_DEBUGGER, 0) != 0;
14040         final boolean alwaysFinishActivities =
14041                 Settings.Global.getInt(resolver, ALWAYS_FINISH_ACTIVITIES, 0) != 0;
14042         final boolean forceRtl = Settings.Global.getInt(resolver, DEVELOPMENT_FORCE_RTL, 0) != 0;
14043         final boolean forceResizable = Settings.Global.getInt(
14044                 resolver, DEVELOPMENT_FORCE_RESIZABLE_ACTIVITIES, 0) != 0;
14045         final long waitForNetworkTimeoutMs = Settings.Global.getLong(resolver,
14046                 NETWORK_ACCESS_TIMEOUT_MS, NETWORK_ACCESS_TIMEOUT_DEFAULT_MS);
14047         final boolean supportsLeanbackOnly =
14048                 mContext.getPackageManager().hasSystemFeature(FEATURE_LEANBACK_ONLY);
14049
14050         // Transfer any global setting for forcing RTL layout, into a System Property
14051         SystemProperties.set(DEVELOPMENT_FORCE_RTL, forceRtl ? "1":"0");
14052
14053         final Configuration configuration = new Configuration();
14054         Settings.System.getConfiguration(resolver, configuration);
14055         if (forceRtl) {
14056             // This will take care of setting the correct layout direction flags
14057             configuration.setLayoutDirection(configuration.locale);
14058         }
14059
14060         synchronized (this) {
14061             mDebugApp = mOrigDebugApp = debugApp;
14062             mWaitForDebugger = mOrigWaitForDebugger = waitForDebugger;
14063             mAlwaysFinishActivities = alwaysFinishActivities;
14064             mSupportsLeanbackOnly = supportsLeanbackOnly;
14065             mForceResizableActivities = forceResizable;
14066             final boolean multiWindowFormEnabled = freeformWindowManagement
14067                     || supportsSplitScreenMultiWindow
14068                     || supportsPictureInPicture
14069                     || supportsMultiDisplay;
14070             if ((supportsMultiWindow || forceResizable) && multiWindowFormEnabled) {
14071                 mSupportsMultiWindow = true;
14072                 mSupportsFreeformWindowManagement = freeformWindowManagement;
14073                 mSupportsSplitScreenMultiWindow = supportsSplitScreenMultiWindow;
14074                 mSupportsPictureInPicture = supportsPictureInPicture;
14075                 mSupportsMultiDisplay = supportsMultiDisplay;
14076             } else {
14077                 mSupportsMultiWindow = false;
14078                 mSupportsFreeformWindowManagement = false;
14079                 mSupportsSplitScreenMultiWindow = false;
14080                 mSupportsPictureInPicture = false;
14081                 mSupportsMultiDisplay = false;
14082             }
14083             mWindowManager.setForceResizableTasks(mForceResizableActivities);
14084             mWindowManager.setSupportsPictureInPicture(mSupportsPictureInPicture);
14085             // This happens before any activities are started, so we can change global configuration
14086             // in-place.
14087             updateConfigurationLocked(configuration, null, true);
14088             final Configuration globalConfig = getGlobalConfiguration();
14089             if (DEBUG_CONFIGURATION) Slog.v(TAG_CONFIGURATION, "Initial config: " + globalConfig);
14090
14091             // Load resources only after the current configuration has been set.
14092             final Resources res = mContext.getResources();
14093             mHasRecents = res.getBoolean(com.android.internal.R.bool.config_hasRecents);
14094             mThumbnailWidth = res.getDimensionPixelSize(
14095                     com.android.internal.R.dimen.thumbnail_width);
14096             mThumbnailHeight = res.getDimensionPixelSize(
14097                     com.android.internal.R.dimen.thumbnail_height);
14098             mAppErrors.loadAppsNotReportingCrashesFromConfigLocked(res.getString(
14099                     com.android.internal.R.string.config_appsNotReportingCrashes));
14100             mUserController.mUserSwitchUiEnabled = !res.getBoolean(
14101                     com.android.internal.R.bool.config_customUserSwitchUi);
14102             if ((globalConfig.uiMode & UI_MODE_TYPE_TELEVISION) == UI_MODE_TYPE_TELEVISION) {
14103                 mFullscreenThumbnailScale = (float) res
14104                     .getInteger(com.android.internal.R.integer.thumbnail_width_tv) /
14105                     (float) globalConfig.screenWidthDp;
14106             } else {
14107                 mFullscreenThumbnailScale = res.getFraction(
14108                     com.android.internal.R.fraction.thumbnail_fullscreen_scale, 1, 1);
14109             }
14110             mWaitForNetworkTimeoutMs = waitForNetworkTimeoutMs;
14111         }
14112     }
14113
14114     public void systemReady(final Runnable goingCallback, BootTimingsTraceLog traceLog) {
14115         traceLog.traceBegin("PhaseActivityManagerReady");
14116         synchronized(this) {
14117             if (mSystemReady) {
14118                 // If we're done calling all the receivers, run the next "boot phase" passed in
14119                 // by the SystemServer
14120                 if (goingCallback != null) {
14121                     goingCallback.run();
14122                 }
14123                 return;
14124             }
14125
14126             mLocalDeviceIdleController
14127                     = LocalServices.getService(DeviceIdleController.LocalService.class);
14128             mAssistUtils = new AssistUtils(mContext);
14129             mVrController.onSystemReady();
14130             // Make sure we have the current profile info, since it is needed for security checks.
14131             mUserController.onSystemReady();
14132             mRecentTasks.onSystemReadyLocked();
14133             mAppOpsService.systemReady();
14134             mSystemReady = true;
14135         }
14136
14137         ArrayList<ProcessRecord> procsToKill = null;
14138         synchronized(mPidsSelfLocked) {
14139             for (int i=mPidsSelfLocked.size()-1; i>=0; i--) {
14140                 ProcessRecord proc = mPidsSelfLocked.valueAt(i);
14141                 if (!isAllowedWhileBooting(proc.info)){
14142                     if (procsToKill == null) {
14143                         procsToKill = new ArrayList<ProcessRecord>();
14144                     }
14145                     procsToKill.add(proc);
14146                 }
14147             }
14148         }
14149
14150         synchronized(this) {
14151             if (procsToKill != null) {
14152                 for (int i=procsToKill.size()-1; i>=0; i--) {
14153                     ProcessRecord proc = procsToKill.get(i);
14154                     Slog.i(TAG, "Removing system update proc: " + proc);
14155                     removeProcessLocked(proc, true, false, "system update done");
14156                 }
14157             }
14158
14159             // Now that we have cleaned up any update processes, we
14160             // are ready to start launching real processes and know that
14161             // we won't trample on them any more.
14162             mProcessesReady = true;
14163         }
14164
14165         Slog.i(TAG, "System now ready");
14166         EventLog.writeEvent(EventLogTags.BOOT_PROGRESS_AMS_READY,
14167             SystemClock.uptimeMillis());
14168
14169         synchronized(this) {
14170             // Make sure we have no pre-ready processes sitting around.
14171
14172             if (mFactoryTest == FactoryTest.FACTORY_TEST_LOW_LEVEL) {
14173                 ResolveInfo ri = mContext.getPackageManager()
14174                         .resolveActivity(new Intent(Intent.ACTION_FACTORY_TEST),
14175                                 STOCK_PM_FLAGS);
14176                 CharSequence errorMsg = null;
14177                 if (ri != null) {
14178                     ActivityInfo ai = ri.activityInfo;
14179                     ApplicationInfo app = ai.applicationInfo;
14180                     if ((app.flags&ApplicationInfo.FLAG_SYSTEM) != 0) {
14181                         mTopAction = Intent.ACTION_FACTORY_TEST;
14182                         mTopData = null;
14183                         mTopComponent = new ComponentName(app.packageName,
14184                                 ai.name);
14185                     } else {
14186                         errorMsg = mContext.getResources().getText(
14187                                 com.android.internal.R.string.factorytest_not_system);
14188                     }
14189                 } else {
14190                     errorMsg = mContext.getResources().getText(
14191                             com.android.internal.R.string.factorytest_no_action);
14192                 }
14193                 if (errorMsg != null) {
14194                     mTopAction = null;
14195                     mTopData = null;
14196                     mTopComponent = null;
14197                     Message msg = Message.obtain();
14198                     msg.what = SHOW_FACTORY_ERROR_UI_MSG;
14199                     msg.getData().putCharSequence("msg", errorMsg);
14200                     mUiHandler.sendMessage(msg);
14201                 }
14202             }
14203         }
14204
14205         retrieveSettings();
14206         final int currentUserId;
14207         synchronized (this) {
14208             currentUserId = mUserController.getCurrentUserIdLocked();
14209             readGrantedUriPermissionsLocked();
14210         }
14211
14212         if (goingCallback != null) goingCallback.run();
14213         traceLog.traceBegin("ActivityManagerStartApps");
14214         mBatteryStatsService.noteEvent(BatteryStats.HistoryItem.EVENT_USER_RUNNING_START,
14215                 Integer.toString(currentUserId), currentUserId);
14216         mBatteryStatsService.noteEvent(BatteryStats.HistoryItem.EVENT_USER_FOREGROUND_START,
14217                 Integer.toString(currentUserId), currentUserId);
14218         mSystemServiceManager.startUser(currentUserId);
14219
14220         synchronized (this) {
14221             // Only start up encryption-aware persistent apps; once user is
14222             // unlocked we'll come back around and start unaware apps
14223             startPersistentApps(PackageManager.MATCH_DIRECT_BOOT_AWARE);
14224
14225             // Start up initial activity.
14226             mBooting = true;
14227             // Enable home activity for system user, so that the system can always boot. We don't
14228             // do this when the system user is not setup since the setup wizard should be the one
14229             // to handle home activity in this case.
14230             if (UserManager.isSplitSystemUser() &&
14231                     Settings.Secure.getInt(mContext.getContentResolver(),
14232                          Settings.Secure.USER_SETUP_COMPLETE, 0) != 0) {
14233                 ComponentName cName = new ComponentName(mContext, SystemUserHomeActivity.class);
14234                 try {
14235                     AppGlobals.getPackageManager().setComponentEnabledSetting(cName,
14236                             PackageManager.COMPONENT_ENABLED_STATE_ENABLED, 0,
14237                             UserHandle.USER_SYSTEM);
14238                 } catch (RemoteException e) {
14239                     throw e.rethrowAsRuntimeException();
14240                 }
14241             }
14242             startHomeActivityLocked(currentUserId, "systemReady");
14243
14244             try {
14245                 if (AppGlobals.getPackageManager().hasSystemUidErrors()) {
14246                     Slog.e(TAG, "UIDs on the system are inconsistent, you need to wipe your"
14247                             + " data partition or your device will be unstable.");
14248                     mUiHandler.obtainMessage(SHOW_UID_ERROR_UI_MSG).sendToTarget();
14249                 }
14250             } catch (RemoteException e) {
14251             }
14252
14253             if (!Build.isBuildConsistent()) {
14254                 Slog.e(TAG, "Build fingerprint is not consistent, warning user");
14255                 mUiHandler.obtainMessage(SHOW_FINGERPRINT_ERROR_UI_MSG).sendToTarget();
14256             }
14257
14258             long ident = Binder.clearCallingIdentity();
14259             try {
14260                 Intent intent = new Intent(Intent.ACTION_USER_STARTED);
14261                 intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY
14262                         | Intent.FLAG_RECEIVER_FOREGROUND);
14263                 intent.putExtra(Intent.EXTRA_USER_HANDLE, currentUserId);
14264                 broadcastIntentLocked(null, null, intent,
14265                         null, null, 0, null, null, null, AppOpsManager.OP_NONE,
14266                         null, false, false, MY_PID, SYSTEM_UID,
14267                         currentUserId);
14268                 intent = new Intent(Intent.ACTION_USER_STARTING);
14269                 intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY);
14270                 intent.putExtra(Intent.EXTRA_USER_HANDLE, currentUserId);
14271                 broadcastIntentLocked(null, null, intent,
14272                         null, new IIntentReceiver.Stub() {
14273                             @Override
14274                             public void performReceive(Intent intent, int resultCode, String data,
14275                                     Bundle extras, boolean ordered, boolean sticky, int sendingUser)
14276                                     throws RemoteException {
14277                             }
14278                         }, 0, null, null,
14279                         new String[] {INTERACT_ACROSS_USERS}, AppOpsManager.OP_NONE,
14280                         null, true, false, MY_PID, SYSTEM_UID, UserHandle.USER_ALL);
14281             } catch (Throwable t) {
14282                 Slog.wtf(TAG, "Failed sending first user broadcasts", t);
14283             } finally {
14284                 Binder.restoreCallingIdentity(ident);
14285             }
14286             mStackSupervisor.resumeFocusedStackTopActivityLocked();
14287             mUserController.sendUserSwitchBroadcastsLocked(-1, currentUserId);
14288             traceLog.traceEnd(); // ActivityManagerStartApps
14289             traceLog.traceEnd(); // PhaseActivityManagerReady
14290         }
14291     }
14292
14293     void killAppAtUsersRequest(ProcessRecord app, Dialog fromDialog) {
14294         synchronized (this) {
14295             mAppErrors.killAppAtUserRequestLocked(app, fromDialog);
14296         }
14297     }
14298
14299     void skipCurrentReceiverLocked(ProcessRecord app) {
14300         for (BroadcastQueue queue : mBroadcastQueues) {
14301             queue.skipCurrentReceiverLocked(app);
14302         }
14303     }
14304
14305     /**
14306      * Used by {@link com.android.internal.os.RuntimeInit} to report when an application crashes.
14307      * The application process will exit immediately after this call returns.
14308      * @param app object of the crashing app, null for the system server
14309      * @param crashInfo describing the exception
14310      */
14311     public void handleApplicationCrash(IBinder app,
14312             ApplicationErrorReport.ParcelableCrashInfo crashInfo) {
14313         ProcessRecord r = findAppProcess(app, "Crash");
14314         final String processName = app == null ? "system_server"
14315                 : (r == null ? "unknown" : r.processName);
14316
14317         handleApplicationCrashInner("crash", r, processName, crashInfo);
14318     }
14319
14320     /* Native crash reporting uses this inner version because it needs to be somewhat
14321      * decoupled from the AM-managed cleanup lifecycle
14322      */
14323     void handleApplicationCrashInner(String eventType, ProcessRecord r, String processName,
14324             ApplicationErrorReport.CrashInfo crashInfo) {
14325         EventLog.writeEvent(EventLogTags.AM_CRASH, Binder.getCallingPid(),
14326                 UserHandle.getUserId(Binder.getCallingUid()), processName,
14327                 r == null ? -1 : r.info.flags,
14328                 crashInfo.exceptionClassName,
14329                 crashInfo.exceptionMessage,
14330                 crashInfo.throwFileName,
14331                 crashInfo.throwLineNumber);
14332
14333         addErrorToDropBox(eventType, r, processName, null, null, null, null, null, crashInfo);
14334
14335         mAppErrors.crashApplication(r, crashInfo);
14336     }
14337
14338     public void handleApplicationStrictModeViolation(
14339             IBinder app,
14340             int violationMask,
14341             StrictMode.ViolationInfo info) {
14342         ProcessRecord r = findAppProcess(app, "StrictMode");
14343         if (r == null) {
14344             return;
14345         }
14346
14347         if ((violationMask & StrictMode.PENALTY_DROPBOX) != 0) {
14348             Integer stackFingerprint = info.hashCode();
14349             boolean logIt = true;
14350             synchronized (mAlreadyLoggedViolatedStacks) {
14351                 if (mAlreadyLoggedViolatedStacks.contains(stackFingerprint)) {
14352                     logIt = false;
14353                     // TODO: sub-sample into EventLog for these, with
14354                     // the info.durationMillis?  Then we'd get
14355                     // the relative pain numbers, without logging all
14356                     // the stack traces repeatedly.  We'd want to do
14357                     // likewise in the client code, which also does
14358                     // dup suppression, before the Binder call.
14359                 } else {
14360                     if (mAlreadyLoggedViolatedStacks.size() >= MAX_DUP_SUPPRESSED_STACKS) {
14361                         mAlreadyLoggedViolatedStacks.clear();
14362                     }
14363                     mAlreadyLoggedViolatedStacks.add(stackFingerprint);
14364                 }
14365             }
14366             if (logIt) {
14367                 logStrictModeViolationToDropBox(r, info);
14368             }
14369         }
14370
14371         if ((violationMask & StrictMode.PENALTY_DIALOG) != 0) {
14372             AppErrorResult result = new AppErrorResult();
14373             synchronized (this) {
14374                 final long origId = Binder.clearCallingIdentity();
14375
14376                 Message msg = Message.obtain();
14377                 msg.what = SHOW_STRICT_MODE_VIOLATION_UI_MSG;
14378                 HashMap<String, Object> data = new HashMap<String, Object>();
14379                 data.put("result", result);
14380                 data.put("app", r);
14381                 data.put("violationMask", violationMask);
14382                 data.put("info", info);
14383                 msg.obj = data;
14384                 mUiHandler.sendMessage(msg);
14385
14386                 Binder.restoreCallingIdentity(origId);
14387             }
14388             int res = result.get();
14389             Slog.w(TAG, "handleApplicationStrictModeViolation; res=" + res);
14390         }
14391     }
14392
14393     // Depending on the policy in effect, there could be a bunch of
14394     // these in quick succession so we try to batch these together to
14395     // minimize disk writes, number of dropbox entries, and maximize
14396     // compression, by having more fewer, larger records.
14397     private void logStrictModeViolationToDropBox(
14398             ProcessRecord process,
14399             StrictMode.ViolationInfo info) {
14400         if (info == null) {
14401             return;
14402         }
14403         final boolean isSystemApp = process == null ||
14404                 (process.info.flags & (ApplicationInfo.FLAG_SYSTEM |
14405                                        ApplicationInfo.FLAG_UPDATED_SYSTEM_APP)) != 0;
14406         final String processName = process == null ? "unknown" : process.processName;
14407         final String dropboxTag = isSystemApp ? "system_app_strictmode" : "data_app_strictmode";
14408         final DropBoxManager dbox = (DropBoxManager)
14409                 mContext.getSystemService(Context.DROPBOX_SERVICE);
14410
14411         // Exit early if the dropbox isn't configured to accept this report type.
14412         if (dbox == null || !dbox.isTagEnabled(dropboxTag)) return;
14413
14414         boolean bufferWasEmpty;
14415         boolean needsFlush;
14416         final StringBuilder sb = isSystemApp ? mStrictModeBuffer : new StringBuilder(1024);
14417         synchronized (sb) {
14418             bufferWasEmpty = sb.length() == 0;
14419             appendDropBoxProcessHeaders(process, processName, sb);
14420             sb.append("Build: ").append(Build.FINGERPRINT).append("\n");
14421             sb.append("System-App: ").append(isSystemApp).append("\n");
14422             sb.append("Uptime-Millis: ").append(info.violationUptimeMillis).append("\n");
14423             if (info.violationNumThisLoop != 0) {
14424                 sb.append("Loop-Violation-Number: ").append(info.violationNumThisLoop).append("\n");
14425             }
14426             if (info.numAnimationsRunning != 0) {
14427                 sb.append("Animations-Running: ").append(info.numAnimationsRunning).append("\n");
14428             }
14429             if (info.broadcastIntentAction != null) {
14430                 sb.append("Broadcast-Intent-Action: ").append(info.broadcastIntentAction).append("\n");
14431             }
14432             if (info.durationMillis != -1) {
14433                 sb.append("Duration-Millis: ").append(info.durationMillis).append("\n");
14434             }
14435             if (info.numInstances != -1) {
14436                 sb.append("Instance-Count: ").append(info.numInstances).append("\n");
14437             }
14438             if (info.tags != null) {
14439                 for (String tag : info.tags) {
14440                     sb.append("Span-Tag: ").append(tag).append("\n");
14441                 }
14442             }
14443             sb.append("\n");
14444             if (info.crashInfo != null && info.crashInfo.stackTrace != null) {
14445                 sb.append(info.crashInfo.stackTrace);
14446                 sb.append("\n");
14447             }
14448             if (info.message != null) {
14449                 sb.append(info.message);
14450                 sb.append("\n");
14451             }
14452
14453             // Only buffer up to ~64k.  Various logging bits truncate
14454             // things at 128k.
14455             needsFlush = (sb.length() > 64 * 1024);
14456         }
14457
14458         // Flush immediately if the buffer's grown too large, or this
14459         // is a non-system app.  Non-system apps are isolated with a
14460         // different tag & policy and not batched.
14461         //
14462         // Batching is useful during internal testing with
14463         // StrictMode settings turned up high.  Without batching,
14464         // thousands of separate files could be created on boot.
14465         if (!isSystemApp || needsFlush) {
14466             new Thread("Error dump: " + dropboxTag) {
14467                 @Override
14468                 public void run() {
14469                     String report;
14470                     synchronized (sb) {
14471                         report = sb.toString();
14472                         sb.delete(0, sb.length());
14473                         sb.trimToSize();
14474                     }
14475                     if (report.length() != 0) {
14476                         dbox.addText(dropboxTag, report);
14477                     }
14478                 }
14479             }.start();
14480             return;
14481         }
14482
14483         // System app batching:
14484         if (!bufferWasEmpty) {
14485             // An existing dropbox-writing thread is outstanding, so
14486             // we don't need to start it up.  The existing thread will
14487             // catch the buffer appends we just did.
14488             return;
14489         }
14490
14491         // Worker thread to both batch writes and to avoid blocking the caller on I/O.
14492         // (After this point, we shouldn't access AMS internal data structures.)
14493         new Thread("Error dump: " + dropboxTag) {
14494             @Override
14495             public void run() {
14496                 // 5 second sleep to let stacks arrive and be batched together
14497                 try {
14498                     Thread.sleep(5000);  // 5 seconds
14499                 } catch (InterruptedException e) {}
14500
14501                 String errorReport;
14502                 synchronized (mStrictModeBuffer) {
14503                     errorReport = mStrictModeBuffer.toString();
14504                     if (errorReport.length() == 0) {
14505                         return;
14506                     }
14507                     mStrictModeBuffer.delete(0, mStrictModeBuffer.length());
14508                     mStrictModeBuffer.trimToSize();
14509                 }
14510                 dbox.addText(dropboxTag, errorReport);
14511             }
14512         }.start();
14513     }
14514
14515     /**
14516      * Used by {@link Log} via {@link com.android.internal.os.RuntimeInit} to report serious errors.
14517      * @param app object of the crashing app, null for the system server
14518      * @param tag reported by the caller
14519      * @param system whether this wtf is coming from the system
14520      * @param crashInfo describing the context of the error
14521      * @return true if the process should exit immediately (WTF is fatal)
14522      */
14523     public boolean handleApplicationWtf(final IBinder app, final String tag, boolean system,
14524             final ApplicationErrorReport.ParcelableCrashInfo crashInfo) {
14525         final int callingUid = Binder.getCallingUid();
14526         final int callingPid = Binder.getCallingPid();
14527
14528         if (system) {
14529             // If this is coming from the system, we could very well have low-level
14530             // system locks held, so we want to do this all asynchronously.  And we
14531             // never want this to become fatal, so there is that too.
14532             mHandler.post(new Runnable() {
14533                 @Override public void run() {
14534                     handleApplicationWtfInner(callingUid, callingPid, app, tag, crashInfo);
14535                 }
14536             });
14537             return false;
14538         }
14539
14540         final ProcessRecord r = handleApplicationWtfInner(callingUid, callingPid, app, tag,
14541                 crashInfo);
14542
14543         final boolean isFatal = "eng".equals(Build.TYPE) || Settings.Global
14544                 .getInt(mContext.getContentResolver(), Settings.Global.WTF_IS_FATAL, 0) != 0;
14545         final boolean isSystem = (r == null) || r.persistent;
14546
14547         if (isFatal && !isSystem) {
14548             mAppErrors.crashApplication(r, crashInfo);
14549             return true;
14550         } else {
14551             return false;
14552         }
14553     }
14554
14555     ProcessRecord handleApplicationWtfInner(int callingUid, int callingPid, IBinder app, String tag,
14556             final ApplicationErrorReport.CrashInfo crashInfo) {
14557         final ProcessRecord r = findAppProcess(app, "WTF");
14558         final String processName = app == null ? "system_server"
14559                 : (r == null ? "unknown" : r.processName);
14560
14561         EventLog.writeEvent(EventLogTags.AM_WTF, UserHandle.getUserId(callingUid), callingPid,
14562                 processName, r == null ? -1 : r.info.flags, tag, crashInfo.exceptionMessage);
14563
14564         addErrorToDropBox("wtf", r, processName, null, null, tag, null, null, crashInfo);
14565
14566         return r;
14567     }
14568
14569     /**
14570      * @param app object of some object (as stored in {@link com.android.internal.os.RuntimeInit})
14571      * @return the corresponding {@link ProcessRecord} object, or null if none could be found
14572      */
14573     private ProcessRecord findAppProcess(IBinder app, String reason) {
14574         if (app == null) {
14575             return null;
14576         }
14577
14578         synchronized (this) {
14579             final int NP = mProcessNames.getMap().size();
14580             for (int ip=0; ip<NP; ip++) {
14581                 SparseArray<ProcessRecord> apps = mProcessNames.getMap().valueAt(ip);
14582                 final int NA = apps.size();
14583                 for (int ia=0; ia<NA; ia++) {
14584                     ProcessRecord p = apps.valueAt(ia);
14585                     if (p.thread != null && p.thread.asBinder() == app) {
14586                         return p;
14587                     }
14588                 }
14589             }
14590
14591             Slog.w(TAG, "Can't find mystery application for " + reason
14592                     + " from pid=" + Binder.getCallingPid()
14593                     + " uid=" + Binder.getCallingUid() + ": " + app);
14594             return null;
14595         }
14596     }
14597
14598     /**
14599      * Utility function for addErrorToDropBox and handleStrictModeViolation's logging
14600      * to append various headers to the dropbox log text.
14601      */
14602     private void appendDropBoxProcessHeaders(ProcessRecord process, String processName,
14603             StringBuilder sb) {
14604         // Watchdog thread ends up invoking this function (with
14605         // a null ProcessRecord) to add the stack file to dropbox.
14606         // Do not acquire a lock on this (am) in such cases, as it
14607         // could cause a potential deadlock, if and when watchdog
14608         // is invoked due to unavailability of lock on am and it
14609         // would prevent watchdog from killing system_server.
14610         if (process == null) {
14611             sb.append("Process: ").append(processName).append("\n");
14612             return;
14613         }
14614         // Note: ProcessRecord 'process' is guarded by the service
14615         // instance.  (notably process.pkgList, which could otherwise change
14616         // concurrently during execution of this method)
14617         synchronized (this) {
14618             sb.append("Process: ").append(processName).append("\n");
14619             sb.append("PID: ").append(process.pid).append("\n");
14620             int flags = process.info.flags;
14621             IPackageManager pm = AppGlobals.getPackageManager();
14622             sb.append("Flags: 0x").append(Integer.toHexString(flags)).append("\n");
14623             for (int ip=0; ip<process.pkgList.size(); ip++) {
14624                 String pkg = process.pkgList.keyAt(ip);
14625                 sb.append("Package: ").append(pkg);
14626                 try {
14627                     PackageInfo pi = pm.getPackageInfo(pkg, 0, UserHandle.getCallingUserId());
14628                     if (pi != null) {
14629                         sb.append(" v").append(pi.versionCode);
14630                         if (pi.versionName != null) {
14631                             sb.append(" (").append(pi.versionName).append(")");
14632                         }
14633                     }
14634                 } catch (RemoteException e) {
14635                     Slog.e(TAG, "Error getting package info: " + pkg, e);
14636                 }
14637                 sb.append("\n");
14638             }
14639         }
14640     }
14641
14642     private static String processClass(ProcessRecord process) {
14643         if (process == null || process.pid == MY_PID) {
14644             return "system_server";
14645         } else if ((process.info.flags & ApplicationInfo.FLAG_SYSTEM) != 0) {
14646             return "system_app";
14647         } else {
14648             return "data_app";
14649         }
14650     }
14651
14652     private volatile long mWtfClusterStart;
14653     private volatile int mWtfClusterCount;
14654
14655     /**
14656      * Write a description of an error (crash, WTF, ANR) to the drop box.
14657      * @param eventType to include in the drop box tag ("crash", "wtf", etc.)
14658      * @param process which caused the error, null means the system server
14659      * @param activity which triggered the error, null if unknown
14660      * @param parent activity related to the error, null if unknown
14661      * @param subject line related to the error, null if absent
14662      * @param report in long form describing the error, null if absent
14663      * @param dataFile text file to include in the report, null if none
14664      * @param crashInfo giving an application stack trace, null if absent
14665      */
14666     public void addErrorToDropBox(String eventType,
14667             ProcessRecord process, String processName, ActivityRecord activity,
14668             ActivityRecord parent, String subject,
14669             final String report, final File dataFile,
14670             final ApplicationErrorReport.CrashInfo crashInfo) {
14671         // NOTE -- this must never acquire the ActivityManagerService lock,
14672         // otherwise the watchdog may be prevented from resetting the system.
14673
14674         // Bail early if not published yet
14675         if (ServiceManager.getService(Context.DROPBOX_SERVICE) == null) return;
14676         final DropBoxManager dbox = mContext.getSystemService(DropBoxManager.class);
14677
14678         // Exit early if the dropbox isn't configured to accept this report type.
14679         final String dropboxTag = processClass(process) + "_" + eventType;
14680         if (dbox == null || !dbox.isTagEnabled(dropboxTag)) return;
14681
14682         // Rate-limit how often we're willing to do the heavy lifting below to
14683         // collect and record logs; currently 5 logs per 10 second period.
14684         final long now = SystemClock.elapsedRealtime();
14685         if (now - mWtfClusterStart > 10 * DateUtils.SECOND_IN_MILLIS) {
14686             mWtfClusterStart = now;
14687             mWtfClusterCount = 1;
14688         } else {
14689             if (mWtfClusterCount++ >= 5) return;
14690         }
14691
14692         final StringBuilder sb = new StringBuilder(1024);
14693         appendDropBoxProcessHeaders(process, processName, sb);
14694         if (process != null) {
14695             sb.append("Foreground: ")
14696                     .append(process.isInterestingToUserLocked() ? "Yes" : "No")
14697                     .append("\n");
14698         }
14699         if (activity != null) {
14700             sb.append("Activity: ").append(activity.shortComponentName).append("\n");
14701         }
14702         if (parent != null && parent.app != null && parent.app.pid != process.pid) {
14703             sb.append("Parent-Process: ").append(parent.app.processName).append("\n");
14704         }
14705         if (parent != null && parent != activity) {
14706             sb.append("Parent-Activity: ").append(parent.shortComponentName).append("\n");
14707         }
14708         if (subject != null) {
14709             sb.append("Subject: ").append(subject).append("\n");
14710         }
14711         sb.append("Build: ").append(Build.FINGERPRINT).append("\n");
14712         if (Debug.isDebuggerConnected()) {
14713             sb.append("Debugger: Connected\n");
14714         }
14715         sb.append("\n");
14716
14717         // Do the rest in a worker thread to avoid blocking the caller on I/O
14718         // (After this point, we shouldn't access AMS internal data structures.)
14719         Thread worker = new Thread("Error dump: " + dropboxTag) {
14720             @Override
14721             public void run() {
14722                 if (report != null) {
14723                     sb.append(report);
14724                 }
14725
14726                 String setting = Settings.Global.ERROR_LOGCAT_PREFIX + dropboxTag;
14727                 int lines = Settings.Global.getInt(mContext.getContentResolver(), setting, 0);
14728                 int maxDataFileSize = DROPBOX_MAX_SIZE - sb.length()
14729                         - lines * RESERVED_BYTES_PER_LOGCAT_LINE;
14730
14731                 if (dataFile != null && maxDataFileSize > 0) {
14732                     try {
14733                         sb.append(FileUtils.readTextFile(dataFile, maxDataFileSize,
14734                                     "\n\n[[TRUNCATED]]"));
14735                     } catch (IOException e) {
14736                         Slog.e(TAG, "Error reading " + dataFile, e);
14737                     }
14738                 }
14739                 if (crashInfo != null && crashInfo.stackTrace != null) {
14740                     sb.append(crashInfo.stackTrace);
14741                 }
14742
14743                 if (lines > 0) {
14744                     sb.append("\n");
14745
14746                     // Merge several logcat streams, and take the last N lines
14747                     InputStreamReader input = null;
14748                     try {
14749                         java.lang.Process logcat = new ProcessBuilder(
14750                                 "/system/bin/timeout", "-k", "15s", "10s",
14751                                 "/system/bin/logcat", "-v", "threadtime", "-b", "events", "-b", "system",
14752                                 "-b", "main", "-b", "crash", "-t", String.valueOf(lines))
14753                                         .redirectErrorStream(true).start();
14754
14755                         try { logcat.getOutputStream().close(); } catch (IOException e) {}
14756                         try { logcat.getErrorStream().close(); } catch (IOException e) {}
14757                         input = new InputStreamReader(logcat.getInputStream());
14758
14759                         int num;
14760                         char[] buf = new char[8192];
14761                         while ((num = input.read(buf)) > 0) sb.append(buf, 0, num);
14762                     } catch (IOException e) {
14763                         Slog.e(TAG, "Error running logcat", e);
14764                     } finally {
14765                         if (input != null) try { input.close(); } catch (IOException e) {}
14766                     }
14767                 }
14768
14769                 dbox.addText(dropboxTag, sb.toString());
14770             }
14771         };
14772
14773         if (process == null) {
14774             // If process is null, we are being called from some internal code
14775             // and may be about to die -- run this synchronously.
14776             worker.run();
14777         } else {
14778             worker.start();
14779         }
14780     }
14781
14782     @Override
14783     public List<ActivityManager.ProcessErrorStateInfo> getProcessesInErrorState() {
14784         enforceNotIsolatedCaller("getProcessesInErrorState");
14785         // assume our apps are happy - lazy create the list
14786         List<ActivityManager.ProcessErrorStateInfo> errList = null;
14787
14788         final boolean allUsers = ActivityManager.checkUidPermission(INTERACT_ACROSS_USERS_FULL,
14789                 Binder.getCallingUid()) == PackageManager.PERMISSION_GRANTED;
14790         int userId = UserHandle.getUserId(Binder.getCallingUid());
14791
14792         synchronized (this) {
14793
14794             // iterate across all processes
14795             for (int i=mLruProcesses.size()-1; i>=0; i--) {
14796                 ProcessRecord app = mLruProcesses.get(i);
14797                 if (!allUsers && app.userId != userId) {
14798                     continue;
14799                 }
14800                 if ((app.thread != null) && (app.crashing || app.notResponding)) {
14801                     // This one's in trouble, so we'll generate a report for it
14802                     // crashes are higher priority (in case there's a crash *and* an anr)
14803                     ActivityManager.ProcessErrorStateInfo report = null;
14804                     if (app.crashing) {
14805                         report = app.crashingReport;
14806                     } else if (app.notResponding) {
14807                         report = app.notRespondingReport;
14808                     }
14809
14810                     if (report != null) {
14811                         if (errList == null) {
14812                             errList = new ArrayList<ActivityManager.ProcessErrorStateInfo>(1);
14813                         }
14814                         errList.add(report);
14815                     } else {
14816                         Slog.w(TAG, "Missing app error report, app = " + app.processName +
14817                                 " crashing = " + app.crashing +
14818                                 " notResponding = " + app.notResponding);
14819                     }
14820                 }
14821             }
14822         }
14823
14824         return errList;
14825     }
14826
14827     static int procStateToImportance(int procState, int memAdj,
14828             ActivityManager.RunningAppProcessInfo currApp,
14829             int clientTargetSdk) {
14830         int imp = ActivityManager.RunningAppProcessInfo.procStateToImportanceForTargetSdk(
14831                 procState, clientTargetSdk);
14832         if (imp == ActivityManager.RunningAppProcessInfo.IMPORTANCE_BACKGROUND) {
14833             currApp.lru = memAdj;
14834         } else {
14835             currApp.lru = 0;
14836         }
14837         return imp;
14838     }
14839
14840     private void fillInProcMemInfo(ProcessRecord app,
14841             ActivityManager.RunningAppProcessInfo outInfo,
14842             int clientTargetSdk) {
14843         outInfo.pid = app.pid;
14844         outInfo.uid = app.info.uid;
14845         if (mHeavyWeightProcess == app) {
14846             outInfo.flags |= ActivityManager.RunningAppProcessInfo.FLAG_CANT_SAVE_STATE;
14847         }
14848         if (app.persistent) {
14849             outInfo.flags |= ActivityManager.RunningAppProcessInfo.FLAG_PERSISTENT;
14850         }
14851         if (app.activities.size() > 0) {
14852             outInfo.flags |= ActivityManager.RunningAppProcessInfo.FLAG_HAS_ACTIVITIES;
14853         }
14854         outInfo.lastTrimLevel = app.trimMemoryLevel;
14855         int adj = app.curAdj;
14856         int procState = app.curProcState;
14857         outInfo.importance = procStateToImportance(procState, adj, outInfo, clientTargetSdk);
14858         outInfo.importanceReasonCode = app.adjTypeCode;
14859         outInfo.processState = app.curProcState;
14860     }
14861
14862     @Override
14863     public List<ActivityManager.RunningAppProcessInfo> getRunningAppProcesses() {
14864         enforceNotIsolatedCaller("getRunningAppProcesses");
14865
14866         final int callingUid = Binder.getCallingUid();
14867         final int clientTargetSdk = mPackageManagerInt.getUidTargetSdkVersion(callingUid);
14868
14869         // Lazy instantiation of list
14870         List<ActivityManager.RunningAppProcessInfo> runList = null;
14871         final boolean allUsers = ActivityManager.checkUidPermission(INTERACT_ACROSS_USERS_FULL,
14872                 callingUid) == PackageManager.PERMISSION_GRANTED;
14873         final int userId = UserHandle.getUserId(callingUid);
14874         final boolean allUids = isGetTasksAllowed(
14875                 "getRunningAppProcesses", Binder.getCallingPid(), callingUid);
14876
14877         synchronized (this) {
14878             // Iterate across all processes
14879             for (int i = mLruProcesses.size() - 1; i >= 0; i--) {
14880                 ProcessRecord app = mLruProcesses.get(i);
14881                 if ((!allUsers && app.userId != userId)
14882                         || (!allUids && app.uid != callingUid)) {
14883                     continue;
14884                 }
14885                 if ((app.thread != null) && (!app.crashing && !app.notResponding)) {
14886                     // Generate process state info for running application
14887                     ActivityManager.RunningAppProcessInfo currApp =
14888                         new ActivityManager.RunningAppProcessInfo(app.processName,
14889                                 app.pid, app.getPackageList());
14890                     fillInProcMemInfo(app, currApp, clientTargetSdk);
14891                     if (app.adjSource instanceof ProcessRecord) {
14892                         currApp.importanceReasonPid = ((ProcessRecord)app.adjSource).pid;
14893                         currApp.importanceReasonImportance =
14894                                 ActivityManager.RunningAppProcessInfo.procStateToImportance(
14895                                         app.adjSourceProcState);
14896                     } else if (app.adjSource instanceof ActivityRecord) {
14897                         ActivityRecord r = (ActivityRecord)app.adjSource;
14898                         if (r.app != null) currApp.importanceReasonPid = r.app.pid;
14899                     }
14900                     if (app.adjTarget instanceof ComponentName) {
14901                         currApp.importanceReasonComponent = (ComponentName)app.adjTarget;
14902                     }
14903                     //Slog.v(TAG, "Proc " + app.processName + ": imp=" + currApp.importance
14904                     //        + " lru=" + currApp.lru);
14905                     if (runList == null) {
14906                         runList = new ArrayList<>();
14907                     }
14908                     runList.add(currApp);
14909                 }
14910             }
14911         }
14912         return runList;
14913     }
14914
14915     @Override
14916     public List<ApplicationInfo> getRunningExternalApplications() {
14917         enforceNotIsolatedCaller("getRunningExternalApplications");
14918         List<ActivityManager.RunningAppProcessInfo> runningApps = getRunningAppProcesses();
14919         List<ApplicationInfo> retList = new ArrayList<ApplicationInfo>();
14920         if (runningApps != null && runningApps.size() > 0) {
14921             Set<String> extList = new HashSet<String>();
14922             for (ActivityManager.RunningAppProcessInfo app : runningApps) {
14923                 if (app.pkgList != null) {
14924                     for (String pkg : app.pkgList) {
14925                         extList.add(pkg);
14926                     }
14927                 }
14928             }
14929             IPackageManager pm = AppGlobals.getPackageManager();
14930             for (String pkg : extList) {
14931                 try {
14932                     ApplicationInfo info = pm.getApplicationInfo(pkg, 0, UserHandle.getCallingUserId());
14933                     if ((info.flags & ApplicationInfo.FLAG_EXTERNAL_STORAGE) != 0) {
14934                         retList.add(info);
14935                     }
14936                 } catch (RemoteException e) {
14937                 }
14938             }
14939         }
14940         return retList;
14941     }
14942
14943     @Override
14944     public void getMyMemoryState(ActivityManager.RunningAppProcessInfo outInfo) {
14945         enforceNotIsolatedCaller("getMyMemoryState");
14946
14947         final int callingUid = Binder.getCallingUid();
14948         final int clientTargetSdk = mPackageManagerInt.getUidTargetSdkVersion(callingUid);
14949
14950         synchronized (this) {
14951             ProcessRecord proc;
14952             synchronized (mPidsSelfLocked) {
14953                 proc = mPidsSelfLocked.get(Binder.getCallingPid());
14954             }
14955             fillInProcMemInfo(proc, outInfo, clientTargetSdk);
14956         }
14957     }
14958
14959     @Override
14960     public int getMemoryTrimLevel() {
14961         enforceNotIsolatedCaller("getMyMemoryState");
14962         synchronized (this) {
14963             return mLastMemoryLevel;
14964         }
14965     }
14966
14967     @Override
14968     public void onShellCommand(FileDescriptor in, FileDescriptor out,
14969             FileDescriptor err, String[] args, ShellCallback callback,
14970             ResultReceiver resultReceiver) {
14971         (new ActivityManagerShellCommand(this, false)).exec(
14972                 this, in, out, err, args, callback, resultReceiver);
14973     }
14974
14975     @Override
14976     protected void dump(FileDescriptor fd, PrintWriter pw, String[] args) {
14977         if (!DumpUtils.checkDumpAndUsageStatsPermission(mContext, TAG, pw)) return;
14978
14979         boolean dumpAll = false;
14980         boolean dumpClient = false;
14981         boolean dumpCheckin = false;
14982         boolean dumpCheckinFormat = false;
14983         boolean dumpVisibleStacksOnly = false;
14984         boolean dumpFocusedStackOnly = false;
14985         String dumpPackage = null;
14986
14987         int opti = 0;
14988         while (opti < args.length) {
14989             String opt = args[opti];
14990             if (opt == null || opt.length() <= 0 || opt.charAt(0) != '-') {
14991                 break;
14992             }
14993             opti++;
14994             if ("-a".equals(opt)) {
14995                 dumpAll = true;
14996             } else if ("-c".equals(opt)) {
14997                 dumpClient = true;
14998             } else if ("-v".equals(opt)) {
14999                 dumpVisibleStacksOnly = true;
15000             } else if ("-f".equals(opt)) {
15001                 dumpFocusedStackOnly = true;
15002             } else if ("-p".equals(opt)) {
15003                 if (opti < args.length) {
15004                     dumpPackage = args[opti];
15005                     opti++;
15006                 } else {
15007                     pw.println("Error: -p option requires package argument");
15008                     return;
15009                 }
15010                 dumpClient = true;
15011             } else if ("--checkin".equals(opt)) {
15012                 dumpCheckin = dumpCheckinFormat = true;
15013             } else if ("-C".equals(opt)) {
15014                 dumpCheckinFormat = true;
15015             } else if ("-h".equals(opt)) {
15016                 ActivityManagerShellCommand.dumpHelp(pw, true);
15017                 return;
15018             } else {
15019                 pw.println("Unknown argument: " + opt + "; use -h for help");
15020             }
15021         }
15022
15023         long origId = Binder.clearCallingIdentity();
15024         boolean more = false;
15025         // Is the caller requesting to dump a particular piece of data?
15026         if (opti < args.length) {
15027             String cmd = args[opti];
15028             opti++;
15029             if ("activities".equals(cmd) || "a".equals(cmd)) {
15030                 synchronized (this) {
15031                     dumpActivitiesLocked(fd, pw, args, opti, true, dumpClient, dumpPackage);
15032                 }
15033             } else if ("lastanr".equals(cmd)) {
15034                 synchronized (this) {
15035                     dumpLastANRLocked(pw);
15036                 }
15037             } else if ("starter".equals(cmd)) {
15038                 synchronized (this) {
15039                     dumpActivityStarterLocked(pw);
15040                 }
15041             } else if ("recents".equals(cmd) || "r".equals(cmd)) {
15042                 synchronized (this) {
15043                     dumpRecentsLocked(fd, pw, args, opti, true, dumpPackage);
15044                 }
15045             } else if ("broadcasts".equals(cmd) || "b".equals(cmd)) {
15046                 String[] newArgs;
15047                 String name;
15048                 if (opti >= args.length) {
15049                     name = null;
15050                     newArgs = EMPTY_STRING_ARRAY;
15051                 } else {
15052                     dumpPackage = args[opti];
15053                     opti++;
15054                     newArgs = new String[args.length - opti];
15055                     if (args.length > 2) System.arraycopy(args, opti, newArgs, 0,
15056                             args.length - opti);
15057                 }
15058                 synchronized (this) {
15059                     dumpBroadcastsLocked(fd, pw, args, opti, true, dumpPackage);
15060                 }
15061             } else if ("broadcast-stats".equals(cmd)) {
15062                 String[] newArgs;
15063                 String name;
15064                 if (opti >= args.length) {
15065                     name = null;
15066                     newArgs = EMPTY_STRING_ARRAY;
15067                 } else {
15068                     dumpPackage = args[opti];
15069                     opti++;
15070                     newArgs = new String[args.length - opti];
15071                     if (args.length > 2) System.arraycopy(args, opti, newArgs, 0,
15072                             args.length - opti);
15073                 }
15074                 synchronized (this) {
15075                     if (dumpCheckinFormat) {
15076                         dumpBroadcastStatsCheckinLocked(fd, pw, args, opti, dumpCheckin,
15077                                 dumpPackage);
15078                     } else {
15079                         dumpBroadcastStatsLocked(fd, pw, args, opti, true, dumpPackage);
15080                     }
15081                 }
15082             } else if ("intents".equals(cmd) || "i".equals(cmd)) {
15083                 String[] newArgs;
15084                 String name;
15085                 if (opti >= args.length) {
15086                     name = null;
15087                     newArgs = EMPTY_STRING_ARRAY;
15088                 } else {
15089                     dumpPackage = args[opti];
15090                     opti++;
15091                     newArgs = new String[args.length - opti];
15092                     if (args.length > 2) System.arraycopy(args, opti, newArgs, 0,
15093                             args.length - opti);
15094                 }
15095                 synchronized (this) {
15096                     dumpPendingIntentsLocked(fd, pw, args, opti, true, dumpPackage);
15097                 }
15098             } else if ("processes".equals(cmd) || "p".equals(cmd)) {
15099                 String[] newArgs;
15100                 String name;
15101                 if (opti >= args.length) {
15102                     name = null;
15103                     newArgs = EMPTY_STRING_ARRAY;
15104                 } else {
15105                     dumpPackage = args[opti];
15106                     opti++;
15107                     newArgs = new String[args.length - opti];
15108                     if (args.length > 2) System.arraycopy(args, opti, newArgs, 0,
15109                             args.length - opti);
15110                 }
15111                 synchronized (this) {
15112                     dumpProcessesLocked(fd, pw, args, opti, true, dumpPackage);
15113                 }
15114             } else if ("oom".equals(cmd) || "o".equals(cmd)) {
15115                 synchronized (this) {
15116                     dumpOomLocked(fd, pw, args, opti, true);
15117                 }
15118             } else if ("permissions".equals(cmd) || "perm".equals(cmd)) {
15119                 synchronized (this) {
15120                     dumpPermissionsLocked(fd, pw, args, opti, true, null);
15121                 }
15122             } else if ("provider".equals(cmd)) {
15123                 String[] newArgs;
15124                 String name;
15125                 if (opti >= args.length) {
15126                     name = null;
15127                     newArgs = EMPTY_STRING_ARRAY;
15128                 } else {
15129                     name = args[opti];
15130                     opti++;
15131                     newArgs = new String[args.length - opti];
15132                     if (args.length > 2) System.arraycopy(args, opti, newArgs, 0, args.length - opti);
15133                 }
15134                 if (!dumpProvider(fd, pw, name, newArgs, 0, dumpAll)) {
15135                     pw.println("No providers match: " + name);
15136                     pw.println("Use -h for help.");
15137                 }
15138             } else if ("providers".equals(cmd) || "prov".equals(cmd)) {
15139                 synchronized (this) {
15140                     dumpProvidersLocked(fd, pw, args, opti, true, null);
15141                 }
15142             } else if ("service".equals(cmd)) {
15143                 String[] newArgs;
15144                 String name;
15145                 if (opti >= args.length) {
15146                     name = null;
15147                     newArgs = EMPTY_STRING_ARRAY;
15148                 } else {
15149                     name = args[opti];
15150                     opti++;
15151                     newArgs = new String[args.length - opti];
15152                     if (args.length > 2) System.arraycopy(args, opti, newArgs, 0,
15153                             args.length - opti);
15154                 }
15155                 if (!mServices.dumpService(fd, pw, name, newArgs, 0, dumpAll)) {
15156                     pw.println("No services match: " + name);
15157                     pw.println("Use -h for help.");
15158                 }
15159             } else if ("package".equals(cmd)) {
15160                 String[] newArgs;
15161                 if (opti >= args.length) {
15162                     pw.println("package: no package name specified");
15163                     pw.println("Use -h for help.");
15164                 } else {
15165                     dumpPackage = args[opti];
15166                     opti++;
15167                     newArgs = new String[args.length - opti];
15168                     if (args.length > 2) System.arraycopy(args, opti, newArgs, 0,
15169                             args.length - opti);
15170                     args = newArgs;
15171                     opti = 0;
15172                     more = true;
15173                 }
15174             } else if ("associations".equals(cmd) || "as".equals(cmd)) {
15175                 synchronized (this) {
15176                     dumpAssociationsLocked(fd, pw, args, opti, true, dumpClient, dumpPackage);
15177                 }
15178             } else if ("settings".equals(cmd)) {
15179                 synchronized (this) {
15180                     mConstants.dump(pw);
15181                 }
15182             } else if ("services".equals(cmd) || "s".equals(cmd)) {
15183                 if (dumpClient) {
15184                     ActiveServices.ServiceDumper dumper;
15185                     synchronized (this) {
15186                         dumper = mServices.newServiceDumperLocked(fd, pw, args, opti, true,
15187                                 dumpPackage);
15188                     }
15189                     dumper.dumpWithClient();
15190                 } else {
15191                     synchronized (this) {
15192                         mServices.newServiceDumperLocked(fd, pw, args, opti, true,
15193                                 dumpPackage).dumpLocked();
15194                     }
15195                 }
15196             } else if ("locks".equals(cmd)) {
15197                 LockGuard.dump(fd, pw, args);
15198             } else {
15199                 // Dumping a single activity?
15200                 if (!dumpActivity(fd, pw, cmd, args, opti, dumpAll, dumpVisibleStacksOnly,
15201                         dumpFocusedStackOnly)) {
15202                     ActivityManagerShellCommand shell = new ActivityManagerShellCommand(this, true);
15203                     int res = shell.exec(this, null, fd, null, args, null,
15204                             new ResultReceiver(null));
15205                     if (res < 0) {
15206                         pw.println("Bad activity command, or no activities match: " + cmd);
15207                         pw.println("Use -h for help.");
15208                     }
15209                 }
15210             }
15211             if (!more) {
15212                 Binder.restoreCallingIdentity(origId);
15213                 return;
15214             }
15215         }
15216
15217         // No piece of data specified, dump everything.
15218         if (dumpCheckinFormat) {
15219             dumpBroadcastStatsCheckinLocked(fd, pw, args, opti, dumpCheckin, dumpPackage);
15220         } else if (dumpClient) {
15221             ActiveServices.ServiceDumper sdumper;
15222             synchronized (this) {
15223                 mConstants.dump(pw);
15224                 pw.println();
15225                 if (dumpAll) {
15226                     pw.println("-------------------------------------------------------------------------------");
15227                 }
15228                 dumpPendingIntentsLocked(fd, pw, args, opti, dumpAll, dumpPackage);
15229                 pw.println();
15230                 if (dumpAll) {
15231                     pw.println("-------------------------------------------------------------------------------");
15232                 }
15233                 dumpBroadcastsLocked(fd, pw, args, opti, dumpAll, dumpPackage);
15234                 pw.println();
15235                 if (dumpAll) {
15236                     pw.println("-------------------------------------------------------------------------------");
15237                 }
15238                 if (dumpAll || dumpPackage != null) {
15239                     dumpBroadcastStatsLocked(fd, pw, args, opti, dumpAll, dumpPackage);
15240                     pw.println();
15241                     if (dumpAll) {
15242                         pw.println("-------------------------------------------------------------------------------");
15243                     }
15244                 }
15245                 dumpProvidersLocked(fd, pw, args, opti, dumpAll, dumpPackage);
15246                 pw.println();
15247                 if (dumpAll) {
15248                     pw.println("-------------------------------------------------------------------------------");
15249                 }
15250                 dumpPermissionsLocked(fd, pw, args, opti, dumpAll, dumpPackage);
15251                 pw.println();
15252                 if (dumpAll) {
15253                     pw.println("-------------------------------------------------------------------------------");
15254                 }
15255                 sdumper = mServices.newServiceDumperLocked(fd, pw, args, opti, dumpAll,
15256                         dumpPackage);
15257             }
15258             sdumper.dumpWithClient();
15259             pw.println();
15260             synchronized (this) {
15261                 if (dumpAll) {
15262                     pw.println("-------------------------------------------------------------------------------");
15263                 }
15264                 dumpRecentsLocked(fd, pw, args, opti, dumpAll, dumpPackage);
15265                 pw.println();
15266                 if (dumpAll) {
15267                     pw.println("-------------------------------------------------------------------------------");
15268                 }
15269                 dumpLastANRLocked(pw);
15270                 pw.println();
15271                 if (dumpAll) {
15272                     pw.println("-------------------------------------------------------------------------------");
15273                 }
15274                 dumpActivityStarterLocked(pw);
15275                 pw.println();
15276                 if (dumpAll) {
15277                     pw.println("-------------------------------------------------------------------------------");
15278                 }
15279                 dumpActivitiesLocked(fd, pw, args, opti, dumpAll, dumpClient, dumpPackage);
15280                 if (mAssociations.size() > 0) {
15281                     pw.println();
15282                     if (dumpAll) {
15283                         pw.println("-------------------------------------------------------------------------------");
15284                     }
15285                     dumpAssociationsLocked(fd, pw, args, opti, dumpAll, dumpClient, dumpPackage);
15286                 }
15287                 pw.println();
15288                 if (dumpAll) {
15289                     pw.println("-------------------------------------------------------------------------------");
15290                 }
15291                 dumpProcessesLocked(fd, pw, args, opti, dumpAll, dumpPackage);
15292             }
15293
15294         } else {
15295             synchronized (this) {
15296                 mConstants.dump(pw);
15297                 pw.println();
15298                 if (dumpAll) {
15299                     pw.println("-------------------------------------------------------------------------------");
15300                 }
15301                 dumpPendingIntentsLocked(fd, pw, args, opti, dumpAll, dumpPackage);
15302                 pw.println();
15303                 if (dumpAll) {
15304                     pw.println("-------------------------------------------------------------------------------");
15305                 }
15306                 dumpBroadcastsLocked(fd, pw, args, opti, dumpAll, dumpPackage);
15307                 pw.println();
15308                 if (dumpAll) {
15309                     pw.println("-------------------------------------------------------------------------------");
15310                 }
15311                 if (dumpAll || dumpPackage != null) {
15312                     dumpBroadcastStatsLocked(fd, pw, args, opti, dumpAll, dumpPackage);
15313                     pw.println();
15314                     if (dumpAll) {
15315                         pw.println("-------------------------------------------------------------------------------");
15316                     }
15317                 }
15318                 dumpProvidersLocked(fd, pw, args, opti, dumpAll, dumpPackage);
15319                 pw.println();
15320                 if (dumpAll) {
15321                     pw.println("-------------------------------------------------------------------------------");
15322                 }
15323                 dumpPermissionsLocked(fd, pw, args, opti, dumpAll, dumpPackage);
15324                 pw.println();
15325                 if (dumpAll) {
15326                     pw.println("-------------------------------------------------------------------------------");
15327                 }
15328                 mServices.newServiceDumperLocked(fd, pw, args, opti, dumpAll, dumpPackage)
15329                         .dumpLocked();
15330                 pw.println();
15331                 if (dumpAll) {
15332                     pw.println("-------------------------------------------------------------------------------");
15333                 }
15334                 dumpRecentsLocked(fd, pw, args, opti, dumpAll, dumpPackage);
15335                 pw.println();
15336                 if (dumpAll) {
15337                     pw.println("-------------------------------------------------------------------------------");
15338                 }
15339                 dumpLastANRLocked(pw);
15340                 pw.println();
15341                 if (dumpAll) {
15342                     pw.println("-------------------------------------------------------------------------------");
15343                 }
15344                 dumpActivityStarterLocked(pw);
15345                 pw.println();
15346                 if (dumpAll) {
15347                     pw.println("-------------------------------------------------------------------------------");
15348                 }
15349                 dumpActivitiesLocked(fd, pw, args, opti, dumpAll, dumpClient, dumpPackage);
15350                 if (mAssociations.size() > 0) {
15351                     pw.println();
15352                     if (dumpAll) {
15353                         pw.println("-------------------------------------------------------------------------------");
15354                     }
15355                     dumpAssociationsLocked(fd, pw, args, opti, dumpAll, dumpClient, dumpPackage);
15356                 }
15357                 pw.println();
15358                 if (dumpAll) {
15359                     pw.println("-------------------------------------------------------------------------------");
15360                 }
15361                 dumpProcessesLocked(fd, pw, args, opti, dumpAll, dumpPackage);
15362             }
15363         }
15364         Binder.restoreCallingIdentity(origId);
15365     }
15366
15367     private void dumpLastANRLocked(PrintWriter pw) {
15368         pw.println("ACTIVITY MANAGER ACTIVITIES (dumpsys activity lastanr)");
15369         if (mLastANRState == null) {
15370             pw.println("  <no ANR has occurred since boot>");
15371         } else {
15372             pw.println(mLastANRState);
15373         }
15374     }
15375
15376     private void dumpActivityStarterLocked(PrintWriter pw) {
15377         pw.println("ACTIVITY MANAGER ACTIVITIES (dumpsys activity starter)");
15378         mActivityStarter.dump(pw, "");
15379     }
15380
15381     void dumpActivitiesLocked(FileDescriptor fd, PrintWriter pw, String[] args,
15382             int opti, boolean dumpAll, boolean dumpClient, String dumpPackage) {
15383         dumpActivitiesLocked(fd, pw, args, opti, dumpAll, dumpClient, dumpPackage,
15384                 "ACTIVITY MANAGER ACTIVITIES (dumpsys activity activities)");
15385     }
15386
15387     void dumpActivitiesLocked(FileDescriptor fd, PrintWriter pw, String[] args,
15388             int opti, boolean dumpAll, boolean dumpClient, String dumpPackage, String header) {
15389         pw.println(header);
15390
15391         boolean printedAnything = mStackSupervisor.dumpActivitiesLocked(fd, pw, dumpAll, dumpClient,
15392                 dumpPackage);
15393         boolean needSep = printedAnything;
15394
15395         boolean printed = ActivityStackSupervisor.printThisActivity(pw,
15396                 mStackSupervisor.getResumedActivityLocked(),
15397                 dumpPackage, needSep, "  ResumedActivity: ");
15398         if (printed) {
15399             printedAnything = true;
15400             needSep = false;
15401         }
15402
15403         if (dumpPackage == null) {
15404             if (needSep) {
15405                 pw.println();
15406             }
15407             printedAnything = true;
15408             mStackSupervisor.dump(pw, "  ");
15409         }
15410
15411         if (!printedAnything) {
15412             pw.println("  (nothing)");
15413         }
15414     }
15415
15416     void dumpRecentsLocked(FileDescriptor fd, PrintWriter pw, String[] args,
15417             int opti, boolean dumpAll, String dumpPackage) {
15418         pw.println("ACTIVITY MANAGER RECENT TASKS (dumpsys activity recents)");
15419
15420         boolean printedAnything = false;
15421
15422         if (mRecentTasks != null && mRecentTasks.size() > 0) {
15423             boolean printedHeader = false;
15424
15425             final int N = mRecentTasks.size();
15426             for (int i=0; i<N; i++) {
15427                 TaskRecord tr = mRecentTasks.get(i);
15428                 if (dumpPackage != null) {
15429                     if (tr.realActivity == null ||
15430                             !dumpPackage.equals(tr.realActivity.getPackageName())) {
15431                         continue;
15432                     }
15433                 }
15434                 if (!printedHeader) {
15435                     pw.println("  Recent tasks:");
15436                     printedHeader = true;
15437                     printedAnything = true;
15438                 }
15439                 pw.print("  * Recent #"); pw.print(i); pw.print(": ");
15440                         pw.println(tr);
15441                 if (dumpAll) {
15442                     mRecentTasks.get(i).dump(pw, "    ");
15443                 }
15444             }
15445         }
15446
15447         if (!printedAnything) {
15448             pw.println("  (nothing)");
15449         }
15450     }
15451
15452     void dumpAssociationsLocked(FileDescriptor fd, PrintWriter pw, String[] args,
15453             int opti, boolean dumpAll, boolean dumpClient, String dumpPackage) {
15454         pw.println("ACTIVITY MANAGER ASSOCIATIONS (dumpsys activity associations)");
15455
15456         int dumpUid = 0;
15457         if (dumpPackage != null) {
15458             IPackageManager pm = AppGlobals.getPackageManager();
15459             try {
15460                 dumpUid = pm.getPackageUid(dumpPackage, MATCH_ANY_USER, 0);
15461             } catch (RemoteException e) {
15462             }
15463         }
15464
15465         boolean printedAnything = false;
15466
15467         final long now = SystemClock.uptimeMillis();
15468
15469         for (int i1=0, N1=mAssociations.size(); i1<N1; i1++) {
15470             ArrayMap<ComponentName, SparseArray<ArrayMap<String, Association>>> targetComponents
15471                     = mAssociations.valueAt(i1);
15472             for (int i2=0, N2=targetComponents.size(); i2<N2; i2++) {
15473                 SparseArray<ArrayMap<String, Association>> sourceUids
15474                         = targetComponents.valueAt(i2);
15475                 for (int i3=0, N3=sourceUids.size(); i3<N3; i3++) {
15476                     ArrayMap<String, Association> sourceProcesses = sourceUids.valueAt(i3);
15477                     for (int i4=0, N4=sourceProcesses.size(); i4<N4; i4++) {
15478                         Association ass = sourceProcesses.valueAt(i4);
15479                         if (dumpPackage != null) {
15480                             if (!ass.mTargetComponent.getPackageName().equals(dumpPackage)
15481                                     && UserHandle.getAppId(ass.mSourceUid) != dumpUid) {
15482                                 continue;
15483                             }
15484                         }
15485                         printedAnything = true;
15486                         pw.print("  ");
15487                         pw.print(ass.mTargetProcess);
15488                         pw.print("/");
15489                         UserHandle.formatUid(pw, ass.mTargetUid);
15490                         pw.print(" <- ");
15491                         pw.print(ass.mSourceProcess);
15492                         pw.print("/");
15493                         UserHandle.formatUid(pw, ass.mSourceUid);
15494                         pw.println();
15495                         pw.print("    via ");
15496                         pw.print(ass.mTargetComponent.flattenToShortString());
15497                         pw.println();
15498                         pw.print("    ");
15499                         long dur = ass.mTime;
15500                         if (ass.mNesting > 0) {
15501                             dur += now - ass.mStartTime;
15502                         }
15503                         TimeUtils.formatDuration(dur, pw);
15504                         pw.print(" (");
15505                         pw.print(ass.mCount);
15506                         pw.print(" times)");
15507                         pw.print("  ");
15508                         for (int i=0; i<ass.mStateTimes.length; i++) {
15509                             long amt = ass.mStateTimes[i];
15510                             if ((ass.mLastState-ActivityManager.MIN_PROCESS_STATE) == i) {
15511                                 amt += now - ass.mLastStateUptime;
15512                             }
15513                             if (amt != 0) {
15514                                 pw.print(" ");
15515                                 pw.print(ProcessList.makeProcStateString(
15516                                             i + ActivityManager.MIN_PROCESS_STATE));
15517                                 pw.print("=");
15518                                 TimeUtils.formatDuration(amt, pw);
15519                                 if ((ass.mLastState-ActivityManager.MIN_PROCESS_STATE) == i) {
15520                                     pw.print("*");
15521                                 }
15522                             }
15523                         }
15524                         pw.println();
15525                         if (ass.mNesting > 0) {
15526                             pw.print("    Currently active: ");
15527                             TimeUtils.formatDuration(now - ass.mStartTime, pw);
15528                             pw.println();
15529                         }
15530                     }
15531                 }
15532             }
15533
15534         }
15535
15536         if (!printedAnything) {
15537             pw.println("  (nothing)");
15538         }
15539     }
15540
15541     boolean dumpUids(PrintWriter pw, String dumpPackage, SparseArray<UidRecord> uids,
15542             String header, boolean needSep) {
15543         boolean printed = false;
15544         int whichAppId = -1;
15545         if (dumpPackage != null) {
15546             try {
15547                 ApplicationInfo info = mContext.getPackageManager().getApplicationInfo(
15548                         dumpPackage, 0);
15549                 whichAppId = UserHandle.getAppId(info.uid);
15550             } catch (NameNotFoundException e) {
15551                 e.printStackTrace();
15552             }
15553         }
15554         for (int i=0; i<uids.size(); i++) {
15555             UidRecord uidRec = uids.valueAt(i);
15556             if (dumpPackage != null && UserHandle.getAppId(uidRec.uid) != whichAppId) {
15557                 continue;
15558             }
15559             if (!printed) {
15560                 printed = true;
15561                 if (needSep) {
15562                     pw.println();
15563                 }
15564                 pw.print("  ");
15565                 pw.println(header);
15566                 needSep = true;
15567             }
15568             pw.print("    UID "); UserHandle.formatUid(pw, uidRec.uid);
15569             pw.print(": "); pw.println(uidRec);
15570         }
15571         return printed;
15572     }
15573
15574     void dumpProcessesLocked(FileDescriptor fd, PrintWriter pw, String[] args,
15575             int opti, boolean dumpAll, String dumpPackage) {
15576         boolean needSep = false;
15577         boolean printedAnything = false;
15578         int numPers = 0;
15579
15580         pw.println("ACTIVITY MANAGER RUNNING PROCESSES (dumpsys activity processes)");
15581
15582         if (dumpAll) {
15583             final int NP = mProcessNames.getMap().size();
15584             for (int ip=0; ip<NP; ip++) {
15585                 SparseArray<ProcessRecord> procs = mProcessNames.getMap().valueAt(ip);
15586                 final int NA = procs.size();
15587                 for (int ia=0; ia<NA; ia++) {
15588                     ProcessRecord r = procs.valueAt(ia);
15589                     if (dumpPackage != null && !r.pkgList.containsKey(dumpPackage)) {
15590                         continue;
15591                     }
15592                     if (!needSep) {
15593                         pw.println("  All known processes:");
15594                         needSep = true;
15595                         printedAnything = true;
15596                     }
15597                     pw.print(r.persistent ? "  *PERS*" : "  *APP*");
15598                         pw.print(" UID "); pw.print(procs.keyAt(ia));
15599                         pw.print(" "); pw.println(r);
15600                     r.dump(pw, "    ");
15601                     if (r.persistent) {
15602                         numPers++;
15603                     }
15604                 }
15605             }
15606         }
15607
15608         if (mIsolatedProcesses.size() > 0) {
15609             boolean printed = false;
15610             for (int i=0; i<mIsolatedProcesses.size(); i++) {
15611                 ProcessRecord r = mIsolatedProcesses.valueAt(i);
15612                 if (dumpPackage != null && !r.pkgList.containsKey(dumpPackage)) {
15613                     continue;
15614                 }
15615                 if (!printed) {
15616                     if (needSep) {
15617                         pw.println();
15618                     }
15619                     pw.println("  Isolated process list (sorted by uid):");
15620                     printedAnything = true;
15621                     printed = true;
15622                     needSep = true;
15623                 }
15624                 pw.print("    Isolated #"); pw.print(i); pw.print(": ");
15625                 pw.println(r);
15626             }
15627         }
15628
15629         if (mActiveInstrumentation.size() > 0) {
15630             boolean printed = false;
15631             for (int i=0; i<mActiveInstrumentation.size(); i++) {
15632                 ActiveInstrumentation ai = mActiveInstrumentation.get(i);
15633                 if (dumpPackage != null && !ai.mClass.getPackageName().equals(dumpPackage)
15634                         && !ai.mTargetInfo.packageName.equals(dumpPackage)) {
15635                     continue;
15636                 }
15637                 if (!printed) {
15638                     if (needSep) {
15639                         pw.println();
15640                     }
15641                     pw.println("  Active instrumentation:");
15642                     printedAnything = true;
15643                     printed = true;
15644                     needSep = true;
15645                 }
15646                 pw.print("    Instrumentation #"); pw.print(i); pw.print(": ");
15647                 pw.println(ai);
15648                 ai.dump(pw, "      ");
15649             }
15650         }
15651
15652         if (mActiveUids.size() > 0) {
15653             if (dumpUids(pw, dumpPackage, mActiveUids, "UID states:", needSep)) {
15654                 printedAnything = needSep = true;
15655             }
15656         }
15657         if (dumpAll) {
15658             if (mValidateUids.size() > 0) {
15659                 if (dumpUids(pw, dumpPackage, mValidateUids, "UID validation:", needSep)) {
15660                     printedAnything = needSep = true;
15661                 }
15662             }
15663         }
15664
15665         if (mLruProcesses.size() > 0) {
15666             if (needSep) {
15667                 pw.println();
15668             }
15669             pw.print("  Process LRU list (sorted by oom_adj, "); pw.print(mLruProcesses.size());
15670                     pw.print(" total, non-act at ");
15671                     pw.print(mLruProcesses.size()-mLruProcessActivityStart);
15672                     pw.print(", non-svc at ");
15673                     pw.print(mLruProcesses.size()-mLruProcessServiceStart);
15674                     pw.println("):");
15675             dumpProcessOomList(pw, this, mLruProcesses, "    ", "Proc", "PERS", false, dumpPackage);
15676             needSep = true;
15677             printedAnything = true;
15678         }
15679
15680         if (dumpAll || dumpPackage != null) {
15681             synchronized (mPidsSelfLocked) {
15682                 boolean printed = false;
15683                 for (int i=0; i<mPidsSelfLocked.size(); i++) {
15684                     ProcessRecord r = mPidsSelfLocked.valueAt(i);
15685                     if (dumpPackage != null && !r.pkgList.containsKey(dumpPackage)) {
15686                         continue;
15687                     }
15688                     if (!printed) {
15689                         if (needSep) pw.println();
15690                         needSep = true;
15691                         pw.println("  PID mappings:");
15692                         printed = true;
15693                         printedAnything = true;
15694                     }
15695                     pw.print("    PID #"); pw.print(mPidsSelfLocked.keyAt(i));
15696                         pw.print(": "); pw.println(mPidsSelfLocked.valueAt(i));
15697                 }
15698             }
15699         }
15700
15701         if (mImportantProcesses.size() > 0) {
15702             synchronized (mPidsSelfLocked) {
15703                 boolean printed = false;
15704                 for (int i = 0; i< mImportantProcesses.size(); i++) {
15705                     ProcessRecord r = mPidsSelfLocked.get(
15706                             mImportantProcesses.valueAt(i).pid);
15707                     if (dumpPackage != null && (r == null
15708                             || !r.pkgList.containsKey(dumpPackage))) {
15709                         continue;
15710                     }
15711                     if (!printed) {
15712                         if (needSep) pw.println();
15713                         needSep = true;
15714                         pw.println("  Foreground Processes:");
15715                         printed = true;
15716                         printedAnything = true;
15717                     }
15718                     pw.print("    PID #"); pw.print(mImportantProcesses.keyAt(i));
15719                             pw.print(": "); pw.println(mImportantProcesses.valueAt(i));
15720                 }
15721             }
15722         }
15723
15724         if (mPersistentStartingProcesses.size() > 0) {
15725             if (needSep) pw.println();
15726             needSep = true;
15727             printedAnything = true;
15728             pw.println("  Persisent processes that are starting:");
15729             dumpProcessList(pw, this, mPersistentStartingProcesses, "    ",
15730                     "Starting Norm", "Restarting PERS", dumpPackage);
15731         }
15732
15733         if (mRemovedProcesses.size() > 0) {
15734             if (needSep) pw.println();
15735             needSep = true;
15736             printedAnything = true;
15737             pw.println("  Processes that are being removed:");
15738             dumpProcessList(pw, this, mRemovedProcesses, "    ",
15739                     "Removed Norm", "Removed PERS", dumpPackage);
15740         }
15741
15742         if (mProcessesOnHold.size() > 0) {
15743             if (needSep) pw.println();
15744             needSep = true;
15745             printedAnything = true;
15746             pw.println("  Processes that are on old until the system is ready:");
15747             dumpProcessList(pw, this, mProcessesOnHold, "    ",
15748                     "OnHold Norm", "OnHold PERS", dumpPackage);
15749         }
15750
15751         needSep = dumpProcessesToGc(fd, pw, args, opti, needSep, dumpAll, dumpPackage);
15752
15753         needSep = mAppErrors.dumpLocked(fd, pw, needSep, dumpPackage);
15754         if (needSep) {
15755             printedAnything = true;
15756         }
15757
15758         if (dumpPackage == null) {
15759             pw.println();
15760             needSep = false;
15761             mUserController.dump(pw, dumpAll);
15762         }
15763         if (mHomeProcess != null && (dumpPackage == null
15764                 || mHomeProcess.pkgList.containsKey(dumpPackage))) {
15765             if (needSep) {
15766                 pw.println();
15767                 needSep = false;
15768             }
15769             pw.println("  mHomeProcess: " + mHomeProcess);
15770         }
15771         if (mPreviousProcess != null && (dumpPackage == null
15772                 || mPreviousProcess.pkgList.containsKey(dumpPackage))) {
15773             if (needSep) {
15774                 pw.println();
15775                 needSep = false;
15776             }
15777             pw.println("  mPreviousProcess: " + mPreviousProcess);
15778         }
15779         if (dumpAll) {
15780             StringBuilder sb = new StringBuilder(128);
15781             sb.append("  mPreviousProcessVisibleTime: ");
15782             TimeUtils.formatDuration(mPreviousProcessVisibleTime, sb);
15783             pw.println(sb);
15784         }
15785         if (mHeavyWeightProcess != null && (dumpPackage == null
15786                 || mHeavyWeightProcess.pkgList.containsKey(dumpPackage))) {
15787             if (needSep) {
15788                 pw.println();
15789                 needSep = false;
15790             }
15791             pw.println("  mHeavyWeightProcess: " + mHeavyWeightProcess);
15792         }
15793         if (dumpPackage == null) {
15794             pw.println("  mGlobalConfiguration: " + getGlobalConfiguration());
15795             mStackSupervisor.dumpDisplayConfigs(pw, "  ");
15796         }
15797         if (dumpAll) {
15798             pw.println("  mConfigWillChange: " + getFocusedStack().mConfigWillChange);
15799             if (mCompatModePackages.getPackages().size() > 0) {
15800                 boolean printed = false;
15801                 for (Map.Entry<String, Integer> entry
15802                         : mCompatModePackages.getPackages().entrySet()) {
15803                     String pkg = entry.getKey();
15804                     int mode = entry.getValue();
15805                     if (dumpPackage != null && !dumpPackage.equals(pkg)) {
15806                         continue;
15807                     }
15808                     if (!printed) {
15809                         pw.println("  mScreenCompatPackages:");
15810                         printed = true;
15811                     }
15812                     pw.print("    "); pw.print(pkg); pw.print(": ");
15813                             pw.print(mode); pw.println();
15814                 }
15815             }
15816             final int NI = mUidObservers.getRegisteredCallbackCount();
15817             boolean printed = false;
15818             for (int i=0; i<NI; i++) {
15819                 final UidObserverRegistration reg = (UidObserverRegistration)
15820                         mUidObservers.getRegisteredCallbackCookie(i);
15821                 if (dumpPackage == null || dumpPackage.equals(reg.pkg)) {
15822                     if (!printed) {
15823                         pw.println("  mUidObservers:");
15824                         printed = true;
15825                     }
15826                     pw.print("    "); UserHandle.formatUid(pw, reg.uid);
15827                     pw.print(" "); pw.print(reg.pkg); pw.print(":");
15828                     if ((reg.which&ActivityManager.UID_OBSERVER_IDLE) != 0) {
15829                         pw.print(" IDLE");
15830                     }
15831                     if ((reg.which&ActivityManager.UID_OBSERVER_ACTIVE) != 0) {
15832                         pw.print(" ACT" );
15833                     }
15834                     if ((reg.which&ActivityManager.UID_OBSERVER_GONE) != 0) {
15835                         pw.print(" GONE");
15836                     }
15837                     if ((reg.which&ActivityManager.UID_OBSERVER_PROCSTATE) != 0) {
15838                         pw.print(" STATE");
15839                         pw.print(" (cut="); pw.print(reg.cutpoint);
15840                         pw.print(")");
15841                     }
15842                     pw.println();
15843                     if (reg.lastProcStates != null) {
15844                         final int NJ = reg.lastProcStates.size();
15845                         for (int j=0; j<NJ; j++) {
15846                             pw.print("      Last ");
15847                             UserHandle.formatUid(pw, reg.lastProcStates.keyAt(j));
15848                             pw.print(": "); pw.println(reg.lastProcStates.valueAt(j));
15849                         }
15850                     }
15851                 }
15852             }
15853             pw.println("  mDeviceIdleWhitelist=" + Arrays.toString(mDeviceIdleWhitelist));
15854             pw.println("  mDeviceIdleTempWhitelist=" + Arrays.toString(mDeviceIdleTempWhitelist));
15855             if (mPendingTempWhitelist.size() > 0) {
15856                 pw.println("  mPendingTempWhitelist:");
15857                 for (int i = 0; i < mPendingTempWhitelist.size(); i++) {
15858                     PendingTempWhitelist ptw = mPendingTempWhitelist.valueAt(i);
15859                     pw.print("    ");
15860                     UserHandle.formatUid(pw, ptw.targetUid);
15861                     pw.print(": ");
15862                     TimeUtils.formatDuration(ptw.duration, pw);
15863                     pw.print(" ");
15864                     pw.println(ptw.tag);
15865                 }
15866             }
15867         }
15868         if (dumpPackage == null) {
15869             pw.println("  mWakefulness="
15870                     + PowerManagerInternal.wakefulnessToString(mWakefulness));
15871             pw.println("  mSleepTokens=" + mSleepTokens);
15872             pw.println("  mSleeping=" + mSleeping);
15873             pw.println("  mShuttingDown=" + mShuttingDown + " mTestPssMode=" + mTestPssMode);
15874             if (mRunningVoice != null) {
15875                 pw.println("  mRunningVoice=" + mRunningVoice);
15876                 pw.println("  mVoiceWakeLock" + mVoiceWakeLock);
15877             }
15878         }
15879         pw.println("  mVrController=" + mVrController);
15880         if (mDebugApp != null || mOrigDebugApp != null || mDebugTransient
15881                 || mOrigWaitForDebugger) {
15882             if (dumpPackage == null || dumpPackage.equals(mDebugApp)
15883                     || dumpPackage.equals(mOrigDebugApp)) {
15884                 if (needSep) {
15885                     pw.println();
15886                     needSep = false;
15887                 }
15888                 pw.println("  mDebugApp=" + mDebugApp + "/orig=" + mOrigDebugApp
15889                         + " mDebugTransient=" + mDebugTransient
15890                         + " mOrigWaitForDebugger=" + mOrigWaitForDebugger);
15891             }
15892         }
15893         if (mCurAppTimeTracker != null) {
15894             mCurAppTimeTracker.dumpWithHeader(pw, "  ", true);
15895         }
15896         if (mMemWatchProcesses.getMap().size() > 0) {
15897             pw.println("  Mem watch processes:");
15898             final ArrayMap<String, SparseArray<Pair<Long, String>>> procs
15899                     = mMemWatchProcesses.getMap();
15900             for (int i=0; i<procs.size(); i++) {
15901                 final String proc = procs.keyAt(i);
15902                 final SparseArray<Pair<Long, String>> uids = procs.valueAt(i);
15903                 for (int j=0; j<uids.size(); j++) {
15904                     if (needSep) {
15905                         pw.println();
15906                         needSep = false;
15907                     }
15908                     StringBuilder sb = new StringBuilder();
15909                     sb.append("    ").append(proc).append('/');
15910                     UserHandle.formatUid(sb, uids.keyAt(j));
15911                     Pair<Long, String> val = uids.valueAt(j);
15912                     sb.append(": "); DebugUtils.sizeValueToString(val.first, sb);
15913                     if (val.second != null) {
15914                         sb.append(", report to ").append(val.second);
15915                     }
15916                     pw.println(sb.toString());
15917                 }
15918             }
15919             pw.print("  mMemWatchDumpProcName="); pw.println(mMemWatchDumpProcName);
15920             pw.print("  mMemWatchDumpFile="); pw.println(mMemWatchDumpFile);
15921             pw.print("  mMemWatchDumpPid="); pw.print(mMemWatchDumpPid);
15922                     pw.print(" mMemWatchDumpUid="); pw.println(mMemWatchDumpUid);
15923         }
15924         if (mTrackAllocationApp != null) {
15925             if (dumpPackage == null || dumpPackage.equals(mTrackAllocationApp)) {
15926                 if (needSep) {
15927                     pw.println();
15928                     needSep = false;
15929                 }
15930                 pw.println("  mTrackAllocationApp=" + mTrackAllocationApp);
15931             }
15932         }
15933         if (mProfileApp != null || mProfileProc != null || mProfileFile != null
15934                 || mProfileFd != null) {
15935             if (dumpPackage == null || dumpPackage.equals(mProfileApp)) {
15936                 if (needSep) {
15937                     pw.println();
15938                     needSep = false;
15939                 }
15940                 pw.println("  mProfileApp=" + mProfileApp + " mProfileProc=" + mProfileProc);
15941                 pw.println("  mProfileFile=" + mProfileFile + " mProfileFd=" + mProfileFd);
15942                 pw.println("  mSamplingInterval=" + mSamplingInterval + " mAutoStopProfiler="
15943                         + mAutoStopProfiler + " mStreamingOutput=" + mStreamingOutput);
15944                 pw.println("  mProfileType=" + mProfileType);
15945             }
15946         }
15947         if (mNativeDebuggingApp != null) {
15948             if (dumpPackage == null || dumpPackage.equals(mNativeDebuggingApp)) {
15949                 if (needSep) {
15950                     pw.println();
15951                     needSep = false;
15952                 }
15953                 pw.println("  mNativeDebuggingApp=" + mNativeDebuggingApp);
15954             }
15955         }
15956         if (dumpPackage == null) {
15957             if (mAlwaysFinishActivities) {
15958                 pw.println("  mAlwaysFinishActivities=" + mAlwaysFinishActivities);
15959             }
15960             if (mController != null) {
15961                 pw.println("  mController=" + mController
15962                         + " mControllerIsAMonkey=" + mControllerIsAMonkey);
15963             }
15964             if (dumpAll) {
15965                 pw.println("  Total persistent processes: " + numPers);
15966                 pw.println("  mProcessesReady=" + mProcessesReady
15967                         + " mSystemReady=" + mSystemReady
15968                         + " mBooted=" + mBooted
15969                         + " mFactoryTest=" + mFactoryTest);
15970                 pw.println("  mBooting=" + mBooting
15971                         + " mCallFinishBooting=" + mCallFinishBooting
15972                         + " mBootAnimationComplete=" + mBootAnimationComplete);
15973                 pw.print("  mLastPowerCheckRealtime=");
15974                         TimeUtils.formatDuration(mLastPowerCheckRealtime, pw);
15975                         pw.println("");
15976                 pw.print("  mLastPowerCheckUptime=");
15977                         TimeUtils.formatDuration(mLastPowerCheckUptime, pw);
15978                         pw.println("");
15979                 pw.println("  mGoingToSleep=" + mStackSupervisor.mGoingToSleep);
15980                 pw.println("  mLaunchingActivity=" + mStackSupervisor.mLaunchingActivity);
15981                 pw.println("  mAdjSeq=" + mAdjSeq + " mLruSeq=" + mLruSeq);
15982                 pw.println("  mNumNonCachedProcs=" + mNumNonCachedProcs
15983                         + " (" + mLruProcesses.size() + " total)"
15984                         + " mNumCachedHiddenProcs=" + mNumCachedHiddenProcs
15985                         + " mNumServiceProcs=" + mNumServiceProcs
15986                         + " mNewNumServiceProcs=" + mNewNumServiceProcs);
15987                 pw.println("  mAllowLowerMemLevel=" + mAllowLowerMemLevel
15988                         + " mLastMemoryLevel=" + mLastMemoryLevel
15989                         + " mLastNumProcesses=" + mLastNumProcesses);
15990                 long now = SystemClock.uptimeMillis();
15991                 pw.print("  mLastIdleTime=");
15992                         TimeUtils.formatDuration(now, mLastIdleTime, pw);
15993                         pw.print(" mLowRamSinceLastIdle=");
15994                         TimeUtils.formatDuration(getLowRamTimeSinceIdle(now), pw);
15995                         pw.println();
15996             }
15997         }
15998
15999         if (!printedAnything) {
16000             pw.println("  (nothing)");
16001         }
16002     }
16003
16004     boolean dumpProcessesToGc(FileDescriptor fd, PrintWriter pw, String[] args,
16005             int opti, boolean needSep, boolean dumpAll, String dumpPackage) {
16006         if (mProcessesToGc.size() > 0) {
16007             boolean printed = false;
16008             long now = SystemClock.uptimeMillis();
16009             for (int i=0; i<mProcessesToGc.size(); i++) {
16010                 ProcessRecord proc = mProcessesToGc.get(i);
16011                 if (dumpPackage != null && !dumpPackage.equals(proc.info.packageName)) {
16012                     continue;
16013                 }
16014                 if (!printed) {
16015                     if (needSep) pw.println();
16016                     needSep = true;
16017                     pw.println("  Processes that are waiting to GC:");
16018                     printed = true;
16019                 }
16020                 pw.print("    Process "); pw.println(proc);
16021                 pw.print("      lowMem="); pw.print(proc.reportLowMemory);
16022                         pw.print(", last gced=");
16023                         pw.print(now-proc.lastRequestedGc);
16024                         pw.print(" ms ago, last lowMem=");
16025                         pw.print(now-proc.lastLowMemory);
16026                         pw.println(" ms ago");
16027
16028             }
16029         }
16030         return needSep;
16031     }
16032
16033     void printOomLevel(PrintWriter pw, String name, int adj) {
16034         pw.print("    ");
16035         if (adj >= 0) {
16036             pw.print(' ');
16037             if (adj < 10) pw.print(' ');
16038         } else {
16039             if (adj > -10) pw.print(' ');
16040         }
16041         pw.print(adj);
16042         pw.print(": ");
16043         pw.print(name);
16044         pw.print(" (");
16045         pw.print(stringifySize(mProcessList.getMemLevel(adj), 1024));
16046         pw.println(")");
16047     }
16048
16049     boolean dumpOomLocked(FileDescriptor fd, PrintWriter pw, String[] args,
16050             int opti, boolean dumpAll) {
16051         boolean needSep = false;
16052
16053         if (mLruProcesses.size() > 0) {
16054             if (needSep) pw.println();
16055             needSep = true;
16056             pw.println("  OOM levels:");
16057             printOomLevel(pw, "SYSTEM_ADJ", ProcessList.SYSTEM_ADJ);
16058             printOomLevel(pw, "PERSISTENT_PROC_ADJ", ProcessList.PERSISTENT_PROC_ADJ);
16059             printOomLevel(pw, "PERSISTENT_SERVICE_ADJ", ProcessList.PERSISTENT_SERVICE_ADJ);
16060             printOomLevel(pw, "FOREGROUND_APP_ADJ", ProcessList.FOREGROUND_APP_ADJ);
16061             printOomLevel(pw, "VISIBLE_APP_ADJ", ProcessList.VISIBLE_APP_ADJ);
16062             printOomLevel(pw, "PERCEPTIBLE_APP_ADJ", ProcessList.PERCEPTIBLE_APP_ADJ);
16063             printOomLevel(pw, "BACKUP_APP_ADJ", ProcessList.BACKUP_APP_ADJ);
16064             printOomLevel(pw, "HEAVY_WEIGHT_APP_ADJ", ProcessList.HEAVY_WEIGHT_APP_ADJ);
16065             printOomLevel(pw, "SERVICE_ADJ", ProcessList.SERVICE_ADJ);
16066             printOomLevel(pw, "HOME_APP_ADJ", ProcessList.HOME_APP_ADJ);
16067             printOomLevel(pw, "PREVIOUS_APP_ADJ", ProcessList.PREVIOUS_APP_ADJ);
16068             printOomLevel(pw, "SERVICE_B_ADJ", ProcessList.SERVICE_B_ADJ);
16069             printOomLevel(pw, "CACHED_APP_MIN_ADJ", ProcessList.CACHED_APP_MIN_ADJ);
16070             printOomLevel(pw, "CACHED_APP_MAX_ADJ", ProcessList.CACHED_APP_MAX_ADJ);
16071
16072             if (needSep) pw.println();
16073             pw.print("  Process OOM control ("); pw.print(mLruProcesses.size());
16074                     pw.print(" total, non-act at ");
16075                     pw.print(mLruProcesses.size()-mLruProcessActivityStart);
16076                     pw.print(", non-svc at ");
16077                     pw.print(mLruProcesses.size()-mLruProcessServiceStart);
16078                     pw.println("):");
16079             dumpProcessOomList(pw, this, mLruProcesses, "    ", "Proc", "PERS", true, null);
16080             needSep = true;
16081         }
16082
16083         dumpProcessesToGc(fd, pw, args, opti, needSep, dumpAll, null);
16084
16085         pw.println();
16086         pw.println("  mHomeProcess: " + mHomeProcess);
16087         pw.println("  mPreviousProcess: " + mPreviousProcess);
16088         if (mHeavyWeightProcess != null) {
16089             pw.println("  mHeavyWeightProcess: " + mHeavyWeightProcess);
16090         }
16091
16092         return true;
16093     }
16094
16095     /**
16096      * There are three ways to call this:
16097      *  - no provider specified: dump all the providers
16098      *  - a flattened component name that matched an existing provider was specified as the
16099      *    first arg: dump that one provider
16100      *  - the first arg isn't the flattened component name of an existing provider:
16101      *    dump all providers whose component contains the first arg as a substring
16102      */
16103     protected boolean dumpProvider(FileDescriptor fd, PrintWriter pw, String name, String[] args,
16104             int opti, boolean dumpAll) {
16105         return mProviderMap.dumpProvider(fd, pw, name, args, opti, dumpAll);
16106     }
16107
16108     static class ItemMatcher {
16109         ArrayList<ComponentName> components;
16110         ArrayList<String> strings;
16111         ArrayList<Integer> objects;
16112         boolean all;
16113
16114         ItemMatcher() {
16115             all = true;
16116         }
16117
16118         void build(String name) {
16119             ComponentName componentName = ComponentName.unflattenFromString(name);
16120             if (componentName != null) {
16121                 if (components == null) {
16122                     components = new ArrayList<ComponentName>();
16123                 }
16124                 components.add(componentName);
16125                 all = false;
16126             } else {
16127                 int objectId = 0;
16128                 // Not a '/' separated full component name; maybe an object ID?
16129                 try {
16130                     objectId = Integer.parseInt(name, 16);
16131                     if (objects == null) {
16132                         objects = new ArrayList<Integer>();
16133                     }
16134                     objects.add(objectId);
16135                     all = false;
16136                 } catch (RuntimeException e) {
16137                     // Not an integer; just do string match.
16138                     if (strings == null) {
16139                         strings = new ArrayList<String>();
16140                     }
16141                     strings.add(name);
16142                     all = false;
16143                 }
16144             }
16145         }
16146
16147         int build(String[] args, int opti) {
16148             for (; opti<args.length; opti++) {
16149                 String name = args[opti];
16150                 if ("--".equals(name)) {
16151                     return opti+1;
16152                 }
16153                 build(name);
16154             }
16155             return opti;
16156         }
16157
16158         boolean match(Object object, ComponentName comp) {
16159             if (all) {
16160                 return true;
16161             }
16162             if (components != null) {
16163                 for (int i=0; i<components.size(); i++) {
16164                     if (components.get(i).equals(comp)) {
16165                         return true;
16166                     }
16167                 }
16168             }
16169             if (objects != null) {
16170                 for (int i=0; i<objects.size(); i++) {
16171                     if (System.identityHashCode(object) == objects.get(i)) {
16172                         return true;
16173                     }
16174                 }
16175             }
16176             if (strings != null) {
16177                 String flat = comp.flattenToString();
16178                 for (int i=0; i<strings.size(); i++) {
16179                     if (flat.contains(strings.get(i))) {
16180                         return true;
16181                     }
16182                 }
16183             }
16184             return false;
16185         }
16186     }
16187
16188     /**
16189      * There are three things that cmd can be:
16190      *  - a flattened component name that matches an existing activity
16191      *  - the cmd arg isn't the flattened component name of an existing activity:
16192      *    dump all activity whose component contains the cmd as a substring
16193      *  - A hex number of the ActivityRecord object instance.
16194      *
16195      *  @param dumpVisibleStacksOnly dump activity with {@param name} only if in a visible stack
16196      *  @param dumpFocusedStackOnly dump activity with {@param name} only if in the focused stack
16197      */
16198     protected boolean dumpActivity(FileDescriptor fd, PrintWriter pw, String name, String[] args,
16199             int opti, boolean dumpAll, boolean dumpVisibleStacksOnly, boolean dumpFocusedStackOnly) {
16200         ArrayList<ActivityRecord> activities;
16201
16202         synchronized (this) {
16203             activities = mStackSupervisor.getDumpActivitiesLocked(name, dumpVisibleStacksOnly,
16204                     dumpFocusedStackOnly);
16205         }
16206
16207         if (activities.size() <= 0) {
16208             return false;
16209         }
16210
16211         String[] newArgs = new String[args.length - opti];
16212         System.arraycopy(args, opti, newArgs, 0, args.length - opti);
16213
16214         TaskRecord lastTask = null;
16215         boolean needSep = false;
16216         for (int i=activities.size()-1; i>=0; i--) {
16217             ActivityRecord r = activities.get(i);
16218             if (needSep) {
16219                 pw.println();
16220             }
16221             needSep = true;
16222             synchronized (this) {
16223                 final TaskRecord task = r.getTask();
16224                 if (lastTask != task) {
16225                     lastTask = task;
16226                     pw.print("TASK "); pw.print(lastTask.affinity);
16227                             pw.print(" id="); pw.print(lastTask.taskId);
16228                             pw.print(" userId="); pw.println(lastTask.userId);
16229                     if (dumpAll) {
16230                         lastTask.dump(pw, "  ");
16231                     }
16232                 }
16233             }
16234             dumpActivity("  ", fd, pw, activities.get(i), newArgs, dumpAll);
16235         }
16236         return true;
16237     }
16238
16239     /**
16240      * Invokes IApplicationThread.dumpActivity() on the thread of the specified activity if
16241      * there is a thread associated with the activity.
16242      */
16243     private void dumpActivity(String prefix, FileDescriptor fd, PrintWriter pw,
16244             final ActivityRecord r, String[] args, boolean dumpAll) {
16245         String innerPrefix = prefix + "  ";
16246         synchronized (this) {
16247             pw.print(prefix); pw.print("ACTIVITY "); pw.print(r.shortComponentName);
16248                     pw.print(" "); pw.print(Integer.toHexString(System.identityHashCode(r)));
16249                     pw.print(" pid=");
16250                     if (r.app != null) pw.println(r.app.pid);
16251                     else pw.println("(not running)");
16252             if (dumpAll) {
16253                 r.dump(pw, innerPrefix);
16254             }
16255         }
16256         if (r.app != null && r.app.thread != null) {
16257             // flush anything that is already in the PrintWriter since the thread is going
16258             // to write to the file descriptor directly
16259             pw.flush();
16260             try {
16261                 TransferPipe tp = new TransferPipe();
16262                 try {
16263                     r.app.thread.dumpActivity(tp.getWriteFd(),
16264                             r.appToken, innerPrefix, args);
16265                     tp.go(fd);
16266                 } finally {
16267                     tp.kill();
16268                 }
16269             } catch (IOException e) {
16270                 pw.println(innerPrefix + "Failure while dumping the activity: " + e);
16271             } catch (RemoteException e) {
16272                 pw.println(innerPrefix + "Got a RemoteException while dumping the activity");
16273             }
16274         }
16275     }
16276
16277     void dumpBroadcastsLocked(FileDescriptor fd, PrintWriter pw, String[] args,
16278             int opti, boolean dumpAll, String dumpPackage) {
16279         boolean needSep = false;
16280         boolean onlyHistory = false;
16281         boolean printedAnything = false;
16282
16283         if ("history".equals(dumpPackage)) {
16284             if (opti < args.length && "-s".equals(args[opti])) {
16285                 dumpAll = false;
16286             }
16287             onlyHistory = true;
16288             dumpPackage = null;
16289         }
16290
16291         pw.println("ACTIVITY MANAGER BROADCAST STATE (dumpsys activity broadcasts)");
16292         if (!onlyHistory && dumpAll) {
16293             if (mRegisteredReceivers.size() > 0) {
16294                 boolean printed = false;
16295                 Iterator it = mRegisteredReceivers.values().iterator();
16296                 while (it.hasNext()) {
16297                     ReceiverList r = (ReceiverList)it.next();
16298                     if (dumpPackage != null && (r.app == null ||
16299                             !dumpPackage.equals(r.app.info.packageName))) {
16300                         continue;
16301                     }
16302                     if (!printed) {
16303                         pw.println("  Registered Receivers:");
16304                         needSep = true;
16305                         printed = true;
16306                         printedAnything = true;
16307                     }
16308                     pw.print("  * "); pw.println(r);
16309                     r.dump(pw, "    ");
16310                 }
16311             }
16312
16313             if (mReceiverResolver.dump(pw, needSep ?
16314                     "\n  Receiver Resolver Table:" : "  Receiver Resolver Table:",
16315                     "    ", dumpPackage, false, false)) {
16316                 needSep = true;
16317                 printedAnything = true;
16318             }
16319         }
16320
16321         for (BroadcastQueue q : mBroadcastQueues) {
16322             needSep = q.dumpLocked(fd, pw, args, opti, dumpAll, dumpPackage, needSep);
16323             printedAnything |= needSep;
16324         }
16325
16326         needSep = true;
16327
16328         if (!onlyHistory && mStickyBroadcasts != null && dumpPackage == null) {
16329             for (int user=0; user<mStickyBroadcasts.size(); user++) {
16330                 if (needSep) {
16331                     pw.println();
16332                 }
16333                 needSep = true;
16334                 printedAnything = true;
16335                 pw.print("  Sticky broadcasts for user ");
16336                         pw.print(mStickyBroadcasts.keyAt(user)); pw.println(":");
16337                 StringBuilder sb = new StringBuilder(128);
16338                 for (Map.Entry<String, ArrayList<Intent>> ent
16339                         : mStickyBroadcasts.valueAt(user).entrySet()) {
16340                     pw.print("  * Sticky action "); pw.print(ent.getKey());
16341                     if (dumpAll) {
16342                         pw.println(":");
16343                         ArrayList<Intent> intents = ent.getValue();
16344                         final int N = intents.size();
16345                         for (int i=0; i<N; i++) {
16346                             sb.setLength(0);
16347                             sb.append("    Intent: ");
16348                             intents.get(i).toShortString(sb, false, true, false, false);
16349                             pw.println(sb.toString());
16350                             Bundle bundle = intents.get(i).getExtras();
16351                             if (bundle != null) {
16352                                 pw.print("      ");
16353                                 pw.println(bundle.toString());
16354                             }
16355                         }
16356                     } else {
16357                         pw.println("");
16358                     }
16359                 }
16360             }
16361         }
16362
16363         if (!onlyHistory && dumpAll) {
16364             pw.println();
16365             for (BroadcastQueue queue : mBroadcastQueues) {
16366                 pw.println("  mBroadcastsScheduled [" + queue.mQueueName + "]="
16367                         + queue.mBroadcastsScheduled);
16368             }
16369             pw.println("  mHandler:");
16370             mHandler.dump(new PrintWriterPrinter(pw), "    ");
16371             needSep = true;
16372             printedAnything = true;
16373         }
16374
16375         if (!printedAnything) {
16376             pw.println("  (nothing)");
16377         }
16378     }
16379
16380     void dumpBroadcastStatsLocked(FileDescriptor fd, PrintWriter pw, String[] args,
16381             int opti, boolean dumpAll, String dumpPackage) {
16382         if (mCurBroadcastStats == null) {
16383             return;
16384         }
16385
16386         pw.println("ACTIVITY MANAGER BROADCAST STATS STATE (dumpsys activity broadcast-stats)");
16387         final long now = SystemClock.elapsedRealtime();
16388         if (mLastBroadcastStats != null) {
16389             pw.print("  Last stats (from ");
16390             TimeUtils.formatDuration(mLastBroadcastStats.mStartRealtime, now, pw);
16391             pw.print(" to ");
16392             TimeUtils.formatDuration(mLastBroadcastStats.mEndRealtime, now, pw);
16393             pw.print(", ");
16394             TimeUtils.formatDuration(mLastBroadcastStats.mEndUptime
16395                     - mLastBroadcastStats.mStartUptime, pw);
16396             pw.println(" uptime):");
16397             if (!mLastBroadcastStats.dumpStats(pw, "    ", dumpPackage)) {
16398                 pw.println("    (nothing)");
16399             }
16400             pw.println();
16401         }
16402         pw.print("  Current stats (from ");
16403         TimeUtils.formatDuration(mCurBroadcastStats.mStartRealtime, now, pw);
16404         pw.print(" to now, ");
16405         TimeUtils.formatDuration(SystemClock.uptimeMillis()
16406                 - mCurBroadcastStats.mStartUptime, pw);
16407         pw.println(" uptime):");
16408         if (!mCurBroadcastStats.dumpStats(pw, "    ", dumpPackage)) {
16409             pw.println("    (nothing)");
16410         }
16411     }
16412
16413     void dumpBroadcastStatsCheckinLocked(FileDescriptor fd, PrintWriter pw, String[] args,
16414             int opti, boolean fullCheckin, String dumpPackage) {
16415         if (mCurBroadcastStats == null) {
16416             return;
16417         }
16418
16419         if (mLastBroadcastStats != null) {
16420             mLastBroadcastStats.dumpCheckinStats(pw, dumpPackage);
16421             if (fullCheckin) {
16422                 mLastBroadcastStats = null;
16423                 return;
16424             }
16425         }
16426         mCurBroadcastStats.dumpCheckinStats(pw, dumpPackage);
16427         if (fullCheckin) {
16428             mCurBroadcastStats = null;
16429         }
16430     }
16431
16432     void dumpProvidersLocked(FileDescriptor fd, PrintWriter pw, String[] args,
16433             int opti, boolean dumpAll, String dumpPackage) {
16434         boolean needSep;
16435         boolean printedAnything = false;
16436
16437         ItemMatcher matcher = new ItemMatcher();
16438         matcher.build(args, opti);
16439
16440         pw.println("ACTIVITY MANAGER CONTENT PROVIDERS (dumpsys activity providers)");
16441
16442         needSep = mProviderMap.dumpProvidersLocked(pw, dumpAll, dumpPackage);
16443         printedAnything |= needSep;
16444
16445         if (mLaunchingProviders.size() > 0) {
16446             boolean printed = false;
16447             for (int i=mLaunchingProviders.size()-1; i>=0; i--) {
16448                 ContentProviderRecord r = mLaunchingProviders.get(i);
16449                 if (dumpPackage != null && !dumpPackage.equals(r.name.getPackageName())) {
16450                     continue;
16451                 }
16452                 if (!printed) {
16453                     if (needSep) pw.println();
16454                     needSep = true;
16455                     pw.println("  Launching content providers:");
16456                     printed = true;
16457                     printedAnything = true;
16458                 }
16459                 pw.print("  Launching #"); pw.print(i); pw.print(": ");
16460                         pw.println(r);
16461             }
16462         }
16463
16464         if (!printedAnything) {
16465             pw.println("  (nothing)");
16466         }
16467     }
16468
16469     void dumpPermissionsLocked(FileDescriptor fd, PrintWriter pw, String[] args,
16470             int opti, boolean dumpAll, String dumpPackage) {
16471         boolean needSep = false;
16472         boolean printedAnything = false;
16473
16474         pw.println("ACTIVITY MANAGER URI PERMISSIONS (dumpsys activity permissions)");
16475
16476         if (mGrantedUriPermissions.size() > 0) {
16477             boolean printed = false;
16478             int dumpUid = -2;
16479             if (dumpPackage != null) {
16480                 try {
16481                     dumpUid = mContext.getPackageManager().getPackageUidAsUser(dumpPackage,
16482                             MATCH_ANY_USER, 0);
16483                 } catch (NameNotFoundException e) {
16484                     dumpUid = -1;
16485                 }
16486             }
16487             for (int i=0; i<mGrantedUriPermissions.size(); i++) {
16488                 int uid = mGrantedUriPermissions.keyAt(i);
16489                 if (dumpUid >= -1 && UserHandle.getAppId(uid) != dumpUid) {
16490                     continue;
16491                 }
16492                 final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.valueAt(i);
16493                 if (!printed) {
16494                     if (needSep) pw.println();
16495                     needSep = true;
16496                     pw.println("  Granted Uri Permissions:");
16497                     printed = true;
16498                     printedAnything = true;
16499                 }
16500                 pw.print("  * UID "); pw.print(uid); pw.println(" holds:");
16501                 for (UriPermission perm : perms.values()) {
16502                     pw.print("    "); pw.println(perm);
16503                     if (dumpAll) {
16504                         perm.dump(pw, "      ");
16505                     }
16506                 }
16507             }
16508         }
16509
16510         if (!printedAnything) {
16511             pw.println("  (nothing)");
16512         }
16513     }
16514
16515     void dumpPendingIntentsLocked(FileDescriptor fd, PrintWriter pw, String[] args,
16516             int opti, boolean dumpAll, String dumpPackage) {
16517         boolean printed = false;
16518
16519         pw.println("ACTIVITY MANAGER PENDING INTENTS (dumpsys activity intents)");
16520
16521         if (mIntentSenderRecords.size() > 0) {
16522             // Organize these by package name, so they are easier to read.
16523             final ArrayMap<String, ArrayList<PendingIntentRecord>> byPackage = new ArrayMap<>();
16524             final ArrayList<WeakReference<PendingIntentRecord>> weakRefs = new ArrayList<>();
16525             final Iterator<WeakReference<PendingIntentRecord>> it
16526                     = mIntentSenderRecords.values().iterator();
16527             while (it.hasNext()) {
16528                 WeakReference<PendingIntentRecord> ref = it.next();
16529                 PendingIntentRecord rec = ref != null ? ref.get() : null;
16530                 if (rec == null) {
16531                     weakRefs.add(ref);
16532                     continue;
16533                 }
16534                 if (dumpPackage != null && !dumpPackage.equals(rec.key.packageName)) {
16535                     continue;
16536                 }
16537                 ArrayList<PendingIntentRecord> list = byPackage.get(rec.key.packageName);
16538                 if (list == null) {
16539                     list = new ArrayList<>();
16540                     byPackage.put(rec.key.packageName, list);
16541                 }
16542                 list.add(rec);
16543             }
16544             for (int i = 0; i < byPackage.size(); i++) {
16545                 ArrayList<PendingIntentRecord> intents = byPackage.valueAt(i);
16546                 printed = true;
16547                 pw.print("  * "); pw.print(byPackage.keyAt(i));
16548                 pw.print(": "); pw.print(intents.size()); pw.println(" items");
16549                 for (int j = 0; j < intents.size(); j++) {
16550                     pw.print("    #"); pw.print(j); pw.print(": "); pw.println(intents.get(j));
16551                     if (dumpAll) {
16552                         intents.get(j).dump(pw, "      ");
16553                     }
16554                 }
16555             }
16556             if (weakRefs.size() > 0) {
16557                 printed = true;
16558                 pw.println("  * WEAK REFS:");
16559                 for (int i = 0; i < weakRefs.size(); i++) {
16560                     pw.print("    #"); pw.print(i); pw.print(": "); pw.println(weakRefs.get(i));
16561                 }
16562             }
16563         }
16564
16565         if (!printed) {
16566             pw.println("  (nothing)");
16567         }
16568     }
16569
16570     private static final int dumpProcessList(PrintWriter pw,
16571             ActivityManagerService service, List list,
16572             String prefix, String normalLabel, String persistentLabel,
16573             String dumpPackage) {
16574         int numPers = 0;
16575         final int N = list.size()-1;
16576         for (int i=N; i>=0; i--) {
16577             ProcessRecord r = (ProcessRecord)list.get(i);
16578             if (dumpPackage != null && !dumpPackage.equals(r.info.packageName)) {
16579                 continue;
16580             }
16581             pw.println(String.format("%s%s #%2d: %s",
16582                     prefix, (r.persistent ? persistentLabel : normalLabel),
16583                     i, r.toString()));
16584             if (r.persistent) {
16585                 numPers++;
16586             }
16587         }
16588         return numPers;
16589     }
16590
16591     private static final boolean dumpProcessOomList(PrintWriter pw,
16592             ActivityManagerService service, List<ProcessRecord> origList,
16593             String prefix, String normalLabel, String persistentLabel,
16594             boolean inclDetails, String dumpPackage) {
16595
16596         ArrayList<Pair<ProcessRecord, Integer>> list
16597                 = new ArrayList<Pair<ProcessRecord, Integer>>(origList.size());
16598         for (int i=0; i<origList.size(); i++) {
16599             ProcessRecord r = origList.get(i);
16600             if (dumpPackage != null && !r.pkgList.containsKey(dumpPackage)) {
16601                 continue;
16602             }
16603             list.add(new Pair<ProcessRecord, Integer>(origList.get(i), i));
16604         }
16605
16606         if (list.size() <= 0) {
16607             return false;
16608         }
16609
16610         Comparator<Pair<ProcessRecord, Integer>> comparator
16611                 = new Comparator<Pair<ProcessRecord, Integer>>() {
16612             @Override
16613             public int compare(Pair<ProcessRecord, Integer> object1,
16614                     Pair<ProcessRecord, Integer> object2) {
16615                 if (object1.first.setAdj != object2.first.setAdj) {
16616                     return object1.first.setAdj > object2.first.setAdj ? -1 : 1;
16617                 }
16618                 if (object1.first.setProcState != object2.first.setProcState) {
16619                     return object1.first.setProcState > object2.first.setProcState ? -1 : 1;
16620                 }
16621                 if (object1.second.intValue() != object2.second.intValue()) {
16622                     return object1.second.intValue() > object2.second.intValue() ? -1 : 1;
16623                 }
16624                 return 0;
16625             }
16626         };
16627
16628         Collections.sort(list, comparator);
16629
16630         final long curRealtime = SystemClock.elapsedRealtime();
16631         final long realtimeSince = curRealtime - service.mLastPowerCheckRealtime;
16632         final long curUptime = SystemClock.uptimeMillis();
16633         final long uptimeSince = curUptime - service.mLastPowerCheckUptime;
16634
16635         for (int i=list.size()-1; i>=0; i--) {
16636             ProcessRecord r = list.get(i).first;
16637             String oomAdj = ProcessList.makeOomAdjString(r.setAdj);
16638             char schedGroup;
16639             switch (r.setSchedGroup) {
16640                 case ProcessList.SCHED_GROUP_BACKGROUND:
16641                     schedGroup = 'B';
16642                     break;
16643                 case ProcessList.SCHED_GROUP_DEFAULT:
16644                     schedGroup = 'F';
16645                     break;
16646                 case ProcessList.SCHED_GROUP_TOP_APP:
16647                     schedGroup = 'T';
16648                     break;
16649                 default:
16650                     schedGroup = '?';
16651                     break;
16652             }
16653             char foreground;
16654             if (r.foregroundActivities) {
16655                 foreground = 'A';
16656             } else if (r.foregroundServices) {
16657                 foreground = 'S';
16658             } else {
16659                 foreground = ' ';
16660             }
16661             String procState = ProcessList.makeProcStateString(r.curProcState);
16662             pw.print(prefix);
16663             pw.print(r.persistent ? persistentLabel : normalLabel);
16664             pw.print(" #");
16665             int num = (origList.size()-1)-list.get(i).second;
16666             if (num < 10) pw.print(' ');
16667             pw.print(num);
16668             pw.print(": ");
16669             pw.print(oomAdj);
16670             pw.print(' ');
16671             pw.print(schedGroup);
16672             pw.print('/');
16673             pw.print(foreground);
16674             pw.print('/');
16675             pw.print(procState);
16676             pw.print(" trm:");
16677             if (r.trimMemoryLevel < 10) pw.print(' ');
16678             pw.print(r.trimMemoryLevel);
16679             pw.print(' ');
16680             pw.print(r.toShortString());
16681             pw.print(" (");
16682             pw.print(r.adjType);
16683             pw.println(')');
16684             if (r.adjSource != null || r.adjTarget != null) {
16685                 pw.print(prefix);
16686                 pw.print("    ");
16687                 if (r.adjTarget instanceof ComponentName) {
16688                     pw.print(((ComponentName)r.adjTarget).flattenToShortString());
16689                 } else if (r.adjTarget != null) {
16690                     pw.print(r.adjTarget.toString());
16691                 } else {
16692                     pw.print("{null}");
16693                 }
16694                 pw.print("<=");
16695                 if (r.adjSource instanceof ProcessRecord) {
16696                     pw.print("Proc{");
16697                     pw.print(((ProcessRecord)r.adjSource).toShortString());
16698                     pw.println("}");
16699                 } else if (r.adjSource != null) {
16700                     pw.println(r.adjSource.toString());
16701                 } else {
16702                     pw.println("{null}");
16703                 }
16704             }
16705             if (inclDetails) {
16706                 pw.print(prefix);
16707                 pw.print("    ");
16708                 pw.print("oom: max="); pw.print(r.maxAdj);
16709                 pw.print(" curRaw="); pw.print(r.curRawAdj);
16710                 pw.print(" setRaw="); pw.print(r.setRawAdj);
16711                 pw.print(" cur="); pw.print(r.curAdj);
16712                 pw.print(" set="); pw.println(r.setAdj);
16713                 pw.print(prefix);
16714                 pw.print("    ");
16715                 pw.print("state: cur="); pw.print(ProcessList.makeProcStateString(r.curProcState));
16716                 pw.print(" set="); pw.print(ProcessList.makeProcStateString(r.setProcState));
16717                 pw.print(" lastPss="); DebugUtils.printSizeValue(pw, r.lastPss*1024);
16718                 pw.print(" lastSwapPss="); DebugUtils.printSizeValue(pw, r.lastSwapPss*1024);
16719                 pw.print(" lastCachedPss="); DebugUtils.printSizeValue(pw, r.lastCachedPss*1024);
16720                 pw.println();
16721                 pw.print(prefix);
16722                 pw.print("    ");
16723                 pw.print("cached="); pw.print(r.cached);
16724                 pw.print(" empty="); pw.print(r.empty);
16725                 pw.print(" hasAboveClient="); pw.println(r.hasAboveClient);
16726
16727                 if (r.setProcState >= ActivityManager.PROCESS_STATE_SERVICE) {
16728                     if (r.lastWakeTime != 0) {
16729                         long wtime;
16730                         BatteryStatsImpl stats = service.mBatteryStatsService.getActiveStatistics();
16731                         synchronized (stats) {
16732                             wtime = stats.getProcessWakeTime(r.info.uid,
16733                                     r.pid, curRealtime);
16734                         }
16735                         long timeUsed = wtime - r.lastWakeTime;
16736                         pw.print(prefix);
16737                         pw.print("    ");
16738                         pw.print("keep awake over ");
16739                         TimeUtils.formatDuration(realtimeSince, pw);
16740                         pw.print(" used ");
16741                         TimeUtils.formatDuration(timeUsed, pw);
16742                         pw.print(" (");
16743                         pw.print((timeUsed*100)/realtimeSince);
16744                         pw.println("%)");
16745                     }
16746                     if (r.lastCpuTime != 0) {
16747                         long timeUsed = r.curCpuTime - r.lastCpuTime;
16748                         pw.print(prefix);
16749                         pw.print("    ");
16750                         pw.print("run cpu over ");
16751                         TimeUtils.formatDuration(uptimeSince, pw);
16752                         pw.print(" used ");
16753                         TimeUtils.formatDuration(timeUsed, pw);
16754                         pw.print(" (");
16755                         pw.print((timeUsed*100)/uptimeSince);
16756                         pw.println("%)");
16757                     }
16758                 }
16759             }
16760         }
16761         return true;
16762     }
16763
16764     ArrayList<ProcessRecord> collectProcesses(PrintWriter pw, int start, boolean allPkgs,
16765             String[] args) {
16766         ArrayList<ProcessRecord> procs;
16767         synchronized (this) {
16768             if (args != null && args.length > start
16769                     && args[start].charAt(0) != '-') {
16770                 procs = new ArrayList<ProcessRecord>();
16771                 int pid = -1;
16772                 try {
16773                     pid = Integer.parseInt(args[start]);
16774                 } catch (NumberFormatException e) {
16775                 }
16776                 for (int i=mLruProcesses.size()-1; i>=0; i--) {
16777                     ProcessRecord proc = mLruProcesses.get(i);
16778                     if (proc.pid == pid) {
16779                         procs.add(proc);
16780                     } else if (allPkgs && proc.pkgList != null
16781                             && proc.pkgList.containsKey(args[start])) {
16782                         procs.add(proc);
16783                     } else if (proc.processName.equals(args[start])) {
16784                         procs.add(proc);
16785                     }
16786                 }
16787                 if (procs.size() <= 0) {
16788                     return null;
16789                 }
16790             } else {
16791                 procs = new ArrayList<ProcessRecord>(mLruProcesses);
16792             }
16793         }
16794         return procs;
16795     }
16796
16797     final void dumpGraphicsHardwareUsage(FileDescriptor fd,
16798             PrintWriter pw, String[] args) {
16799         ArrayList<ProcessRecord> procs = collectProcesses(pw, 0, false, args);
16800         if (procs == null) {
16801             pw.println("No process found for: " + args[0]);
16802             return;
16803         }
16804
16805         long uptime = SystemClock.uptimeMillis();
16806         long realtime = SystemClock.elapsedRealtime();
16807         pw.println("Applications Graphics Acceleration Info:");
16808         pw.println("Uptime: " + uptime + " Realtime: " + realtime);
16809
16810         for (int i = procs.size() - 1 ; i >= 0 ; i--) {
16811             ProcessRecord r = procs.get(i);
16812             if (r.thread != null) {
16813                 pw.println("\n** Graphics info for pid " + r.pid + " [" + r.processName + "] **");
16814                 pw.flush();
16815                 try {
16816                     TransferPipe tp = new TransferPipe();
16817                     try {
16818                         r.thread.dumpGfxInfo(tp.getWriteFd(), args);
16819                         tp.go(fd);
16820                     } finally {
16821                         tp.kill();
16822                     }
16823                 } catch (IOException e) {
16824                     pw.println("Failure while dumping the app: " + r);
16825                     pw.flush();
16826                 } catch (RemoteException e) {
16827                     pw.println("Got a RemoteException while dumping the app " + r);
16828                     pw.flush();
16829                 }
16830             }
16831         }
16832     }
16833
16834     final void dumpDbInfo(FileDescriptor fd, PrintWriter pw, String[] args) {
16835         ArrayList<ProcessRecord> procs = collectProcesses(pw, 0, false, args);
16836         if (procs == null) {
16837             pw.println("No process found for: " + args[0]);
16838             return;
16839         }
16840
16841         pw.println("Applications Database Info:");
16842
16843         for (int i = procs.size() - 1 ; i >= 0 ; i--) {
16844             ProcessRecord r = procs.get(i);
16845             if (r.thread != null) {
16846                 pw.println("\n** Database info for pid " + r.pid + " [" + r.processName + "] **");
16847                 pw.flush();
16848                 try {
16849                     TransferPipe tp = new TransferPipe();
16850                     try {
16851                         r.thread.dumpDbInfo(tp.getWriteFd(), args);
16852                         tp.go(fd);
16853                     } finally {
16854                         tp.kill();
16855                     }
16856                 } catch (IOException e) {
16857                     pw.println("Failure while dumping the app: " + r);
16858                     pw.flush();
16859                 } catch (RemoteException e) {
16860                     pw.println("Got a RemoteException while dumping the app " + r);
16861                     pw.flush();
16862                 }
16863             }
16864         }
16865     }
16866
16867     final static class MemItem {
16868         final boolean isProc;
16869         final String label;
16870         final String shortLabel;
16871         final long pss;
16872         final long swapPss;
16873         final int id;
16874         final boolean hasActivities;
16875         ArrayList<MemItem> subitems;
16876
16877         public MemItem(String _label, String _shortLabel, long _pss, long _swapPss, int _id,
16878                 boolean _hasActivities) {
16879             isProc = true;
16880             label = _label;
16881             shortLabel = _shortLabel;
16882             pss = _pss;
16883             swapPss = _swapPss;
16884             id = _id;
16885             hasActivities = _hasActivities;
16886         }
16887
16888         public MemItem(String _label, String _shortLabel, long _pss, long _swapPss, int _id) {
16889             isProc = false;
16890             label = _label;
16891             shortLabel = _shortLabel;
16892             pss = _pss;
16893             swapPss = _swapPss;
16894             id = _id;
16895             hasActivities = false;
16896         }
16897     }
16898
16899     static final void dumpMemItems(PrintWriter pw, String prefix, String tag,
16900             ArrayList<MemItem> items, boolean sort, boolean isCompact, boolean dumpSwapPss) {
16901         if (sort && !isCompact) {
16902             Collections.sort(items, new Comparator<MemItem>() {
16903                 @Override
16904                 public int compare(MemItem lhs, MemItem rhs) {
16905                     if (lhs.pss < rhs.pss) {
16906                         return 1;
16907                     } else if (lhs.pss > rhs.pss) {
16908                         return -1;
16909                     }
16910                     return 0;
16911                 }
16912             });
16913         }
16914
16915         for (int i=0; i<items.size(); i++) {
16916             MemItem mi = items.get(i);
16917             if (!isCompact) {
16918                 if (dumpSwapPss) {
16919                     pw.printf("%s%s: %-60s (%s in swap)\n", prefix, stringifyKBSize(mi.pss),
16920                             mi.label, stringifyKBSize(mi.swapPss));
16921                 } else {
16922                     pw.printf("%s%s: %s\n", prefix, stringifyKBSize(mi.pss), mi.label);
16923                 }
16924             } else if (mi.isProc) {
16925                 pw.print("proc,"); pw.print(tag); pw.print(","); pw.print(mi.shortLabel);
16926                 pw.print(","); pw.print(mi.id); pw.print(","); pw.print(mi.pss); pw.print(",");
16927                 pw.print(dumpSwapPss ? mi.swapPss : "N/A");
16928                 pw.println(mi.hasActivities ? ",a" : ",e");
16929             } else {
16930                 pw.print(tag); pw.print(","); pw.print(mi.shortLabel); pw.print(",");
16931                 pw.print(mi.pss); pw.print(","); pw.println(dumpSwapPss ? mi.swapPss : "N/A");
16932             }
16933             if (mi.subitems != null) {
16934                 dumpMemItems(pw, prefix + "    ", mi.shortLabel, mi.subitems,
16935                         true, isCompact, dumpSwapPss);
16936             }
16937         }
16938     }
16939
16940     // These are in KB.
16941     static final long[] DUMP_MEM_BUCKETS = new long[] {
16942         5*1024, 7*1024, 10*1024, 15*1024, 20*1024, 30*1024, 40*1024, 80*1024,
16943         120*1024, 160*1024, 200*1024,
16944         250*1024, 300*1024, 350*1024, 400*1024, 500*1024, 600*1024, 800*1024,
16945         1*1024*1024, 2*1024*1024, 5*1024*1024, 10*1024*1024, 20*1024*1024
16946     };
16947
16948     static final void appendMemBucket(StringBuilder out, long memKB, String label,
16949             boolean stackLike) {
16950         int start = label.lastIndexOf('.');
16951         if (start >= 0) start++;
16952         else start = 0;
16953         int end = label.length();
16954         for (int i=0; i<DUMP_MEM_BUCKETS.length; i++) {
16955             if (DUMP_MEM_BUCKETS[i] >= memKB) {
16956                 long bucket = DUMP_MEM_BUCKETS[i]/1024;
16957                 out.append(bucket);
16958                 out.append(stackLike ? "MB." : "MB ");
16959                 out.append(label, start, end);
16960                 return;
16961             }
16962         }
16963         out.append(memKB/1024);
16964         out.append(stackLike ? "MB." : "MB ");
16965         out.append(label, start, end);
16966     }
16967
16968     static final int[] DUMP_MEM_OOM_ADJ = new int[] {
16969             ProcessList.NATIVE_ADJ,
16970             ProcessList.SYSTEM_ADJ, ProcessList.PERSISTENT_PROC_ADJ,
16971             ProcessList.PERSISTENT_SERVICE_ADJ, ProcessList.FOREGROUND_APP_ADJ,
16972             ProcessList.VISIBLE_APP_ADJ, ProcessList.PERCEPTIBLE_APP_ADJ,
16973             ProcessList.BACKUP_APP_ADJ, ProcessList.HEAVY_WEIGHT_APP_ADJ,
16974             ProcessList.SERVICE_ADJ, ProcessList.HOME_APP_ADJ,
16975             ProcessList.PREVIOUS_APP_ADJ, ProcessList.SERVICE_B_ADJ, ProcessList.CACHED_APP_MIN_ADJ
16976     };
16977     static final String[] DUMP_MEM_OOM_LABEL = new String[] {
16978             "Native",
16979             "System", "Persistent", "Persistent Service", "Foreground",
16980             "Visible", "Perceptible",
16981             "Heavy Weight", "Backup",
16982             "A Services", "Home",
16983             "Previous", "B Services", "Cached"
16984     };
16985     static final String[] DUMP_MEM_OOM_COMPACT_LABEL = new String[] {
16986             "native",
16987             "sys", "pers", "persvc", "fore",
16988             "vis", "percept",
16989             "heavy", "backup",
16990             "servicea", "home",
16991             "prev", "serviceb", "cached"
16992     };
16993
16994     private final void dumpApplicationMemoryUsageHeader(PrintWriter pw, long uptime,
16995             long realtime, boolean isCheckinRequest, boolean isCompact) {
16996         if (isCompact) {
16997             pw.print("version,"); pw.println(MEMINFO_COMPACT_VERSION);
16998         }
16999         if (isCheckinRequest || isCompact) {
17000             // short checkin version
17001             pw.print("time,"); pw.print(uptime); pw.print(","); pw.println(realtime);
17002         } else {
17003             pw.println("Applications Memory Usage (in Kilobytes):");
17004             pw.println("Uptime: " + uptime + " Realtime: " + realtime);
17005         }
17006     }
17007
17008     private static final int KSM_SHARED = 0;
17009     private static final int KSM_SHARING = 1;
17010     private static final int KSM_UNSHARED = 2;
17011     private static final int KSM_VOLATILE = 3;
17012
17013     private final long[] getKsmInfo() {
17014         long[] longOut = new long[4];
17015         final int[] SINGLE_LONG_FORMAT = new int[] {
17016             PROC_SPACE_TERM| PROC_OUT_LONG
17017         };
17018         long[] longTmp = new long[1];
17019         readProcFile("/sys/kernel/mm/ksm/pages_shared",
17020                 SINGLE_LONG_FORMAT, null, longTmp, null);
17021         longOut[KSM_SHARED] = longTmp[0] * ProcessList.PAGE_SIZE / 1024;
17022         longTmp[0] = 0;
17023         readProcFile("/sys/kernel/mm/ksm/pages_sharing",
17024                 SINGLE_LONG_FORMAT, null, longTmp, null);
17025         longOut[KSM_SHARING] = longTmp[0] * ProcessList.PAGE_SIZE / 1024;
17026         longTmp[0] = 0;
17027         readProcFile("/sys/kernel/mm/ksm/pages_unshared",
17028                 SINGLE_LONG_FORMAT, null, longTmp, null);
17029         longOut[KSM_UNSHARED] = longTmp[0] * ProcessList.PAGE_SIZE / 1024;
17030         longTmp[0] = 0;
17031         readProcFile("/sys/kernel/mm/ksm/pages_volatile",
17032                 SINGLE_LONG_FORMAT, null, longTmp, null);
17033         longOut[KSM_VOLATILE] = longTmp[0] * ProcessList.PAGE_SIZE / 1024;
17034         return longOut;
17035     }
17036
17037     private static String stringifySize(long size, int order) {
17038         Locale locale = Locale.US;
17039         switch (order) {
17040             case 1:
17041                 return String.format(locale, "%,13d", size);
17042             case 1024:
17043                 return String.format(locale, "%,9dK", size / 1024);
17044             case 1024 * 1024:
17045                 return String.format(locale, "%,5dM", size / 1024 / 1024);
17046             case 1024 * 1024 * 1024:
17047                 return String.format(locale, "%,1dG", size / 1024 / 1024 / 1024);
17048             default:
17049                 throw new IllegalArgumentException("Invalid size order");
17050         }
17051     }
17052
17053     private static String stringifyKBSize(long size) {
17054         return stringifySize(size * 1024, 1024);
17055     }
17056
17057     // Update this version number in case you change the 'compact' format
17058     private static final int MEMINFO_COMPACT_VERSION = 1;
17059
17060     final void dumpApplicationMemoryUsage(FileDescriptor fd,
17061             PrintWriter pw, String prefix, String[] args, boolean brief, PrintWriter categoryPw) {
17062         boolean dumpDetails = false;
17063         boolean dumpFullDetails = false;
17064         boolean dumpDalvik = false;
17065         boolean dumpSummaryOnly = false;
17066         boolean dumpUnreachable = false;
17067         boolean oomOnly = false;
17068         boolean isCompact = false;
17069         boolean localOnly = false;
17070         boolean packages = false;
17071         boolean isCheckinRequest = false;
17072         boolean dumpSwapPss = false;
17073
17074         int opti = 0;
17075         while (opti < args.length) {
17076             String opt = args[opti];
17077             if (opt == null || opt.length() <= 0 || opt.charAt(0) != '-') {
17078                 break;
17079             }
17080             opti++;
17081             if ("-a".equals(opt)) {
17082                 dumpDetails = true;
17083                 dumpFullDetails = true;
17084                 dumpDalvik = true;
17085                 dumpSwapPss = true;
17086             } else if ("-d".equals(opt)) {
17087                 dumpDalvik = true;
17088             } else if ("-c".equals(opt)) {
17089                 isCompact = true;
17090             } else if ("-s".equals(opt)) {
17091                 dumpDetails = true;
17092                 dumpSummaryOnly = true;
17093             } else if ("-S".equals(opt)) {
17094                 dumpSwapPss = true;
17095             } else if ("--unreachable".equals(opt)) {
17096                 dumpUnreachable = true;
17097             } else if ("--oom".equals(opt)) {
17098                 oomOnly = true;
17099             } else if ("--local".equals(opt)) {
17100                 localOnly = true;
17101             } else if ("--package".equals(opt)) {
17102                 packages = true;
17103             } else if ("--checkin".equals(opt)) {
17104                 isCheckinRequest = true;
17105
17106             } else if ("-h".equals(opt)) {
17107                 pw.println("meminfo dump options: [-a] [-d] [-c] [-s] [--oom] [process]");
17108                 pw.println("  -a: include all available information for each process.");
17109                 pw.println("  -d: include dalvik details.");
17110                 pw.println("  -c: dump in a compact machine-parseable representation.");
17111                 pw.println("  -s: dump only summary of application memory usage.");
17112                 pw.println("  -S: dump also SwapPss.");
17113                 pw.println("  --oom: only show processes organized by oom adj.");
17114                 pw.println("  --local: only collect details locally, don't call process.");
17115                 pw.println("  --package: interpret process arg as package, dumping all");
17116                 pw.println("             processes that have loaded that package.");
17117                 pw.println("  --checkin: dump data for a checkin");
17118                 pw.println("If [process] is specified it can be the name or ");
17119                 pw.println("pid of a specific process to dump.");
17120                 return;
17121             } else {
17122                 pw.println("Unknown argument: " + opt + "; use -h for help");
17123             }
17124         }
17125
17126         long uptime = SystemClock.uptimeMillis();
17127         long realtime = SystemClock.elapsedRealtime();
17128         final long[] tmpLong = new long[1];
17129
17130         ArrayList<ProcessRecord> procs = collectProcesses(pw, opti, packages, args);
17131         if (procs == null) {
17132             // No Java processes.  Maybe they want to print a native process.
17133             if (args != null && args.length > opti
17134                     && args[opti].charAt(0) != '-') {
17135                 ArrayList<ProcessCpuTracker.Stats> nativeProcs
17136                         = new ArrayList<ProcessCpuTracker.Stats>();
17137                 updateCpuStatsNow();
17138                 int findPid = -1;
17139                 try {
17140                     findPid = Integer.parseInt(args[opti]);
17141                 } catch (NumberFormatException e) {
17142                 }
17143                 synchronized (mProcessCpuTracker) {
17144                     final int N = mProcessCpuTracker.countStats();
17145                     for (int i=0; i<N; i++) {
17146                         ProcessCpuTracker.Stats st = mProcessCpuTracker.getStats(i);
17147                         if (st.pid == findPid || (st.baseName != null
17148                                 && st.baseName.equals(args[opti]))) {
17149                             nativeProcs.add(st);
17150                         }
17151                     }
17152                 }
17153                 if (nativeProcs.size() > 0) {
17154                     dumpApplicationMemoryUsageHeader(pw, uptime, realtime, isCheckinRequest,
17155                             isCompact);
17156                     Debug.MemoryInfo mi = null;
17157                     for (int i = nativeProcs.size() - 1 ; i >= 0 ; i--) {
17158                         final ProcessCpuTracker.Stats r = nativeProcs.get(i);
17159                         final int pid = r.pid;
17160                         if (!isCheckinRequest && dumpDetails) {
17161                             pw.println("\n** MEMINFO in pid " + pid + " [" + r.baseName + "] **");
17162                         }
17163                         if (mi == null) {
17164                             mi = new Debug.MemoryInfo();
17165                         }
17166                         if (dumpDetails || (!brief && !oomOnly)) {
17167                             Debug.getMemoryInfo(pid, mi);
17168                         } else {
17169                             mi.dalvikPss = (int)Debug.getPss(pid, tmpLong, null);
17170                             mi.dalvikPrivateDirty = (int)tmpLong[0];
17171                         }
17172                         ActivityThread.dumpMemInfoTable(pw, mi, isCheckinRequest, dumpFullDetails,
17173                                 dumpDalvik, dumpSummaryOnly, pid, r.baseName, 0, 0, 0, 0, 0, 0);
17174                         if (isCheckinRequest) {
17175                             pw.println();
17176                         }
17177                     }
17178                     return;
17179                 }
17180             }
17181             pw.println("No process found for: " + args[opti]);
17182             return;
17183         }
17184
17185         if (!brief && !oomOnly && (procs.size() == 1 || isCheckinRequest || packages)) {
17186             dumpDetails = true;
17187         }
17188
17189         dumpApplicationMemoryUsageHeader(pw, uptime, realtime, isCheckinRequest, isCompact);
17190
17191         String[] innerArgs = new String[args.length-opti];
17192         System.arraycopy(args, opti, innerArgs, 0, args.length-opti);
17193
17194         ArrayList<MemItem> procMems = new ArrayList<MemItem>();
17195         final SparseArray<MemItem> procMemsMap = new SparseArray<MemItem>();
17196         long nativePss = 0;
17197         long nativeSwapPss = 0;
17198         long dalvikPss = 0;
17199         long dalvikSwapPss = 0;
17200         long[] dalvikSubitemPss = dumpDalvik ? new long[Debug.MemoryInfo.NUM_DVK_STATS] :
17201                 EmptyArray.LONG;
17202         long[] dalvikSubitemSwapPss = dumpDalvik ? new long[Debug.MemoryInfo.NUM_DVK_STATS] :
17203                 EmptyArray.LONG;
17204         long otherPss = 0;
17205         long otherSwapPss = 0;
17206         long[] miscPss = new long[Debug.MemoryInfo.NUM_OTHER_STATS];
17207         long[] miscSwapPss = new long[Debug.MemoryInfo.NUM_OTHER_STATS];
17208
17209         long oomPss[] = new long[DUMP_MEM_OOM_LABEL.length];
17210         long oomSwapPss[] = new long[DUMP_MEM_OOM_LABEL.length];
17211         ArrayList<MemItem>[] oomProcs = (ArrayList<MemItem>[])
17212                 new ArrayList[DUMP_MEM_OOM_LABEL.length];
17213
17214         long totalPss = 0;
17215         long totalSwapPss = 0;
17216         long cachedPss = 0;
17217         long cachedSwapPss = 0;
17218         boolean hasSwapPss = false;
17219
17220         Debug.MemoryInfo mi = null;
17221         for (int i = procs.size() - 1 ; i >= 0 ; i--) {
17222             final ProcessRecord r = procs.get(i);
17223             final IApplicationThread thread;
17224             final int pid;
17225             final int oomAdj;
17226             final boolean hasActivities;
17227             synchronized (this) {
17228                 thread = r.thread;
17229                 pid = r.pid;
17230                 oomAdj = r.getSetAdjWithServices();
17231                 hasActivities = r.activities.size() > 0;
17232             }
17233             if (thread != null) {
17234                 if (!isCheckinRequest && dumpDetails) {
17235                     pw.println("\n** MEMINFO in pid " + pid + " [" + r.processName + "] **");
17236                 }
17237                 if (mi == null) {
17238                     mi = new Debug.MemoryInfo();
17239                 }
17240                 if (dumpDetails || (!brief && !oomOnly)) {
17241                     Debug.getMemoryInfo(pid, mi);
17242                     hasSwapPss = mi.hasSwappedOutPss;
17243                 } else {
17244                     mi.dalvikPss = (int)Debug.getPss(pid, tmpLong, null);
17245                     mi.dalvikPrivateDirty = (int)tmpLong[0];
17246                 }
17247                 if (dumpDetails) {
17248                     if (localOnly) {
17249                         ActivityThread.dumpMemInfoTable(pw, mi, isCheckinRequest, dumpFullDetails,
17250                                 dumpDalvik, dumpSummaryOnly, pid, r.processName, 0, 0, 0, 0, 0, 0);
17251                         if (isCheckinRequest) {
17252                             pw.println();
17253                         }
17254                     } else {
17255                         pw.flush();
17256                         try {
17257                             TransferPipe tp = new TransferPipe();
17258                             try {
17259                                 thread.dumpMemInfo(tp.getWriteFd(),
17260                                         mi, isCheckinRequest, dumpFullDetails,
17261                                         dumpDalvik, dumpSummaryOnly, dumpUnreachable, innerArgs);
17262                                 tp.go(fd);
17263                             } finally {
17264                                 tp.kill();
17265                             }
17266                         } catch (IOException e) {
17267                             if (!isCheckinRequest) {
17268                                 pw.println("Got IoException!");
17269                                 pw.flush();
17270                             }
17271                         } catch (RemoteException e) {
17272                             if (!isCheckinRequest) {
17273                                 pw.println("Got RemoteException!");
17274                                 pw.flush();
17275                             }
17276                         }
17277                     }
17278                 }
17279
17280                 final long myTotalPss = mi.getTotalPss();
17281                 final long myTotalUss = mi.getTotalUss();
17282                 final long myTotalSwapPss = mi.getTotalSwappedOutPss();
17283
17284                 synchronized (this) {
17285                     if (r.thread != null && oomAdj == r.getSetAdjWithServices()) {
17286                         // Record this for posterity if the process has been stable.
17287                         r.baseProcessTracker.addPss(myTotalPss, myTotalUss, true, r.pkgList);
17288                     }
17289                 }
17290
17291                 if (!isCheckinRequest && mi != null) {
17292                     totalPss += myTotalPss;
17293                     totalSwapPss += myTotalSwapPss;
17294                     MemItem pssItem = new MemItem(r.processName + " (pid " + pid +
17295                             (hasActivities ? " / activities)" : ")"), r.processName, myTotalPss,
17296                             myTotalSwapPss, pid, hasActivities);
17297                     procMems.add(pssItem);
17298                     procMemsMap.put(pid, pssItem);
17299
17300                     nativePss += mi.nativePss;
17301                     nativeSwapPss += mi.nativeSwappedOutPss;
17302                     dalvikPss += mi.dalvikPss;
17303                     dalvikSwapPss += mi.dalvikSwappedOutPss;
17304                     for (int j=0; j<dalvikSubitemPss.length; j++) {
17305                         dalvikSubitemPss[j] += mi.getOtherPss(Debug.MemoryInfo.NUM_OTHER_STATS + j);
17306                         dalvikSubitemSwapPss[j] +=
17307                                 mi.getOtherSwappedOutPss(Debug.MemoryInfo.NUM_OTHER_STATS + j);
17308                     }
17309                     otherPss += mi.otherPss;
17310                     otherSwapPss += mi.otherSwappedOutPss;
17311                     for (int j=0; j<Debug.MemoryInfo.NUM_OTHER_STATS; j++) {
17312                         long mem = mi.getOtherPss(j);
17313                         miscPss[j] += mem;
17314                         otherPss -= mem;
17315                         mem = mi.getOtherSwappedOutPss(j);
17316                         miscSwapPss[j] += mem;
17317                         otherSwapPss -= mem;
17318                     }
17319
17320                     if (oomAdj >= ProcessList.CACHED_APP_MIN_ADJ) {
17321                         cachedPss += myTotalPss;
17322                         cachedSwapPss += myTotalSwapPss;
17323                     }
17324
17325                     for (int oomIndex=0; oomIndex<oomPss.length; oomIndex++) {
17326                         if (oomIndex == (oomPss.length - 1)
17327                                 || (oomAdj >= DUMP_MEM_OOM_ADJ[oomIndex]
17328                                         && oomAdj < DUMP_MEM_OOM_ADJ[oomIndex + 1])) {
17329                             oomPss[oomIndex] += myTotalPss;
17330                             oomSwapPss[oomIndex] += myTotalSwapPss;
17331                             if (oomProcs[oomIndex] == null) {
17332                                 oomProcs[oomIndex] = new ArrayList<MemItem>();
17333                             }
17334                             oomProcs[oomIndex].add(pssItem);
17335                             break;
17336                         }
17337                     }
17338                 }
17339             }
17340         }
17341
17342         long nativeProcTotalPss = 0;
17343
17344         if (!isCheckinRequest && procs.size() > 1 && !packages) {
17345             // If we are showing aggregations, also look for native processes to
17346             // include so that our aggregations are more accurate.
17347             updateCpuStatsNow();
17348             mi = null;
17349             synchronized (mProcessCpuTracker) {
17350                 final int N = mProcessCpuTracker.countStats();
17351                 for (int i=0; i<N; i++) {
17352                     ProcessCpuTracker.Stats st = mProcessCpuTracker.getStats(i);
17353                     if (st.vsize > 0 && procMemsMap.indexOfKey(st.pid) < 0) {
17354                         if (mi == null) {
17355                             mi = new Debug.MemoryInfo();
17356                         }
17357                         if (!brief && !oomOnly) {
17358                             Debug.getMemoryInfo(st.pid, mi);
17359                         } else {
17360                             mi.nativePss = (int)Debug.getPss(st.pid, tmpLong, null);
17361                             mi.nativePrivateDirty = (int)tmpLong[0];
17362                         }
17363
17364                         final long myTotalPss = mi.getTotalPss();
17365                         final long myTotalSwapPss = mi.getTotalSwappedOutPss();
17366                         totalPss += myTotalPss;
17367                         nativeProcTotalPss += myTotalPss;
17368
17369                         MemItem pssItem = new MemItem(st.name + " (pid " + st.pid + ")",
17370                                 st.name, myTotalPss, mi.getSummaryTotalSwapPss(), st.pid, false);
17371                         procMems.add(pssItem);
17372
17373                         nativePss += mi.nativePss;
17374                         nativeSwapPss += mi.nativeSwappedOutPss;
17375                         dalvikPss += mi.dalvikPss;
17376                         dalvikSwapPss += mi.dalvikSwappedOutPss;
17377                         for (int j=0; j<dalvikSubitemPss.length; j++) {
17378                             dalvikSubitemPss[j] += mi.getOtherPss(Debug.MemoryInfo.NUM_OTHER_STATS + j);
17379                             dalvikSubitemSwapPss[j] +=
17380                                     mi.getOtherSwappedOutPss(Debug.MemoryInfo.NUM_OTHER_STATS + j);
17381                         }
17382                         otherPss += mi.otherPss;
17383                         otherSwapPss += mi.otherSwappedOutPss;
17384                         for (int j=0; j<Debug.MemoryInfo.NUM_OTHER_STATS; j++) {
17385                             long mem = mi.getOtherPss(j);
17386                             miscPss[j] += mem;
17387                             otherPss -= mem;
17388                             mem = mi.getOtherSwappedOutPss(j);
17389                             miscSwapPss[j] += mem;
17390                             otherSwapPss -= mem;
17391                         }
17392                         oomPss[0] += myTotalPss;
17393                         oomSwapPss[0] += myTotalSwapPss;
17394                         if (oomProcs[0] == null) {
17395                             oomProcs[0] = new ArrayList<MemItem>();
17396                         }
17397                         oomProcs[0].add(pssItem);
17398                     }
17399                 }
17400             }
17401
17402             ArrayList<MemItem> catMems = new ArrayList<MemItem>();
17403
17404             catMems.add(new MemItem("Native", "Native", nativePss, nativeSwapPss, -1));
17405             final MemItem dalvikItem =
17406                     new MemItem("Dalvik", "Dalvik", dalvikPss, dalvikSwapPss, -2);
17407             if (dalvikSubitemPss.length > 0) {
17408                 dalvikItem.subitems = new ArrayList<MemItem>();
17409                 for (int j=0; j<dalvikSubitemPss.length; j++) {
17410                     final String name = Debug.MemoryInfo.getOtherLabel(
17411                             Debug.MemoryInfo.NUM_OTHER_STATS + j);
17412                     dalvikItem.subitems.add(new MemItem(name, name, dalvikSubitemPss[j],
17413                                     dalvikSubitemSwapPss[j], j));
17414                 }
17415             }
17416             catMems.add(dalvikItem);
17417             catMems.add(new MemItem("Unknown", "Unknown", otherPss, otherSwapPss, -3));
17418             for (int j=0; j<Debug.MemoryInfo.NUM_OTHER_STATS; j++) {
17419                 String label = Debug.MemoryInfo.getOtherLabel(j);
17420                 catMems.add(new MemItem(label, label, miscPss[j], miscSwapPss[j], j));
17421             }
17422
17423             ArrayList<MemItem> oomMems = new ArrayList<MemItem>();
17424             for (int j=0; j<oomPss.length; j++) {
17425                 if (oomPss[j] != 0) {
17426                     String label = isCompact ? DUMP_MEM_OOM_COMPACT_LABEL[j]
17427                             : DUMP_MEM_OOM_LABEL[j];
17428                     MemItem item = new MemItem(label, label, oomPss[j], oomSwapPss[j],
17429                             DUMP_MEM_OOM_ADJ[j]);
17430                     item.subitems = oomProcs[j];
17431                     oomMems.add(item);
17432                 }
17433             }
17434
17435             dumpSwapPss = dumpSwapPss && hasSwapPss && totalSwapPss != 0;
17436             if (!brief && !oomOnly && !isCompact) {
17437                 pw.println();
17438                 pw.println("Total PSS by process:");
17439                 dumpMemItems(pw, "  ", "proc", procMems, true, isCompact, dumpSwapPss);
17440                 pw.println();
17441             }
17442             if (!isCompact) {
17443                 pw.println("Total PSS by OOM adjustment:");
17444             }
17445             dumpMemItems(pw, "  ", "oom", oomMems, false, isCompact, dumpSwapPss);
17446             if (!brief && !oomOnly) {
17447                 PrintWriter out = categoryPw != null ? categoryPw : pw;
17448                 if (!isCompact) {
17449                     out.println();
17450                     out.println("Total PSS by category:");
17451                 }
17452                 dumpMemItems(out, "  ", "cat", catMems, true, isCompact, dumpSwapPss);
17453             }
17454             if (!isCompact) {
17455                 pw.println();
17456             }
17457             MemInfoReader memInfo = new MemInfoReader();
17458             memInfo.readMemInfo();
17459             if (nativeProcTotalPss > 0) {
17460                 synchronized (this) {
17461                     final long cachedKb = memInfo.getCachedSizeKb();
17462                     final long freeKb = memInfo.getFreeSizeKb();
17463                     final long zramKb = memInfo.getZramTotalSizeKb();
17464                     final long kernelKb = memInfo.getKernelUsedSizeKb();
17465                     EventLogTags.writeAmMeminfo(cachedKb*1024, freeKb*1024, zramKb*1024,
17466                             kernelKb*1024, nativeProcTotalPss*1024);
17467                     mProcessStats.addSysMemUsageLocked(cachedKb, freeKb, zramKb, kernelKb,
17468                             nativeProcTotalPss);
17469                 }
17470             }
17471             if (!brief) {
17472                 if (!isCompact) {
17473                     pw.print("Total RAM: "); pw.print(stringifyKBSize(memInfo.getTotalSizeKb()));
17474                     pw.print(" (status ");
17475                     switch (mLastMemoryLevel) {
17476                         case ProcessStats.ADJ_MEM_FACTOR_NORMAL:
17477                             pw.println("normal)");
17478                             break;
17479                         case ProcessStats.ADJ_MEM_FACTOR_MODERATE:
17480                             pw.println("moderate)");
17481                             break;
17482                         case ProcessStats.ADJ_MEM_FACTOR_LOW:
17483                             pw.println("low)");
17484                             break;
17485                         case ProcessStats.ADJ_MEM_FACTOR_CRITICAL:
17486                             pw.println("critical)");
17487                             break;
17488                         default:
17489                             pw.print(mLastMemoryLevel);
17490                             pw.println(")");
17491                             break;
17492                     }
17493                     pw.print(" Free RAM: ");
17494                     pw.print(stringifyKBSize(cachedPss + memInfo.getCachedSizeKb()
17495                             + memInfo.getFreeSizeKb()));
17496                     pw.print(" (");
17497                     pw.print(stringifyKBSize(cachedPss));
17498                     pw.print(" cached pss + ");
17499                     pw.print(stringifyKBSize(memInfo.getCachedSizeKb()));
17500                     pw.print(" cached kernel + ");
17501                     pw.print(stringifyKBSize(memInfo.getFreeSizeKb()));
17502                     pw.println(" free)");
17503                 } else {
17504                     pw.print("ram,"); pw.print(memInfo.getTotalSizeKb()); pw.print(",");
17505                     pw.print(cachedPss + memInfo.getCachedSizeKb()
17506                             + memInfo.getFreeSizeKb()); pw.print(",");
17507                     pw.println(totalPss - cachedPss);
17508                 }
17509             }
17510             long lostRAM = memInfo.getTotalSizeKb() - (totalPss - totalSwapPss)
17511                     - memInfo.getFreeSizeKb() - memInfo.getCachedSizeKb()
17512                     - memInfo.getKernelUsedSizeKb() - memInfo.getZramTotalSizeKb();
17513             if (!isCompact) {
17514                 pw.print(" Used RAM: "); pw.print(stringifyKBSize(totalPss - cachedPss
17515                         + memInfo.getKernelUsedSizeKb())); pw.print(" (");
17516                 pw.print(stringifyKBSize(totalPss - cachedPss)); pw.print(" used pss + ");
17517                 pw.print(stringifyKBSize(memInfo.getKernelUsedSizeKb())); pw.print(" kernel)\n");
17518                 pw.print(" Lost RAM: "); pw.println(stringifyKBSize(lostRAM));
17519             } else {
17520                 pw.print("lostram,"); pw.println(lostRAM);
17521             }
17522             if (!brief) {
17523                 if (memInfo.getZramTotalSizeKb() != 0) {
17524                     if (!isCompact) {
17525                         pw.print("     ZRAM: ");
17526                         pw.print(stringifyKBSize(memInfo.getZramTotalSizeKb()));
17527                                 pw.print(" physical used for ");
17528                                 pw.print(stringifyKBSize(memInfo.getSwapTotalSizeKb()
17529                                         - memInfo.getSwapFreeSizeKb()));
17530                                 pw.print(" in swap (");
17531                                 pw.print(stringifyKBSize(memInfo.getSwapTotalSizeKb()));
17532                                 pw.println(" total swap)");
17533                     } else {
17534                         pw.print("zram,"); pw.print(memInfo.getZramTotalSizeKb()); pw.print(",");
17535                                 pw.print(memInfo.getSwapTotalSizeKb()); pw.print(",");
17536                                 pw.println(memInfo.getSwapFreeSizeKb());
17537                     }
17538                 }
17539                 final long[] ksm = getKsmInfo();
17540                 if (!isCompact) {
17541                     if (ksm[KSM_SHARING] != 0 || ksm[KSM_SHARED] != 0 || ksm[KSM_UNSHARED] != 0
17542                             || ksm[KSM_VOLATILE] != 0) {
17543                         pw.print("      KSM: "); pw.print(stringifyKBSize(ksm[KSM_SHARING]));
17544                                 pw.print(" saved from shared ");
17545                                 pw.print(stringifyKBSize(ksm[KSM_SHARED]));
17546                         pw.print("           "); pw.print(stringifyKBSize(ksm[KSM_UNSHARED]));
17547                                 pw.print(" unshared; ");
17548                                 pw.print(stringifyKBSize(
17549                                              ksm[KSM_VOLATILE])); pw.println(" volatile");
17550                     }
17551                     pw.print("   Tuning: ");
17552                     pw.print(ActivityManager.staticGetMemoryClass());
17553                     pw.print(" (large ");
17554                     pw.print(ActivityManager.staticGetLargeMemoryClass());
17555                     pw.print("), oom ");
17556                     pw.print(stringifySize(
17557                                 mProcessList.getMemLevel(ProcessList.CACHED_APP_MAX_ADJ), 1024));
17558                     pw.print(", restore limit ");
17559                     pw.print(stringifyKBSize(mProcessList.getCachedRestoreThresholdKb()));
17560                     if (ActivityManager.isLowRamDeviceStatic()) {
17561                         pw.print(" (low-ram)");
17562                     }
17563                     if (ActivityManager.isHighEndGfx()) {
17564                         pw.print(" (high-end-gfx)");
17565                     }
17566                     pw.println();
17567                 } else {
17568                     pw.print("ksm,"); pw.print(ksm[KSM_SHARING]); pw.print(",");
17569                     pw.print(ksm[KSM_SHARED]); pw.print(","); pw.print(ksm[KSM_UNSHARED]);
17570                     pw.print(","); pw.println(ksm[KSM_VOLATILE]);
17571                     pw.print("tuning,");
17572                     pw.print(ActivityManager.staticGetMemoryClass());
17573                     pw.print(',');
17574                     pw.print(ActivityManager.staticGetLargeMemoryClass());
17575                     pw.print(',');
17576                     pw.print(mProcessList.getMemLevel(ProcessList.CACHED_APP_MAX_ADJ)/1024);
17577                     if (ActivityManager.isLowRamDeviceStatic()) {
17578                         pw.print(",low-ram");
17579                     }
17580                     if (ActivityManager.isHighEndGfx()) {
17581                         pw.print(",high-end-gfx");
17582                     }
17583                     pw.println();
17584                 }
17585             }
17586         }
17587     }
17588
17589     private void appendBasicMemEntry(StringBuilder sb, int oomAdj, int procState, long pss,
17590             long memtrack, String name) {
17591         sb.append("  ");
17592         sb.append(ProcessList.makeOomAdjString(oomAdj));
17593         sb.append(' ');
17594         sb.append(ProcessList.makeProcStateString(procState));
17595         sb.append(' ');
17596         ProcessList.appendRamKb(sb, pss);
17597         sb.append(": ");
17598         sb.append(name);
17599         if (memtrack > 0) {
17600             sb.append(" (");
17601             sb.append(stringifyKBSize(memtrack));
17602             sb.append(" memtrack)");
17603         }
17604     }
17605
17606     private void appendMemInfo(StringBuilder sb, ProcessMemInfo mi) {
17607         appendBasicMemEntry(sb, mi.oomAdj, mi.procState, mi.pss, mi.memtrack, mi.name);
17608         sb.append(" (pid ");
17609         sb.append(mi.pid);
17610         sb.append(") ");
17611         sb.append(mi.adjType);
17612         sb.append('\n');
17613         if (mi.adjReason != null) {
17614             sb.append("                      ");
17615             sb.append(mi.adjReason);
17616             sb.append('\n');
17617         }
17618     }
17619
17620     void reportMemUsage(ArrayList<ProcessMemInfo> memInfos) {
17621         final SparseArray<ProcessMemInfo> infoMap = new SparseArray<>(memInfos.size());
17622         for (int i=0, N=memInfos.size(); i<N; i++) {
17623             ProcessMemInfo mi = memInfos.get(i);
17624             infoMap.put(mi.pid, mi);
17625         }
17626         updateCpuStatsNow();
17627         long[] memtrackTmp = new long[1];
17628         final List<ProcessCpuTracker.Stats> stats;
17629         // Get a list of Stats that have vsize > 0
17630         synchronized (mProcessCpuTracker) {
17631             stats = mProcessCpuTracker.getStats((st) -> {
17632                 return st.vsize > 0;
17633             });
17634         }
17635         final int statsCount = stats.size();
17636         for (int i = 0; i < statsCount; i++) {
17637             ProcessCpuTracker.Stats st = stats.get(i);
17638             long pss = Debug.getPss(st.pid, null, memtrackTmp);
17639             if (pss > 0) {
17640                 if (infoMap.indexOfKey(st.pid) < 0) {
17641                     ProcessMemInfo mi = new ProcessMemInfo(st.name, st.pid,
17642                             ProcessList.NATIVE_ADJ, -1, "native", null);
17643                     mi.pss = pss;
17644                     mi.memtrack = memtrackTmp[0];
17645                     memInfos.add(mi);
17646                 }
17647             }
17648         }
17649
17650         long totalPss = 0;
17651         long totalMemtrack = 0;
17652         for (int i=0, N=memInfos.size(); i<N; i++) {
17653             ProcessMemInfo mi = memInfos.get(i);
17654             if (mi.pss == 0) {
17655                 mi.pss = Debug.getPss(mi.pid, null, memtrackTmp);
17656                 mi.memtrack = memtrackTmp[0];
17657             }
17658             totalPss += mi.pss;
17659             totalMemtrack += mi.memtrack;
17660         }
17661         Collections.sort(memInfos, new Comparator<ProcessMemInfo>() {
17662             @Override public int compare(ProcessMemInfo lhs, ProcessMemInfo rhs) {
17663                 if (lhs.oomAdj != rhs.oomAdj) {
17664                     return lhs.oomAdj < rhs.oomAdj ? -1 : 1;
17665                 }
17666                 if (lhs.pss != rhs.pss) {
17667                     return lhs.pss < rhs.pss ? 1 : -1;
17668                 }
17669                 return 0;
17670             }
17671         });
17672
17673         StringBuilder tag = new StringBuilder(128);
17674         StringBuilder stack = new StringBuilder(128);
17675         tag.append("Low on memory -- ");
17676         appendMemBucket(tag, totalPss, "total", false);
17677         appendMemBucket(stack, totalPss, "total", true);
17678
17679         StringBuilder fullNativeBuilder = new StringBuilder(1024);
17680         StringBuilder shortNativeBuilder = new StringBuilder(1024);
17681         StringBuilder fullJavaBuilder = new StringBuilder(1024);
17682
17683         boolean firstLine = true;
17684         int lastOomAdj = Integer.MIN_VALUE;
17685         long extraNativeRam = 0;
17686         long extraNativeMemtrack = 0;
17687         long cachedPss = 0;
17688         for (int i=0, N=memInfos.size(); i<N; i++) {
17689             ProcessMemInfo mi = memInfos.get(i);
17690
17691             if (mi.oomAdj >= ProcessList.CACHED_APP_MIN_ADJ) {
17692                 cachedPss += mi.pss;
17693             }
17694
17695             if (mi.oomAdj != ProcessList.NATIVE_ADJ
17696                     && (mi.oomAdj < ProcessList.SERVICE_ADJ
17697                             || mi.oomAdj == ProcessList.HOME_APP_ADJ
17698                             || mi.oomAdj == ProcessList.PREVIOUS_APP_ADJ)) {
17699                 if (lastOomAdj != mi.oomAdj) {
17700                     lastOomAdj = mi.oomAdj;
17701                     if (mi.oomAdj <= ProcessList.FOREGROUND_APP_ADJ) {
17702                         tag.append(" / ");
17703                     }
17704                     if (mi.oomAdj >= ProcessList.FOREGROUND_APP_ADJ) {
17705                         if (firstLine) {
17706                             stack.append(":");
17707                             firstLine = false;
17708                         }
17709                         stack.append("\n\t at ");
17710                     } else {
17711                         stack.append("$");
17712                     }
17713                 } else {
17714                     tag.append(" ");
17715                     stack.append("$");
17716                 }
17717                 if (mi.oomAdj <= ProcessList.FOREGROUND_APP_ADJ) {
17718                     appendMemBucket(tag, mi.pss, mi.name, false);
17719                 }
17720                 appendMemBucket(stack, mi.pss, mi.name, true);
17721                 if (mi.oomAdj >= ProcessList.FOREGROUND_APP_ADJ
17722                         && ((i+1) >= N || memInfos.get(i+1).oomAdj != lastOomAdj)) {
17723                     stack.append("(");
17724                     for (int k=0; k<DUMP_MEM_OOM_ADJ.length; k++) {
17725                         if (DUMP_MEM_OOM_ADJ[k] == mi.oomAdj) {
17726                             stack.append(DUMP_MEM_OOM_LABEL[k]);
17727                             stack.append(":");
17728                             stack.append(DUMP_MEM_OOM_ADJ[k]);
17729                         }
17730                     }
17731                     stack.append(")");
17732                 }
17733             }
17734
17735             appendMemInfo(fullNativeBuilder, mi);
17736             if (mi.oomAdj == ProcessList.NATIVE_ADJ) {
17737                 // The short form only has native processes that are >= 512K.
17738                 if (mi.pss >= 512) {
17739                     appendMemInfo(shortNativeBuilder, mi);
17740                 } else {
17741                     extraNativeRam += mi.pss;
17742                     extraNativeMemtrack += mi.memtrack;
17743                 }
17744             } else {
17745                 // Short form has all other details, but if we have collected RAM
17746                 // from smaller native processes let's dump a summary of that.
17747                 if (extraNativeRam > 0) {
17748                     appendBasicMemEntry(shortNativeBuilder, ProcessList.NATIVE_ADJ,
17749                             -1, extraNativeRam, extraNativeMemtrack, "(Other native)");
17750                     shortNativeBuilder.append('\n');
17751                     extraNativeRam = 0;
17752                 }
17753                 appendMemInfo(fullJavaBuilder, mi);
17754             }
17755         }
17756
17757         fullJavaBuilder.append("           ");
17758         ProcessList.appendRamKb(fullJavaBuilder, totalPss);
17759         fullJavaBuilder.append(": TOTAL");
17760         if (totalMemtrack > 0) {
17761             fullJavaBuilder.append(" (");
17762             fullJavaBuilder.append(stringifyKBSize(totalMemtrack));
17763             fullJavaBuilder.append(" memtrack)");
17764         } else {
17765         }
17766         fullJavaBuilder.append("\n");
17767
17768         MemInfoReader memInfo = new MemInfoReader();
17769         memInfo.readMemInfo();
17770         final long[] infos = memInfo.getRawInfo();
17771
17772         StringBuilder memInfoBuilder = new StringBuilder(1024);
17773         Debug.getMemInfo(infos);
17774         memInfoBuilder.append("  MemInfo: ");
17775         memInfoBuilder.append(stringifyKBSize(infos[Debug.MEMINFO_SLAB])).append(" slab, ");
17776         memInfoBuilder.append(stringifyKBSize(infos[Debug.MEMINFO_SHMEM])).append(" shmem, ");
17777         memInfoBuilder.append(stringifyKBSize(
17778                                   infos[Debug.MEMINFO_VM_ALLOC_USED])).append(" vm alloc, ");
17779         memInfoBuilder.append(stringifyKBSize(
17780                                   infos[Debug.MEMINFO_PAGE_TABLES])).append(" page tables ");
17781         memInfoBuilder.append(stringifyKBSize(
17782                                   infos[Debug.MEMINFO_KERNEL_STACK])).append(" kernel stack\n");
17783         memInfoBuilder.append("           ");
17784         memInfoBuilder.append(stringifyKBSize(infos[Debug.MEMINFO_BUFFERS])).append(" buffers, ");
17785         memInfoBuilder.append(stringifyKBSize(infos[Debug.MEMINFO_CACHED])).append(" cached, ");
17786         memInfoBuilder.append(stringifyKBSize(infos[Debug.MEMINFO_MAPPED])).append(" mapped, ");
17787         memInfoBuilder.append(stringifyKBSize(infos[Debug.MEMINFO_FREE])).append(" free\n");
17788         if (infos[Debug.MEMINFO_ZRAM_TOTAL] != 0) {
17789             memInfoBuilder.append("  ZRAM: ");
17790             memInfoBuilder.append(stringifyKBSize(infos[Debug.MEMINFO_ZRAM_TOTAL]));
17791             memInfoBuilder.append(" RAM, ");
17792             memInfoBuilder.append(stringifyKBSize(infos[Debug.MEMINFO_SWAP_TOTAL]));
17793             memInfoBuilder.append(" swap total, ");
17794             memInfoBuilder.append(stringifyKBSize(infos[Debug.MEMINFO_SWAP_FREE]));
17795             memInfoBuilder.append(" swap free\n");
17796         }
17797         final long[] ksm = getKsmInfo();
17798         if (ksm[KSM_SHARING] != 0 || ksm[KSM_SHARED] != 0 || ksm[KSM_UNSHARED] != 0
17799                 || ksm[KSM_VOLATILE] != 0) {
17800             memInfoBuilder.append("  KSM: ");
17801             memInfoBuilder.append(stringifyKBSize(ksm[KSM_SHARING]));
17802             memInfoBuilder.append(" saved from shared ");
17803             memInfoBuilder.append(stringifyKBSize(ksm[KSM_SHARED]));
17804             memInfoBuilder.append("\n       ");
17805             memInfoBuilder.append(stringifyKBSize(ksm[KSM_UNSHARED]));
17806             memInfoBuilder.append(" unshared; ");
17807             memInfoBuilder.append(stringifyKBSize(ksm[KSM_VOLATILE]));
17808             memInfoBuilder.append(" volatile\n");
17809         }
17810         memInfoBuilder.append("  Free RAM: ");
17811         memInfoBuilder.append(stringifyKBSize(cachedPss + memInfo.getCachedSizeKb()
17812                 + memInfo.getFreeSizeKb()));
17813         memInfoBuilder.append("\n");
17814         memInfoBuilder.append("  Used RAM: ");
17815         memInfoBuilder.append(stringifyKBSize(
17816                                   totalPss - cachedPss + memInfo.getKernelUsedSizeKb()));
17817         memInfoBuilder.append("\n");
17818         memInfoBuilder.append("  Lost RAM: ");
17819         memInfoBuilder.append(stringifyKBSize(memInfo.getTotalSizeKb()
17820                 - totalPss - memInfo.getFreeSizeKb() - memInfo.getCachedSizeKb()
17821                 - memInfo.getKernelUsedSizeKb() - memInfo.getZramTotalSizeKb()));
17822         memInfoBuilder.append("\n");
17823         Slog.i(TAG, "Low on memory:");
17824         Slog.i(TAG, shortNativeBuilder.toString());
17825         Slog.i(TAG, fullJavaBuilder.toString());
17826         Slog.i(TAG, memInfoBuilder.toString());
17827
17828         StringBuilder dropBuilder = new StringBuilder(1024);
17829         /*
17830         StringWriter oomSw = new StringWriter();
17831         PrintWriter oomPw = new FastPrintWriter(oomSw, false, 256);
17832         StringWriter catSw = new StringWriter();
17833         PrintWriter catPw = new FastPrintWriter(catSw, false, 256);
17834         String[] emptyArgs = new String[] { };
17835         dumpApplicationMemoryUsage(null, oomPw, "  ", emptyArgs, true, catPw);
17836         oomPw.flush();
17837         String oomString = oomSw.toString();
17838         */
17839         dropBuilder.append("Low on memory:");
17840         dropBuilder.append(stack);
17841         dropBuilder.append('\n');
17842         dropBuilder.append(fullNativeBuilder);
17843         dropBuilder.append(fullJavaBuilder);
17844         dropBuilder.append('\n');
17845         dropBuilder.append(memInfoBuilder);
17846         dropBuilder.append('\n');
17847         /*
17848         dropBuilder.append(oomString);
17849         dropBuilder.append('\n');
17850         */
17851         StringWriter catSw = new StringWriter();
17852         synchronized (ActivityManagerService.this) {
17853             PrintWriter catPw = new FastPrintWriter(catSw, false, 256);
17854             String[] emptyArgs = new String[] { };
17855             catPw.println();
17856             dumpProcessesLocked(null, catPw, emptyArgs, 0, false, null);
17857             catPw.println();
17858             mServices.newServiceDumperLocked(null, catPw, emptyArgs, 0,
17859                     false, null).dumpLocked();
17860             catPw.println();
17861             dumpActivitiesLocked(null, catPw, emptyArgs, 0, false, false, null);
17862             catPw.flush();
17863         }
17864         dropBuilder.append(catSw.toString());
17865         addErrorToDropBox("lowmem", null, "system_server", null,
17866                 null, tag.toString(), dropBuilder.toString(), null, null);
17867         //Slog.i(TAG, "Sent to dropbox:");
17868         //Slog.i(TAG, dropBuilder.toString());
17869         synchronized (ActivityManagerService.this) {
17870             long now = SystemClock.uptimeMillis();
17871             if (mLastMemUsageReportTime < now) {
17872                 mLastMemUsageReportTime = now;
17873             }
17874         }
17875     }
17876
17877     /**
17878      * Searches array of arguments for the specified string
17879      * @param args array of argument strings
17880      * @param value value to search for
17881      * @return true if the value is contained in the array
17882      */
17883     private static boolean scanArgs(String[] args, String value) {
17884         if (args != null) {
17885             for (String arg : args) {
17886                 if (value.equals(arg)) {
17887                     return true;
17888                 }
17889             }
17890         }
17891         return false;
17892     }
17893
17894     private final boolean removeDyingProviderLocked(ProcessRecord proc,
17895             ContentProviderRecord cpr, boolean always) {
17896         final boolean inLaunching = mLaunchingProviders.contains(cpr);
17897
17898         if (!inLaunching || always) {
17899             synchronized (cpr) {
17900                 cpr.launchingApp = null;
17901                 cpr.notifyAll();
17902             }
17903             mProviderMap.removeProviderByClass(cpr.name, UserHandle.getUserId(cpr.uid));
17904             String names[] = cpr.info.authority.split(";");
17905             for (int j = 0; j < names.length; j++) {
17906                 mProviderMap.removeProviderByName(names[j], UserHandle.getUserId(cpr.uid));
17907             }
17908         }
17909
17910         for (int i = cpr.connections.size() - 1; i >= 0; i--) {
17911             ContentProviderConnection conn = cpr.connections.get(i);
17912             if (conn.waiting) {
17913                 // If this connection is waiting for the provider, then we don't
17914                 // need to mess with its process unless we are always removing
17915                 // or for some reason the provider is not currently launching.
17916                 if (inLaunching && !always) {
17917                     continue;
17918                 }
17919             }
17920             ProcessRecord capp = conn.client;
17921             conn.dead = true;
17922             if (conn.stableCount > 0) {
17923                 if (!capp.persistent && capp.thread != null
17924                         && capp.pid != 0
17925                         && capp.pid != MY_PID) {
17926                     capp.kill("depends on provider "
17927                             + cpr.name.flattenToShortString()
17928                             + " in dying proc " + (proc != null ? proc.processName : "??")
17929                             + " (adj " + (proc != null ? proc.setAdj : "??") + ")", true);
17930                 }
17931             } else if (capp.thread != null && conn.provider.provider != null) {
17932                 try {
17933                     capp.thread.unstableProviderDied(conn.provider.provider.asBinder());
17934                 } catch (RemoteException e) {
17935                 }
17936                 // In the protocol here, we don't expect the client to correctly
17937                 // clean up this connection, we'll just remove it.
17938                 cpr.connections.remove(i);
17939                 if (conn.client.conProviders.remove(conn)) {
17940                     stopAssociationLocked(capp.uid, capp.processName, cpr.uid, cpr.name);
17941                 }
17942             }
17943         }
17944
17945         if (inLaunching && always) {
17946             mLaunchingProviders.remove(cpr);
17947         }
17948         return inLaunching;
17949     }
17950
17951     /**
17952      * Main code for cleaning up a process when it has gone away.  This is
17953      * called both as a result of the process dying, or directly when stopping
17954      * a process when running in single process mode.
17955      *
17956      * @return Returns true if the given process has been restarted, so the
17957      * app that was passed in must remain on the process lists.
17958      */
17959     private final boolean cleanUpApplicationRecordLocked(ProcessRecord app,
17960             boolean restarting, boolean allowRestart, int index, boolean replacingPid) {
17961         if (index >= 0) {
17962             removeLruProcessLocked(app);
17963             ProcessList.remove(app.pid);
17964         }
17965
17966         mProcessesToGc.remove(app);
17967         mPendingPssProcesses.remove(app);
17968
17969         // Dismiss any open dialogs.
17970         if (app.crashDialog != null && !app.forceCrashReport) {
17971             app.crashDialog.dismiss();
17972             app.crashDialog = null;
17973         }
17974         if (app.anrDialog != null) {
17975             app.anrDialog.dismiss();
17976             app.anrDialog = null;
17977         }
17978         if (app.waitDialog != null) {
17979             app.waitDialog.dismiss();
17980             app.waitDialog = null;
17981         }
17982
17983         app.crashing = false;
17984         app.notResponding = false;
17985
17986         app.resetPackageList(mProcessStats);
17987         app.unlinkDeathRecipient();
17988         app.makeInactive(mProcessStats);
17989         app.waitingToKill = null;
17990         app.forcingToImportant = null;
17991         updateProcessForegroundLocked(app, false, false);
17992         app.foregroundActivities = false;
17993         app.hasShownUi = false;
17994         app.treatLikeActivity = false;
17995         app.hasAboveClient = false;
17996         app.hasClientActivities = false;
17997
17998         mServices.killServicesLocked(app, allowRestart);
17999
18000         boolean restart = false;
18001
18002         // Remove published content providers.
18003         for (int i = app.pubProviders.size() - 1; i >= 0; i--) {
18004             ContentProviderRecord cpr = app.pubProviders.valueAt(i);
18005             final boolean always = app.bad || !allowRestart;
18006             boolean inLaunching = removeDyingProviderLocked(app, cpr, always);
18007             if ((inLaunching || always) && cpr.hasConnectionOrHandle()) {
18008                 // We left the provider in the launching list, need to
18009                 // restart it.
18010                 restart = true;
18011             }
18012
18013             cpr.provider = null;
18014             cpr.proc = null;
18015         }
18016         app.pubProviders.clear();
18017
18018         // Take care of any launching providers waiting for this process.
18019         if (cleanupAppInLaunchingProvidersLocked(app, false)) {
18020             restart = true;
18021         }
18022
18023         // Unregister from connected content providers.
18024         if (!app.conProviders.isEmpty()) {
18025             for (int i = app.conProviders.size() - 1; i >= 0; i--) {
18026                 ContentProviderConnection conn = app.conProviders.get(i);
18027                 conn.provider.connections.remove(conn);
18028                 stopAssociationLocked(app.uid, app.processName, conn.provider.uid,
18029                         conn.provider.name);
18030             }
18031             app.conProviders.clear();
18032         }
18033
18034         // At this point there may be remaining entries in mLaunchingProviders
18035         // where we were the only one waiting, so they are no longer of use.
18036         // Look for these and clean up if found.
18037         // XXX Commented out for now.  Trying to figure out a way to reproduce
18038         // the actual situation to identify what is actually going on.
18039         if (false) {
18040             for (int i = mLaunchingProviders.size() - 1; i >= 0; i--) {
18041                 ContentProviderRecord cpr = mLaunchingProviders.get(i);
18042                 if (cpr.connections.size() <= 0 && !cpr.hasExternalProcessHandles()) {
18043                     synchronized (cpr) {
18044                         cpr.launchingApp = null;
18045                         cpr.notifyAll();
18046                     }
18047                 }
18048             }
18049         }
18050
18051         skipCurrentReceiverLocked(app);
18052
18053         // Unregister any receivers.
18054         for (int i = app.receivers.size() - 1; i >= 0; i--) {
18055             removeReceiverLocked(app.receivers.valueAt(i));
18056         }
18057         app.receivers.clear();
18058
18059         // If the app is undergoing backup, tell the backup manager about it
18060         if (mBackupTarget != null && app.pid == mBackupTarget.app.pid) {
18061             if (DEBUG_BACKUP || DEBUG_CLEANUP) Slog.d(TAG_CLEANUP, "App "
18062                     + mBackupTarget.appInfo + " died during backup");
18063             mHandler.post(new Runnable() {
18064                 @Override
18065                 public void run(){
18066                     try {
18067                         IBackupManager bm = IBackupManager.Stub.asInterface(
18068                                 ServiceManager.getService(Context.BACKUP_SERVICE));
18069                         bm.agentDisconnected(app.info.packageName);
18070                     } catch (RemoteException e) {
18071                         // can't happen; backup manager is local
18072                     }
18073                 }
18074             });
18075         }
18076
18077         for (int i = mPendingProcessChanges.size() - 1; i >= 0; i--) {
18078             ProcessChangeItem item = mPendingProcessChanges.get(i);
18079             if (item.pid == app.pid) {
18080                 mPendingProcessChanges.remove(i);
18081                 mAvailProcessChanges.add(item);
18082             }
18083         }
18084         mUiHandler.obtainMessage(DISPATCH_PROCESS_DIED_UI_MSG, app.pid, app.info.uid,
18085                 null).sendToTarget();
18086
18087         // If the caller is restarting this app, then leave it in its
18088         // current lists and let the caller take care of it.
18089         if (restarting) {
18090             return false;
18091         }
18092
18093         if (!app.persistent || app.isolated) {
18094             if (DEBUG_PROCESSES || DEBUG_CLEANUP) Slog.v(TAG_CLEANUP,
18095                     "Removing non-persistent process during cleanup: " + app);
18096             if (!replacingPid) {
18097                 removeProcessNameLocked(app.processName, app.uid, app);
18098             }
18099             if (mHeavyWeightProcess == app) {
18100                 mHandler.sendMessage(mHandler.obtainMessage(CANCEL_HEAVY_NOTIFICATION_MSG,
18101                         mHeavyWeightProcess.userId, 0));
18102                 mHeavyWeightProcess = null;
18103             }
18104         } else if (!app.removed) {
18105             // This app is persistent, so we need to keep its record around.
18106             // If it is not already on the pending app list, add it there
18107             // and start a new process for it.
18108             if (mPersistentStartingProcesses.indexOf(app) < 0) {
18109                 mPersistentStartingProcesses.add(app);
18110                 restart = true;
18111             }
18112         }
18113         if ((DEBUG_PROCESSES || DEBUG_CLEANUP) && mProcessesOnHold.contains(app)) Slog.v(
18114                 TAG_CLEANUP, "Clean-up removing on hold: " + app);
18115         mProcessesOnHold.remove(app);
18116
18117         if (app == mHomeProcess) {
18118             mHomeProcess = null;
18119         }
18120         if (app == mPreviousProcess) {
18121             mPreviousProcess = null;
18122         }
18123
18124         if (restart && !app.isolated) {
18125             // We have components that still need to be running in the
18126             // process, so re-launch it.
18127             if (index < 0) {
18128                 ProcessList.remove(app.pid);
18129             }
18130             addProcessNameLocked(app);
18131             startProcessLocked(app, "restart", app.processName);
18132             return true;
18133         } else if (app.pid > 0 && app.pid != MY_PID) {
18134             // Goodbye!
18135             boolean removed;
18136             synchronized (mPidsSelfLocked) {
18137                 mPidsSelfLocked.remove(app.pid);
18138                 mHandler.removeMessages(PROC_START_TIMEOUT_MSG, app);
18139             }
18140             mBatteryStatsService.noteProcessFinish(app.processName, app.info.uid);
18141             if (app.isolated) {
18142                 mBatteryStatsService.removeIsolatedUid(app.uid, app.info.uid);
18143             }
18144             app.setPid(0);
18145         }
18146         return false;
18147     }
18148
18149     boolean checkAppInLaunchingProvidersLocked(ProcessRecord app) {
18150         for (int i = mLaunchingProviders.size() - 1; i >= 0; i--) {
18151             ContentProviderRecord cpr = mLaunchingProviders.get(i);
18152             if (cpr.launchingApp == app) {
18153                 return true;
18154             }
18155         }
18156         return false;
18157     }
18158
18159     boolean cleanupAppInLaunchingProvidersLocked(ProcessRecord app, boolean alwaysBad) {
18160         // Look through the content providers we are waiting to have launched,
18161         // and if any run in this process then either schedule a restart of
18162         // the process or kill the client waiting for it if this process has
18163         // gone bad.
18164         boolean restart = false;
18165         for (int i = mLaunchingProviders.size() - 1; i >= 0; i--) {
18166             ContentProviderRecord cpr = mLaunchingProviders.get(i);
18167             if (cpr.launchingApp == app) {
18168                 if (!alwaysBad && !app.bad && cpr.hasConnectionOrHandle()) {
18169                     restart = true;
18170                 } else {
18171                     removeDyingProviderLocked(app, cpr, true);
18172                 }
18173             }
18174         }
18175         return restart;
18176     }
18177
18178     // =========================================================
18179     // SERVICES
18180     // =========================================================
18181
18182     @Override
18183     public List<ActivityManager.RunningServiceInfo> getServices(int maxNum,
18184             int flags) {
18185         enforceNotIsolatedCaller("getServices");
18186
18187         final int callingUid = Binder.getCallingUid();
18188         final boolean canInteractAcrossUsers = (ActivityManager.checkUidPermission(
18189             INTERACT_ACROSS_USERS_FULL, callingUid) == PERMISSION_GRANTED);
18190         final boolean allowed = isGetTasksAllowed("getServices", Binder.getCallingPid(),
18191             callingUid);
18192         synchronized (this) {
18193             return mServices.getRunningServiceInfoLocked(maxNum, flags, callingUid,
18194                 allowed, canInteractAcrossUsers);
18195         }
18196     }
18197
18198     @Override
18199     public PendingIntent getRunningServiceControlPanel(ComponentName name) {
18200         enforceNotIsolatedCaller("getRunningServiceControlPanel");
18201         synchronized (this) {
18202             return mServices.getRunningServiceControlPanelLocked(name);
18203         }
18204     }
18205
18206     @Override
18207     public ComponentName startService(IApplicationThread caller, Intent service,
18208             String resolvedType, boolean requireForeground, String callingPackage, int userId)
18209             throws TransactionTooLargeException {
18210         enforceNotIsolatedCaller("startService");
18211         // Refuse possible leaked file descriptors
18212         if (service != null && service.hasFileDescriptors() == true) {
18213             throw new IllegalArgumentException("File descriptors passed in Intent");
18214         }
18215
18216         if (callingPackage == null) {
18217             throw new IllegalArgumentException("callingPackage cannot be null");
18218         }
18219
18220         if (DEBUG_SERVICE) Slog.v(TAG_SERVICE,
18221                 "*** startService: " + service + " type=" + resolvedType + " fg=" + requireForeground);
18222         synchronized(this) {
18223             final int callingPid = Binder.getCallingPid();
18224             final int callingUid = Binder.getCallingUid();
18225             final long origId = Binder.clearCallingIdentity();
18226             ComponentName res;
18227             try {
18228                 res = mServices.startServiceLocked(caller, service,
18229                         resolvedType, callingPid, callingUid,
18230                         requireForeground, callingPackage, userId);
18231             } finally {
18232                 Binder.restoreCallingIdentity(origId);
18233             }
18234             return res;
18235         }
18236     }
18237
18238     ComponentName startServiceInPackage(int uid, Intent service, String resolvedType,
18239             boolean fgRequired, String callingPackage, int userId)
18240             throws TransactionTooLargeException {
18241         synchronized(this) {
18242             if (DEBUG_SERVICE) Slog.v(TAG_SERVICE,
18243                     "startServiceInPackage: " + service + " type=" + resolvedType);
18244             final long origId = Binder.clearCallingIdentity();
18245             ComponentName res;
18246             try {
18247                 res = mServices.startServiceLocked(null, service,
18248                         resolvedType, -1, uid, fgRequired, callingPackage, userId);
18249             } finally {
18250                 Binder.restoreCallingIdentity(origId);
18251             }
18252             return res;
18253         }
18254     }
18255
18256     @Override
18257     public int stopService(IApplicationThread caller, Intent service,
18258             String resolvedType, int userId) {
18259         enforceNotIsolatedCaller("stopService");
18260         // Refuse possible leaked file descriptors
18261         if (service != null && service.hasFileDescriptors() == true) {
18262             throw new IllegalArgumentException("File descriptors passed in Intent");
18263         }
18264
18265         synchronized(this) {
18266             return mServices.stopServiceLocked(caller, service, resolvedType, userId);
18267         }
18268     }
18269
18270     @Override
18271     public IBinder peekService(Intent service, String resolvedType, String callingPackage) {
18272         enforceNotIsolatedCaller("peekService");
18273         // Refuse possible leaked file descriptors
18274         if (service != null && service.hasFileDescriptors() == true) {
18275             throw new IllegalArgumentException("File descriptors passed in Intent");
18276         }
18277
18278         if (callingPackage == null) {
18279             throw new IllegalArgumentException("callingPackage cannot be null");
18280         }
18281
18282         synchronized(this) {
18283             return mServices.peekServiceLocked(service, resolvedType, callingPackage);
18284         }
18285     }
18286
18287     @Override
18288     public boolean stopServiceToken(ComponentName className, IBinder token,
18289             int startId) {
18290         synchronized(this) {
18291             return mServices.stopServiceTokenLocked(className, token, startId);
18292         }
18293     }
18294
18295     @Override
18296     public void setServiceForeground(ComponentName className, IBinder token,
18297             int id, Notification notification, int flags) {
18298         synchronized(this) {
18299             mServices.setServiceForegroundLocked(className, token, id, notification, flags);
18300         }
18301     }
18302
18303     @Override
18304     public int handleIncomingUser(int callingPid, int callingUid, int userId, boolean allowAll,
18305             boolean requireFull, String name, String callerPackage) {
18306         return mUserController.handleIncomingUser(callingPid, callingUid, userId, allowAll,
18307                 requireFull ? ALLOW_FULL_ONLY : ALLOW_NON_FULL, name, callerPackage);
18308     }
18309
18310     boolean isSingleton(String componentProcessName, ApplicationInfo aInfo,
18311             String className, int flags) {
18312         boolean result = false;
18313         // For apps that don't have pre-defined UIDs, check for permission
18314         if (UserHandle.getAppId(aInfo.uid) >= FIRST_APPLICATION_UID) {
18315             if ((flags & ServiceInfo.FLAG_SINGLE_USER) != 0) {
18316                 if (ActivityManager.checkUidPermission(
18317                         INTERACT_ACROSS_USERS,
18318                         aInfo.uid) != PackageManager.PERMISSION_GRANTED) {
18319                     ComponentName comp = new ComponentName(aInfo.packageName, className);
18320                     String msg = "Permission Denial: Component " + comp.flattenToShortString()
18321                             + " requests FLAG_SINGLE_USER, but app does not hold "
18322                             + INTERACT_ACROSS_USERS;
18323                     Slog.w(TAG, msg);
18324                     throw new SecurityException(msg);
18325                 }
18326                 // Permission passed
18327                 result = true;
18328             }
18329         } else if ("system".equals(componentProcessName)) {
18330             result = true;
18331         } else if ((flags & ServiceInfo.FLAG_SINGLE_USER) != 0) {
18332             // Phone app and persistent apps are allowed to export singleuser providers.
18333             result = UserHandle.isSameApp(aInfo.uid, PHONE_UID)
18334                     || (aInfo.flags & ApplicationInfo.FLAG_PERSISTENT) != 0;
18335         }
18336         if (DEBUG_MU) Slog.v(TAG_MU,
18337                 "isSingleton(" + componentProcessName + ", " + aInfo + ", " + className + ", 0x"
18338                 + Integer.toHexString(flags) + ") = " + result);
18339         return result;
18340     }
18341
18342     /**
18343      * Checks to see if the caller is in the same app as the singleton
18344      * component, or the component is in a special app. It allows special apps
18345      * to export singleton components but prevents exporting singleton
18346      * components for regular apps.
18347      */
18348     boolean isValidSingletonCall(int callingUid, int componentUid) {
18349         int componentAppId = UserHandle.getAppId(componentUid);
18350         return UserHandle.isSameApp(callingUid, componentUid)
18351                 || componentAppId == SYSTEM_UID
18352                 || componentAppId == PHONE_UID
18353                 || ActivityManager.checkUidPermission(INTERACT_ACROSS_USERS_FULL, componentUid)
18354                         == PackageManager.PERMISSION_GRANTED;
18355     }
18356
18357     public int bindService(IApplicationThread caller, IBinder token, Intent service,
18358             String resolvedType, IServiceConnection connection, int flags, String callingPackage,
18359             int userId) throws TransactionTooLargeException {
18360         enforceNotIsolatedCaller("bindService");
18361
18362         // Refuse possible leaked file descriptors
18363         if (service != null && service.hasFileDescriptors() == true) {
18364             throw new IllegalArgumentException("File descriptors passed in Intent");
18365         }
18366
18367         if (callingPackage == null) {
18368             throw new IllegalArgumentException("callingPackage cannot be null");
18369         }
18370
18371         synchronized(this) {
18372             return mServices.bindServiceLocked(caller, token, service,
18373                     resolvedType, connection, flags, callingPackage, userId);
18374         }
18375     }
18376
18377     public boolean unbindService(IServiceConnection connection) {
18378         synchronized (this) {
18379             return mServices.unbindServiceLocked(connection);
18380         }
18381     }
18382
18383     public void publishService(IBinder token, Intent intent, IBinder service) {
18384         // Refuse possible leaked file descriptors
18385         if (intent != null && intent.hasFileDescriptors() == true) {
18386             throw new IllegalArgumentException("File descriptors passed in Intent");
18387         }
18388
18389         synchronized(this) {
18390             if (!(token instanceof ServiceRecord)) {
18391                 throw new IllegalArgumentException("Invalid service token");
18392             }
18393             mServices.publishServiceLocked((ServiceRecord)token, intent, service);
18394         }
18395     }
18396
18397     public void unbindFinished(IBinder token, Intent intent, boolean doRebind) {
18398         // Refuse possible leaked file descriptors
18399         if (intent != null && intent.hasFileDescriptors() == true) {
18400             throw new IllegalArgumentException("File descriptors passed in Intent");
18401         }
18402
18403         synchronized(this) {
18404             mServices.unbindFinishedLocked((ServiceRecord)token, intent, doRebind);
18405         }
18406     }
18407
18408     public void serviceDoneExecuting(IBinder token, int type, int startId, int res) {
18409         synchronized(this) {
18410             if (!(token instanceof ServiceRecord)) {
18411                 Slog.e(TAG, "serviceDoneExecuting: Invalid service token=" + token);
18412                 throw new IllegalArgumentException("Invalid service token");
18413             }
18414             mServices.serviceDoneExecutingLocked((ServiceRecord)token, type, startId, res);
18415         }
18416     }
18417
18418     // =========================================================
18419     // BACKUP AND RESTORE
18420     // =========================================================
18421
18422     // Cause the target app to be launched if necessary and its backup agent
18423     // instantiated.  The backup agent will invoke backupAgentCreated() on the
18424     // activity manager to announce its creation.
18425     public boolean bindBackupAgent(String packageName, int backupMode, int userId) {
18426         if (DEBUG_BACKUP) Slog.v(TAG, "bindBackupAgent: app=" + packageName + " mode=" + backupMode);
18427         enforceCallingPermission("android.permission.CONFIRM_FULL_BACKUP", "bindBackupAgent");
18428
18429         IPackageManager pm = AppGlobals.getPackageManager();
18430         ApplicationInfo app = null;
18431         try {
18432             app = pm.getApplicationInfo(packageName, 0, userId);
18433         } catch (RemoteException e) {
18434             // can't happen; package manager is process-local
18435         }
18436         if (app == null) {
18437             Slog.w(TAG, "Unable to bind backup agent for " + packageName);
18438             return false;
18439         }
18440
18441         int oldBackupUid;
18442         int newBackupUid;
18443
18444         synchronized(this) {
18445             // !!! TODO: currently no check here that we're already bound
18446             BatteryStatsImpl.Uid.Pkg.Serv ss = null;
18447             BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
18448             synchronized (stats) {
18449                 ss = stats.getServiceStatsLocked(app.uid, app.packageName, app.name);
18450             }
18451
18452             // Backup agent is now in use, its package can't be stopped.
18453             try {
18454                 AppGlobals.getPackageManager().setPackageStoppedState(
18455                         app.packageName, false, UserHandle.getUserId(app.uid));
18456             } catch (RemoteException e) {
18457             } catch (IllegalArgumentException e) {
18458                 Slog.w(TAG, "Failed trying to unstop package "
18459                         + app.packageName + ": " + e);
18460             }
18461
18462             BackupRecord r = new BackupRecord(ss, app, backupMode);
18463             ComponentName hostingName =
18464                     (backupMode == ApplicationThreadConstants.BACKUP_MODE_INCREMENTAL)
18465                             ? new ComponentName(app.packageName, app.backupAgentName)
18466                             : new ComponentName("android", "FullBackupAgent");
18467             // startProcessLocked() returns existing proc's record if it's already running
18468             ProcessRecord proc = startProcessLocked(app.processName, app,
18469                     false, 0, "backup", hostingName, false, false, false);
18470             if (proc == null) {
18471                 Slog.e(TAG, "Unable to start backup agent process " + r);
18472                 return false;
18473             }
18474
18475             // If the app is a regular app (uid >= 10000) and not the system server or phone
18476             // process, etc, then mark it as being in full backup so that certain calls to the
18477             // process can be blocked. This is not reset to false anywhere because we kill the
18478             // process after the full backup is done and the ProcessRecord will vaporize anyway.
18479             if (UserHandle.isApp(app.uid) &&
18480                     backupMode == ApplicationThreadConstants.BACKUP_MODE_FULL) {
18481                 proc.inFullBackup = true;
18482             }
18483             r.app = proc;
18484             oldBackupUid = mBackupTarget != null ? mBackupTarget.appInfo.uid : -1;
18485             newBackupUid = proc.inFullBackup ? r.appInfo.uid : -1;
18486             mBackupTarget = r;
18487             mBackupAppName = app.packageName;
18488
18489             // Try not to kill the process during backup
18490             updateOomAdjLocked(proc, true);
18491
18492             // If the process is already attached, schedule the creation of the backup agent now.
18493             // If it is not yet live, this will be done when it attaches to the framework.
18494             if (proc.thread != null) {
18495                 if (DEBUG_BACKUP) Slog.v(TAG_BACKUP, "Agent proc already running: " + proc);
18496                 try {
18497                     proc.thread.scheduleCreateBackupAgent(app,
18498                             compatibilityInfoForPackageLocked(app), backupMode);
18499                 } catch (RemoteException e) {
18500                     // Will time out on the backup manager side
18501                 }
18502             } else {
18503                 if (DEBUG_BACKUP) Slog.v(TAG_BACKUP, "Agent proc not running, waiting for attach");
18504             }
18505             // Invariants: at this point, the target app process exists and the application
18506             // is either already running or in the process of coming up.  mBackupTarget and
18507             // mBackupAppName describe the app, so that when it binds back to the AM we
18508             // know that it's scheduled for a backup-agent operation.
18509         }
18510
18511         JobSchedulerInternal js = LocalServices.getService(JobSchedulerInternal.class);
18512         if (oldBackupUid != -1) {
18513             js.removeBackingUpUid(oldBackupUid);
18514         }
18515         if (newBackupUid != -1) {
18516             js.addBackingUpUid(newBackupUid);
18517         }
18518
18519         return true;
18520     }
18521
18522     @Override
18523     public void clearPendingBackup() {
18524         if (DEBUG_BACKUP) Slog.v(TAG_BACKUP, "clearPendingBackup");
18525         enforceCallingPermission("android.permission.BACKUP", "clearPendingBackup");
18526
18527         synchronized (this) {
18528             mBackupTarget = null;
18529             mBackupAppName = null;
18530         }
18531
18532         JobSchedulerInternal js = LocalServices.getService(JobSchedulerInternal.class);
18533         js.clearAllBackingUpUids();
18534     }
18535
18536     // A backup agent has just come up
18537     public void backupAgentCreated(String agentPackageName, IBinder agent) {
18538         if (DEBUG_BACKUP) Slog.v(TAG_BACKUP, "backupAgentCreated: " + agentPackageName
18539                 + " = " + agent);
18540
18541         synchronized(this) {
18542             if (!agentPackageName.equals(mBackupAppName)) {
18543                 Slog.e(TAG, "Backup agent created for " + agentPackageName + " but not requested!");
18544                 return;
18545             }
18546         }
18547
18548         long oldIdent = Binder.clearCallingIdentity();
18549         try {
18550             IBackupManager bm = IBackupManager.Stub.asInterface(
18551                     ServiceManager.getService(Context.BACKUP_SERVICE));
18552             bm.agentConnected(agentPackageName, agent);
18553         } catch (RemoteException e) {
18554             // can't happen; the backup manager service is local
18555         } catch (Exception e) {
18556             Slog.w(TAG, "Exception trying to deliver BackupAgent binding: ");
18557             e.printStackTrace();
18558         } finally {
18559             Binder.restoreCallingIdentity(oldIdent);
18560         }
18561     }
18562
18563     // done with this agent
18564     public void unbindBackupAgent(ApplicationInfo appInfo) {
18565         if (DEBUG_BACKUP) Slog.v(TAG_BACKUP, "unbindBackupAgent: " + appInfo);
18566         if (appInfo == null) {
18567             Slog.w(TAG, "unbind backup agent for null app");
18568             return;
18569         }
18570
18571         int oldBackupUid;
18572
18573         synchronized(this) {
18574             try {
18575                 if (mBackupAppName == null) {
18576                     Slog.w(TAG, "Unbinding backup agent with no active backup");
18577                     return;
18578                 }
18579
18580                 if (!mBackupAppName.equals(appInfo.packageName)) {
18581                     Slog.e(TAG, "Unbind of " + appInfo + " but is not the current backup target");
18582                     return;
18583                 }
18584
18585                 // Not backing this app up any more; reset its OOM adjustment
18586                 final ProcessRecord proc = mBackupTarget.app;
18587                 updateOomAdjLocked(proc, true);
18588                 proc.inFullBackup = false;
18589
18590                 oldBackupUid = mBackupTarget != null ? mBackupTarget.appInfo.uid : -1;
18591
18592                 // If the app crashed during backup, 'thread' will be null here
18593                 if (proc.thread != null) {
18594                     try {
18595                         proc.thread.scheduleDestroyBackupAgent(appInfo,
18596                                 compatibilityInfoForPackageLocked(appInfo));
18597                     } catch (Exception e) {
18598                         Slog.e(TAG, "Exception when unbinding backup agent:");
18599                         e.printStackTrace();
18600                     }
18601                 }
18602             } finally {
18603                 mBackupTarget = null;
18604                 mBackupAppName = null;
18605             }
18606         }
18607
18608         if (oldBackupUid != -1) {
18609             JobSchedulerInternal js = LocalServices.getService(JobSchedulerInternal.class);
18610             js.removeBackingUpUid(oldBackupUid);
18611         }
18612     }
18613
18614     // =========================================================
18615     // BROADCASTS
18616     // =========================================================
18617
18618     private boolean isInstantApp(ProcessRecord record, String callerPackage, int uid) {
18619         if (UserHandle.getAppId(uid) < FIRST_APPLICATION_UID) {
18620             return false;
18621         }
18622         // Easy case -- we have the app's ProcessRecord.
18623         if (record != null) {
18624             return record.info.isInstantApp();
18625         }
18626         // Otherwise check with PackageManager.
18627         if (callerPackage == null) {
18628             Slog.e(TAG, "isInstantApp with an application's uid, no record, and no package name");
18629             throw new IllegalArgumentException("Calling application did not provide package name");
18630         }
18631         mAppOpsService.checkPackage(uid, callerPackage);
18632         try {
18633             IPackageManager pm = AppGlobals.getPackageManager();
18634             return pm.isInstantApp(callerPackage, UserHandle.getUserId(uid));
18635         } catch (RemoteException e) {
18636             Slog.e(TAG, "Error looking up if " + callerPackage + " is an instant app.", e);
18637             return true;
18638         }
18639     }
18640
18641     boolean isPendingBroadcastProcessLocked(int pid) {
18642         return mFgBroadcastQueue.isPendingBroadcastProcessLocked(pid)
18643                 || mBgBroadcastQueue.isPendingBroadcastProcessLocked(pid);
18644     }
18645
18646     void skipPendingBroadcastLocked(int pid) {
18647             Slog.w(TAG, "Unattached app died before broadcast acknowledged, skipping");
18648             for (BroadcastQueue queue : mBroadcastQueues) {
18649                 queue.skipPendingBroadcastLocked(pid);
18650             }
18651     }
18652
18653     // The app just attached; send any pending broadcasts that it should receive
18654     boolean sendPendingBroadcastsLocked(ProcessRecord app) {
18655         boolean didSomething = false;
18656         for (BroadcastQueue queue : mBroadcastQueues) {
18657             didSomething |= queue.sendPendingBroadcastsLocked(app);
18658         }
18659         return didSomething;
18660     }
18661
18662     public Intent registerReceiver(IApplicationThread caller, String callerPackage,
18663             IIntentReceiver receiver, IntentFilter filter, String permission, int userId,
18664             int flags) {
18665         enforceNotIsolatedCaller("registerReceiver");
18666         ArrayList<Intent> stickyIntents = null;
18667         ProcessRecord callerApp = null;
18668         final boolean visibleToInstantApps
18669                 = (flags & Context.RECEIVER_VISIBLE_TO_INSTANT_APPS) != 0;
18670         int callingUid;
18671         int callingPid;
18672         boolean instantApp;
18673         synchronized(this) {
18674             if (caller != null) {
18675                 callerApp = getRecordForAppLocked(caller);
18676                 if (callerApp == null) {
18677                     throw new SecurityException(
18678                             "Unable to find app for caller " + caller
18679                             + " (pid=" + Binder.getCallingPid()
18680                             + ") when registering receiver " + receiver);
18681                 }
18682                 if (callerApp.info.uid != SYSTEM_UID &&
18683                         !callerApp.pkgList.containsKey(callerPackage) &&
18684                         !"android".equals(callerPackage)) {
18685                     throw new SecurityException("Given caller package " + callerPackage
18686                             + " is not running in process " + callerApp);
18687                 }
18688                 callingUid = callerApp.info.uid;
18689                 callingPid = callerApp.pid;
18690             } else {
18691                 callerPackage = null;
18692                 callingUid = Binder.getCallingUid();
18693                 callingPid = Binder.getCallingPid();
18694             }
18695
18696             instantApp = isInstantApp(callerApp, callerPackage, callingUid);
18697             userId = mUserController.handleIncomingUser(callingPid, callingUid, userId, true,
18698                     ALLOW_FULL_ONLY, "registerReceiver", callerPackage);
18699
18700             Iterator<String> actions = filter.actionsIterator();
18701             if (actions == null) {
18702                 ArrayList<String> noAction = new ArrayList<String>(1);
18703                 noAction.add(null);
18704                 actions = noAction.iterator();
18705             }
18706
18707             // Collect stickies of users
18708             int[] userIds = { UserHandle.USER_ALL, UserHandle.getUserId(callingUid) };
18709             while (actions.hasNext()) {
18710                 String action = actions.next();
18711                 for (int id : userIds) {
18712                     ArrayMap<String, ArrayList<Intent>> stickies = mStickyBroadcasts.get(id);
18713                     if (stickies != null) {
18714                         ArrayList<Intent> intents = stickies.get(action);
18715                         if (intents != null) {
18716                             if (stickyIntents == null) {
18717                                 stickyIntents = new ArrayList<Intent>();
18718                             }
18719                             stickyIntents.addAll(intents);
18720                         }
18721                     }
18722                 }
18723             }
18724         }
18725
18726         ArrayList<Intent> allSticky = null;
18727         if (stickyIntents != null) {
18728             final ContentResolver resolver = mContext.getContentResolver();
18729             // Look for any matching sticky broadcasts...
18730             for (int i = 0, N = stickyIntents.size(); i < N; i++) {
18731                 Intent intent = stickyIntents.get(i);
18732                 // Don't provided intents that aren't available to instant apps.
18733                 if (instantApp &&
18734                         (intent.getFlags() & Intent.FLAG_RECEIVER_VISIBLE_TO_INSTANT_APPS) == 0) {
18735                     continue;
18736                 }
18737                 // If intent has scheme "content", it will need to acccess
18738                 // provider that needs to lock mProviderMap in ActivityThread
18739                 // and also it may need to wait application response, so we
18740                 // cannot lock ActivityManagerService here.
18741                 if (filter.match(resolver, intent, true, TAG) >= 0) {
18742                     if (allSticky == null) {
18743                         allSticky = new ArrayList<Intent>();
18744                     }
18745                     allSticky.add(intent);
18746                 }
18747             }
18748         }
18749
18750         // The first sticky in the list is returned directly back to the client.
18751         Intent sticky = allSticky != null ? allSticky.get(0) : null;
18752         if (DEBUG_BROADCAST) Slog.v(TAG_BROADCAST, "Register receiver " + filter + ": " + sticky);
18753         if (receiver == null) {
18754             return sticky;
18755         }
18756
18757         synchronized (this) {
18758             if (callerApp != null && (callerApp.thread == null
18759                     || callerApp.thread.asBinder() != caller.asBinder())) {
18760                 // Original caller already died
18761                 return null;
18762             }
18763             ReceiverList rl = mRegisteredReceivers.get(receiver.asBinder());
18764             if (rl == null) {
18765                 rl = new ReceiverList(this, callerApp, callingPid, callingUid,
18766                         userId, receiver);
18767                 if (rl.app != null) {
18768                     rl.app.receivers.add(rl);
18769                 } else {
18770                     try {
18771                         receiver.asBinder().linkToDeath(rl, 0);
18772                     } catch (RemoteException e) {
18773                         return sticky;
18774                     }
18775                     rl.linkedToDeath = true;
18776                 }
18777                 mRegisteredReceivers.put(receiver.asBinder(), rl);
18778             } else if (rl.uid != callingUid) {
18779                 throw new IllegalArgumentException(
18780                         "Receiver requested to register for uid " + callingUid
18781                         + " was previously registered for uid " + rl.uid
18782                         + " callerPackage is " + callerPackage);
18783             } else if (rl.pid != callingPid) {
18784                 throw new IllegalArgumentException(
18785                         "Receiver requested to register for pid " + callingPid
18786                         + " was previously registered for pid " + rl.pid
18787                         + " callerPackage is " + callerPackage);
18788             } else if (rl.userId != userId) {
18789                 throw new IllegalArgumentException(
18790                         "Receiver requested to register for user " + userId
18791                         + " was previously registered for user " + rl.userId
18792                         + " callerPackage is " + callerPackage);
18793             }
18794             BroadcastFilter bf = new BroadcastFilter(filter, rl, callerPackage,
18795                     permission, callingUid, userId, instantApp, visibleToInstantApps);
18796             rl.add(bf);
18797             if (!bf.debugCheck()) {
18798                 Slog.w(TAG, "==> For Dynamic broadcast");
18799             }
18800             mReceiverResolver.addFilter(bf);
18801
18802             // Enqueue broadcasts for all existing stickies that match
18803             // this filter.
18804             if (allSticky != null) {
18805                 ArrayList receivers = new ArrayList();
18806                 receivers.add(bf);
18807
18808                 final int stickyCount = allSticky.size();
18809                 for (int i = 0; i < stickyCount; i++) {
18810                     Intent intent = allSticky.get(i);
18811                     BroadcastQueue queue = broadcastQueueForIntent(intent);
18812                     BroadcastRecord r = new BroadcastRecord(queue, intent, null,
18813                             null, -1, -1, false, null, null, AppOpsManager.OP_NONE, null, receivers,
18814                             null, 0, null, null, false, true, true, -1);
18815                     queue.enqueueParallelBroadcastLocked(r);
18816                     queue.scheduleBroadcastsLocked();
18817                 }
18818             }
18819
18820             return sticky;
18821         }
18822     }
18823
18824     public void unregisterReceiver(IIntentReceiver receiver) {
18825         if (DEBUG_BROADCAST) Slog.v(TAG_BROADCAST, "Unregister receiver: " + receiver);
18826
18827         final long origId = Binder.clearCallingIdentity();
18828         try {
18829             boolean doTrim = false;
18830
18831             synchronized(this) {
18832                 ReceiverList rl = mRegisteredReceivers.get(receiver.asBinder());
18833                 if (rl != null) {
18834                     final BroadcastRecord r = rl.curBroadcast;
18835                     if (r != null && r == r.queue.getMatchingOrderedReceiver(r)) {
18836                         final boolean doNext = r.queue.finishReceiverLocked(
18837                                 r, r.resultCode, r.resultData, r.resultExtras,
18838                                 r.resultAbort, false);
18839                         if (doNext) {
18840                             doTrim = true;
18841                             r.queue.processNextBroadcast(false);
18842                         }
18843                     }
18844
18845                     if (rl.app != null) {
18846                         rl.app.receivers.remove(rl);
18847                     }
18848                     removeReceiverLocked(rl);
18849                     if (rl.linkedToDeath) {
18850                         rl.linkedToDeath = false;
18851                         rl.receiver.asBinder().unlinkToDeath(rl, 0);
18852                     }
18853                 }
18854             }
18855
18856             // If we actually concluded any broadcasts, we might now be able
18857             // to trim the recipients' apps from our working set
18858             if (doTrim) {
18859                 trimApplications();
18860                 return;
18861             }
18862
18863         } finally {
18864             Binder.restoreCallingIdentity(origId);
18865         }
18866     }
18867
18868     void removeReceiverLocked(ReceiverList rl) {
18869         mRegisteredReceivers.remove(rl.receiver.asBinder());
18870         for (int i = rl.size() - 1; i >= 0; i--) {
18871             mReceiverResolver.removeFilter(rl.get(i));
18872         }
18873     }
18874
18875     private final void sendPackageBroadcastLocked(int cmd, String[] packages, int userId) {
18876         for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) {
18877             ProcessRecord r = mLruProcesses.get(i);
18878             if (r.thread != null && (userId == UserHandle.USER_ALL || r.userId == userId)) {
18879                 try {
18880                     r.thread.dispatchPackageBroadcast(cmd, packages);
18881                 } catch (RemoteException ex) {
18882                 }
18883             }
18884         }
18885     }
18886
18887     private List<ResolveInfo> collectReceiverComponents(Intent intent, String resolvedType,
18888             int callingUid, int[] users) {
18889         // TODO: come back and remove this assumption to triage all broadcasts
18890         int pmFlags = STOCK_PM_FLAGS | MATCH_DEBUG_TRIAGED_MISSING;
18891
18892         List<ResolveInfo> receivers = null;
18893         try {
18894             HashSet<ComponentName> singleUserReceivers = null;
18895             boolean scannedFirstReceivers = false;
18896             for (int user : users) {
18897                 // Skip users that have Shell restrictions, with exception of always permitted
18898                 // Shell broadcasts
18899                 if (callingUid == SHELL_UID
18900                         && mUserController.hasUserRestriction(
18901                                 UserManager.DISALLOW_DEBUGGING_FEATURES, user)
18902                         && !isPermittedShellBroadcast(intent)) {
18903                     continue;
18904                 }
18905                 List<ResolveInfo> newReceivers = AppGlobals.getPackageManager()
18906                         .queryIntentReceivers(intent, resolvedType, pmFlags, user).getList();
18907                 if (user != UserHandle.USER_SYSTEM && newReceivers != null) {
18908                     // If this is not the system user, we need to check for
18909                     // any receivers that should be filtered out.
18910                     for (int i=0; i<newReceivers.size(); i++) {
18911                         ResolveInfo ri = newReceivers.get(i);
18912                         if ((ri.activityInfo.flags&ActivityInfo.FLAG_SYSTEM_USER_ONLY) != 0) {
18913                             newReceivers.remove(i);
18914                             i--;
18915                         }
18916                     }
18917                 }
18918                 if (newReceivers != null && newReceivers.size() == 0) {
18919                     newReceivers = null;
18920                 }
18921                 if (receivers == null) {
18922                     receivers = newReceivers;
18923                 } else if (newReceivers != null) {
18924                     // We need to concatenate the additional receivers
18925                     // found with what we have do far.  This would be easy,
18926                     // but we also need to de-dup any receivers that are
18927                     // singleUser.
18928                     if (!scannedFirstReceivers) {
18929                         // Collect any single user receivers we had already retrieved.
18930                         scannedFirstReceivers = true;
18931                         for (int i=0; i<receivers.size(); i++) {
18932                             ResolveInfo ri = receivers.get(i);
18933                             if ((ri.activityInfo.flags&ActivityInfo.FLAG_SINGLE_USER) != 0) {
18934                                 ComponentName cn = new ComponentName(
18935                                         ri.activityInfo.packageName, ri.activityInfo.name);
18936                                 if (singleUserReceivers == null) {
18937                                     singleUserReceivers = new HashSet<ComponentName>();
18938                                 }
18939                                 singleUserReceivers.add(cn);
18940                             }
18941                         }
18942                     }
18943                     // Add the new results to the existing results, tracking
18944                     // and de-dupping single user receivers.
18945                     for (int i=0; i<newReceivers.size(); i++) {
18946                         ResolveInfo ri = newReceivers.get(i);
18947                         if ((ri.activityInfo.flags&ActivityInfo.FLAG_SINGLE_USER) != 0) {
18948                             ComponentName cn = new ComponentName(
18949                                     ri.activityInfo.packageName, ri.activityInfo.name);
18950                             if (singleUserReceivers == null) {
18951                                 singleUserReceivers = new HashSet<ComponentName>();
18952                             }
18953                             if (!singleUserReceivers.contains(cn)) {
18954                                 singleUserReceivers.add(cn);
18955                                 receivers.add(ri);
18956                             }
18957                         } else {
18958                             receivers.add(ri);
18959                         }
18960                     }
18961                 }
18962             }
18963         } catch (RemoteException ex) {
18964             // pm is in same process, this will never happen.
18965         }
18966         return receivers;
18967     }
18968
18969     private boolean isPermittedShellBroadcast(Intent intent) {
18970         // remote bugreport should always be allowed to be taken
18971         return INTENT_REMOTE_BUGREPORT_FINISHED.equals(intent.getAction());
18972     }
18973
18974     private void checkBroadcastFromSystem(Intent intent, ProcessRecord callerApp,
18975             String callerPackage, int callingUid, boolean isProtectedBroadcast, List receivers) {
18976         if ((intent.getFlags() & Intent.FLAG_RECEIVER_FROM_SHELL) != 0) {
18977             // Don't yell about broadcasts sent via shell
18978             return;
18979         }
18980
18981         final String action = intent.getAction();
18982         if (isProtectedBroadcast
18983                 || Intent.ACTION_CLOSE_SYSTEM_DIALOGS.equals(action)
18984                 || Intent.ACTION_DISMISS_KEYBOARD_SHORTCUTS.equals(action)
18985                 || Intent.ACTION_MEDIA_BUTTON.equals(action)
18986                 || Intent.ACTION_MEDIA_SCANNER_SCAN_FILE.equals(action)
18987                 || Intent.ACTION_SHOW_KEYBOARD_SHORTCUTS.equals(action)
18988                 || Intent.ACTION_MASTER_CLEAR.equals(action)
18989                 || Intent.ACTION_FACTORY_RESET.equals(action)
18990                 || AppWidgetManager.ACTION_APPWIDGET_CONFIGURE.equals(action)
18991                 || AppWidgetManager.ACTION_APPWIDGET_UPDATE.equals(action)
18992                 || LocationManager.HIGH_POWER_REQUEST_CHANGE_ACTION.equals(action)
18993                 || TelephonyIntents.ACTION_REQUEST_OMADM_CONFIGURATION_UPDATE.equals(action)
18994                 || SuggestionSpan.ACTION_SUGGESTION_PICKED.equals(action)
18995                 || AudioEffect.ACTION_OPEN_AUDIO_EFFECT_CONTROL_SESSION.equals(action)
18996                 || AudioEffect.ACTION_CLOSE_AUDIO_EFFECT_CONTROL_SESSION.equals(action)) {
18997             // Broadcast is either protected, or it's a public action that
18998             // we've relaxed, so it's fine for system internals to send.
18999             return;
19000         }
19001
19002         // This broadcast may be a problem...  but there are often system components that
19003         // want to send an internal broadcast to themselves, which is annoying to have to
19004         // explicitly list each action as a protected broadcast, so we will check for that
19005         // one safe case and allow it: an explicit broadcast, only being received by something
19006         // that has protected itself.
19007         if (receivers != null && receivers.size() > 0
19008                 && (intent.getPackage() != null || intent.getComponent() != null)) {
19009             boolean allProtected = true;
19010             for (int i = receivers.size()-1; i >= 0; i--) {
19011                 Object target = receivers.get(i);
19012                 if (target instanceof ResolveInfo) {
19013                     ResolveInfo ri = (ResolveInfo)target;
19014                     if (ri.activityInfo.exported && ri.activityInfo.permission == null) {
19015                         allProtected = false;
19016                         break;
19017                     }
19018                 } else {
19019                     BroadcastFilter bf = (BroadcastFilter)target;
19020                     if (bf.requiredPermission == null) {
19021                         allProtected = false;
19022                         break;
19023                     }
19024                 }
19025             }
19026             if (allProtected) {
19027                 // All safe!
19028                 return;
19029             }
19030         }
19031
19032         // The vast majority of broadcasts sent from system internals
19033         // should be protected to avoid security holes, so yell loudly
19034         // to ensure we examine these cases.
19035         if (callerApp != null) {
19036             Log.wtf(TAG, "Sending non-protected broadcast " + action
19037                             + " from system " + callerApp.toShortString() + " pkg " + callerPackage,
19038                     new Throwable());
19039         } else {
19040             Log.wtf(TAG, "Sending non-protected broadcast " + action
19041                             + " from system uid " + UserHandle.formatUid(callingUid)
19042                             + " pkg " + callerPackage,
19043                     new Throwable());
19044         }
19045     }
19046
19047     final int broadcastIntentLocked(ProcessRecord callerApp,
19048             String callerPackage, Intent intent, String resolvedType,
19049             IIntentReceiver resultTo, int resultCode, String resultData,
19050             Bundle resultExtras, String[] requiredPermissions, int appOp, Bundle bOptions,
19051             boolean ordered, boolean sticky, int callingPid, int callingUid, int userId) {
19052         intent = new Intent(intent);
19053
19054         final boolean callerInstantApp = isInstantApp(callerApp, callerPackage, callingUid);
19055         // Instant Apps cannot use FLAG_RECEIVER_VISIBLE_TO_INSTANT_APPS
19056         if (callerInstantApp) {
19057             intent.setFlags(intent.getFlags() & ~Intent.FLAG_RECEIVER_VISIBLE_TO_INSTANT_APPS);
19058         }
19059
19060         // By default broadcasts do not go to stopped apps.
19061         intent.addFlags(Intent.FLAG_EXCLUDE_STOPPED_PACKAGES);
19062
19063         // If we have not finished booting, don't allow this to launch new processes.
19064         if (!mProcessesReady && (intent.getFlags()&Intent.FLAG_RECEIVER_BOOT_UPGRADE) == 0) {
19065             intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY);
19066         }
19067
19068         if (DEBUG_BROADCAST_LIGHT) Slog.v(TAG_BROADCAST,
19069                 (sticky ? "Broadcast sticky: ": "Broadcast: ") + intent
19070                 + " ordered=" + ordered + " userid=" + userId);
19071         if ((resultTo != null) && !ordered) {
19072             Slog.w(TAG, "Broadcast " + intent + " not ordered but result callback requested!");
19073         }
19074
19075         userId = mUserController.handleIncomingUser(callingPid, callingUid, userId, true,
19076                 ALLOW_NON_FULL, "broadcast", callerPackage);
19077
19078         // Make sure that the user who is receiving this broadcast is running.
19079         // If not, we will just skip it. Make an exception for shutdown broadcasts
19080         // and upgrade steps.
19081
19082         if (userId != UserHandle.USER_ALL && !mUserController.isUserRunningLocked(userId, 0)) {
19083             if ((callingUid != SYSTEM_UID
19084                     || (intent.getFlags() & Intent.FLAG_RECEIVER_BOOT_UPGRADE) == 0)
19085                     && !Intent.ACTION_SHUTDOWN.equals(intent.getAction())) {
19086                 Slog.w(TAG, "Skipping broadcast of " + intent
19087                         + ": user " + userId + " is stopped");
19088                 return ActivityManager.BROADCAST_FAILED_USER_STOPPED;
19089             }
19090         }
19091
19092         BroadcastOptions brOptions = null;
19093         if (bOptions != null) {
19094             brOptions = new BroadcastOptions(bOptions);
19095             if (brOptions.getTemporaryAppWhitelistDuration() > 0) {
19096                 // See if the caller is allowed to do this.  Note we are checking against
19097                 // the actual real caller (not whoever provided the operation as say a
19098                 // PendingIntent), because that who is actually supplied the arguments.
19099                 if (checkComponentPermission(
19100                         android.Manifest.permission.CHANGE_DEVICE_IDLE_TEMP_WHITELIST,
19101                         Binder.getCallingPid(), Binder.getCallingUid(), -1, true)
19102                         != PackageManager.PERMISSION_GRANTED) {
19103                     String msg = "Permission Denial: " + intent.getAction()
19104                             + " broadcast from " + callerPackage + " (pid=" + callingPid
19105                             + ", uid=" + callingUid + ")"
19106                             + " requires "
19107                             + android.Manifest.permission.CHANGE_DEVICE_IDLE_TEMP_WHITELIST;
19108                     Slog.w(TAG, msg);
19109                     throw new SecurityException(msg);
19110                 }
19111             }
19112         }
19113
19114         // Verify that protected broadcasts are only being sent by system code,
19115         // and that system code is only sending protected broadcasts.
19116         final String action = intent.getAction();
19117         final boolean isProtectedBroadcast;
19118         try {
19119             isProtectedBroadcast = AppGlobals.getPackageManager().isProtectedBroadcast(action);
19120         } catch (RemoteException e) {
19121             Slog.w(TAG, "Remote exception", e);
19122             return ActivityManager.BROADCAST_SUCCESS;
19123         }
19124
19125         final boolean isCallerSystem;
19126         switch (UserHandle.getAppId(callingUid)) {
19127             case ROOT_UID:
19128             case SYSTEM_UID:
19129             case PHONE_UID:
19130             case BLUETOOTH_UID:
19131             case NFC_UID:
19132                 isCallerSystem = true;
19133                 break;
19134             default:
19135                 isCallerSystem = (callerApp != null) && callerApp.persistent;
19136                 break;
19137         }
19138
19139         // First line security check before anything else: stop non-system apps from
19140         // sending protected broadcasts.
19141         if (!isCallerSystem) {
19142             if (isProtectedBroadcast) {
19143                 String msg = "Permission Denial: not allowed to send broadcast "
19144                         + action + " from pid="
19145                         + callingPid + ", uid=" + callingUid;
19146                 Slog.w(TAG, msg);
19147                 throw new SecurityException(msg);
19148
19149             } else if (AppWidgetManager.ACTION_APPWIDGET_CONFIGURE.equals(action)
19150                     || AppWidgetManager.ACTION_APPWIDGET_UPDATE.equals(action)) {
19151                 // Special case for compatibility: we don't want apps to send this,
19152                 // but historically it has not been protected and apps may be using it
19153                 // to poke their own app widget.  So, instead of making it protected,
19154                 // just limit it to the caller.
19155                 if (callerPackage == null) {
19156                     String msg = "Permission Denial: not allowed to send broadcast "
19157                             + action + " from unknown caller.";
19158                     Slog.w(TAG, msg);
19159                     throw new SecurityException(msg);
19160                 } else if (intent.getComponent() != null) {
19161                     // They are good enough to send to an explicit component...  verify
19162                     // it is being sent to the calling app.
19163                     if (!intent.getComponent().getPackageName().equals(
19164                             callerPackage)) {
19165                         String msg = "Permission Denial: not allowed to send broadcast "
19166                                 + action + " to "
19167                                 + intent.getComponent().getPackageName() + " from "
19168                                 + callerPackage;
19169                         Slog.w(TAG, msg);
19170                         throw new SecurityException(msg);
19171                     }
19172                 } else {
19173                     // Limit broadcast to their own package.
19174                     intent.setPackage(callerPackage);
19175                 }
19176             }
19177         }
19178
19179         if (action != null) {
19180             if (getBackgroundLaunchBroadcasts().contains(action)) {
19181                 if (DEBUG_BACKGROUND_CHECK) {
19182                     Slog.i(TAG, "Broadcast action " + action + " forcing include-background");
19183                 }
19184                 intent.addFlags(Intent.FLAG_RECEIVER_INCLUDE_BACKGROUND);
19185             }
19186
19187             switch (action) {
19188                 case Intent.ACTION_UID_REMOVED:
19189                 case Intent.ACTION_PACKAGE_REMOVED:
19190                 case Intent.ACTION_PACKAGE_CHANGED:
19191                 case Intent.ACTION_EXTERNAL_APPLICATIONS_UNAVAILABLE:
19192                 case Intent.ACTION_EXTERNAL_APPLICATIONS_AVAILABLE:
19193                 case Intent.ACTION_PACKAGES_SUSPENDED:
19194                 case Intent.ACTION_PACKAGES_UNSUSPENDED:
19195                     // Handle special intents: if this broadcast is from the package
19196                     // manager about a package being removed, we need to remove all of
19197                     // its activities from the history stack.
19198                     if (checkComponentPermission(
19199                             android.Manifest.permission.BROADCAST_PACKAGE_REMOVED,
19200                             callingPid, callingUid, -1, true)
19201                             != PackageManager.PERMISSION_GRANTED) {
19202                         String msg = "Permission Denial: " + intent.getAction()
19203                                 + " broadcast from " + callerPackage + " (pid=" + callingPid
19204                                 + ", uid=" + callingUid + ")"
19205                                 + " requires "
19206                                 + android.Manifest.permission.BROADCAST_PACKAGE_REMOVED;
19207                         Slog.w(TAG, msg);
19208                         throw new SecurityException(msg);
19209                     }
19210                     switch (action) {
19211                         case Intent.ACTION_UID_REMOVED:
19212                             final int uid = getUidFromIntent(intent);
19213                             if (uid >= 0) {
19214                                 mBatteryStatsService.removeUid(uid);
19215                                 mAppOpsService.uidRemoved(uid);
19216                             }
19217                             break;
19218                         case Intent.ACTION_EXTERNAL_APPLICATIONS_UNAVAILABLE:
19219                             // If resources are unavailable just force stop all those packages
19220                             // and flush the attribute cache as well.
19221                             String list[] =
19222                                     intent.getStringArrayExtra(Intent.EXTRA_CHANGED_PACKAGE_LIST);
19223                             if (list != null && list.length > 0) {
19224                                 for (int i = 0; i < list.length; i++) {
19225                                     forceStopPackageLocked(list[i], -1, false, true, true,
19226                                             false, false, userId, "storage unmount");
19227                                 }
19228                                 mRecentTasks.cleanupLocked(UserHandle.USER_ALL);
19229                                 sendPackageBroadcastLocked(
19230                                         ApplicationThreadConstants.EXTERNAL_STORAGE_UNAVAILABLE,
19231                                         list, userId);
19232                             }
19233                             break;
19234                         case Intent.ACTION_EXTERNAL_APPLICATIONS_AVAILABLE:
19235                             mRecentTasks.cleanupLocked(UserHandle.USER_ALL);
19236                             break;
19237                         case Intent.ACTION_PACKAGE_REMOVED:
19238                         case Intent.ACTION_PACKAGE_CHANGED:
19239                             Uri data = intent.getData();
19240                             String ssp;
19241                             if (data != null && (ssp=data.getSchemeSpecificPart()) != null) {
19242                                 boolean removed = Intent.ACTION_PACKAGE_REMOVED.equals(action);
19243                                 final boolean replacing =
19244                                         intent.getBooleanExtra(Intent.EXTRA_REPLACING, false);
19245                                 final boolean killProcess =
19246                                         !intent.getBooleanExtra(Intent.EXTRA_DONT_KILL_APP, false);
19247                                 final boolean fullUninstall = removed && !replacing;
19248                                 if (removed) {
19249                                     if (killProcess) {
19250                                         forceStopPackageLocked(ssp, UserHandle.getAppId(
19251                                                 intent.getIntExtra(Intent.EXTRA_UID, -1)),
19252                                                 false, true, true, false, fullUninstall, userId,
19253                                                 removed ? "pkg removed" : "pkg changed");
19254                                     }
19255                                     final int cmd = killProcess
19256                                             ? ApplicationThreadConstants.PACKAGE_REMOVED
19257                                             : ApplicationThreadConstants.PACKAGE_REMOVED_DONT_KILL;
19258                                     sendPackageBroadcastLocked(cmd,
19259                                             new String[] {ssp}, userId);
19260                                     if (fullUninstall) {
19261                                         mAppOpsService.packageRemoved(
19262                                                 intent.getIntExtra(Intent.EXTRA_UID, -1), ssp);
19263
19264                                         // Remove all permissions granted from/to this package
19265                                         removeUriPermissionsForPackageLocked(ssp, userId, true);
19266
19267                                         removeTasksByPackageNameLocked(ssp, userId);
19268
19269                                         mServices.forceStopPackageLocked(ssp, userId);
19270
19271                                         // Hide the "unsupported display" dialog if necessary.
19272                                         if (mUnsupportedDisplaySizeDialog != null && ssp.equals(
19273                                                 mUnsupportedDisplaySizeDialog.getPackageName())) {
19274                                             mUnsupportedDisplaySizeDialog.dismiss();
19275                                             mUnsupportedDisplaySizeDialog = null;
19276                                         }
19277                                         mCompatModePackages.handlePackageUninstalledLocked(ssp);
19278                                         mBatteryStatsService.notePackageUninstalled(ssp);
19279                                     }
19280                                 } else {
19281                                     if (killProcess) {
19282                                         killPackageProcessesLocked(ssp, UserHandle.getAppId(
19283                                                 intent.getIntExtra(Intent.EXTRA_UID, -1)),
19284                                                 userId, ProcessList.INVALID_ADJ,
19285                                                 false, true, true, false, "change " + ssp);
19286                                     }
19287                                     cleanupDisabledPackageComponentsLocked(ssp, userId, killProcess,
19288                                             intent.getStringArrayExtra(
19289                                                     Intent.EXTRA_CHANGED_COMPONENT_NAME_LIST));
19290                                 }
19291                             }
19292                             break;
19293                         case Intent.ACTION_PACKAGES_SUSPENDED:
19294                         case Intent.ACTION_PACKAGES_UNSUSPENDED:
19295                             final boolean suspended = Intent.ACTION_PACKAGES_SUSPENDED.equals(
19296                                     intent.getAction());
19297                             final String[] packageNames = intent.getStringArrayExtra(
19298                                     Intent.EXTRA_CHANGED_PACKAGE_LIST);
19299                             final int userHandle = intent.getIntExtra(
19300                                     Intent.EXTRA_USER_HANDLE, UserHandle.USER_NULL);
19301
19302                             synchronized(ActivityManagerService.this) {
19303                                 mRecentTasks.onPackagesSuspendedChanged(
19304                                         packageNames, suspended, userHandle);
19305                             }
19306                             break;
19307                     }
19308                     break;
19309                 case Intent.ACTION_PACKAGE_REPLACED:
19310                 {
19311                     final Uri data = intent.getData();
19312                     final String ssp;
19313                     if (data != null && (ssp = data.getSchemeSpecificPart()) != null) {
19314                         ApplicationInfo aInfo = null;
19315                         try {
19316                             aInfo = AppGlobals.getPackageManager()
19317                                     .getApplicationInfo(ssp, 0 /*flags*/, userId);
19318                         } catch (RemoteException ignore) {}
19319                         if (aInfo == null) {
19320                             Slog.w(TAG, "Dropping ACTION_PACKAGE_REPLACED for non-existent pkg:"
19321                                     + " ssp=" + ssp + " data=" + data);
19322                             return ActivityManager.BROADCAST_SUCCESS;
19323                         }
19324                         mStackSupervisor.updateActivityApplicationInfoLocked(aInfo);
19325                         sendPackageBroadcastLocked(ApplicationThreadConstants.PACKAGE_REPLACED,
19326                                 new String[] {ssp}, userId);
19327                     }
19328                     break;
19329                 }
19330                 case Intent.ACTION_PACKAGE_ADDED:
19331                 {
19332                     // Special case for adding a package: by default turn on compatibility mode.
19333                     Uri data = intent.getData();
19334                     String ssp;
19335                     if (data != null && (ssp = data.getSchemeSpecificPart()) != null) {
19336                         final boolean replacing =
19337                                 intent.getBooleanExtra(Intent.EXTRA_REPLACING, false);
19338                         mCompatModePackages.handlePackageAddedLocked(ssp, replacing);
19339
19340                         try {
19341                             ApplicationInfo ai = AppGlobals.getPackageManager().
19342                                     getApplicationInfo(ssp, 0, 0);
19343                             mBatteryStatsService.notePackageInstalled(ssp,
19344                                     ai != null ? ai.versionCode : 0);
19345                         } catch (RemoteException e) {
19346                         }
19347                     }
19348                     break;
19349                 }
19350                 case Intent.ACTION_PACKAGE_DATA_CLEARED:
19351                 {
19352                     Uri data = intent.getData();
19353                     String ssp;
19354                     if (data != null && (ssp = data.getSchemeSpecificPart()) != null) {
19355                         // Hide the "unsupported display" dialog if necessary.
19356                         if (mUnsupportedDisplaySizeDialog != null && ssp.equals(
19357                                 mUnsupportedDisplaySizeDialog.getPackageName())) {
19358                             mUnsupportedDisplaySizeDialog.dismiss();
19359                             mUnsupportedDisplaySizeDialog = null;
19360                         }
19361                         mCompatModePackages.handlePackageDataClearedLocked(ssp);
19362                     }
19363                     break;
19364                 }
19365                 case Intent.ACTION_TIMEZONE_CHANGED:
19366                     // If this is the time zone changed action, queue up a message that will reset
19367                     // the timezone of all currently running processes. This message will get
19368                     // queued up before the broadcast happens.
19369                     mHandler.sendEmptyMessage(UPDATE_TIME_ZONE);
19370                     break;
19371                 case Intent.ACTION_TIME_CHANGED:
19372                     // EXTRA_TIME_PREF_24_HOUR_FORMAT is optional so we must distinguish between
19373                     // the tri-state value it may contain and "unknown".
19374                     // For convenience we re-use the Intent extra values.
19375                     final int NO_EXTRA_VALUE_FOUND = -1;
19376                     final int timeFormatPreferenceMsgValue = intent.getIntExtra(
19377                             Intent.EXTRA_TIME_PREF_24_HOUR_FORMAT,
19378                             NO_EXTRA_VALUE_FOUND /* defaultValue */);
19379                     // Only send a message if the time preference is available.
19380                     if (timeFormatPreferenceMsgValue != NO_EXTRA_VALUE_FOUND) {
19381                         Message updateTimePreferenceMsg =
19382                                 mHandler.obtainMessage(UPDATE_TIME_PREFERENCE_MSG,
19383                                         timeFormatPreferenceMsgValue, 0);
19384                         mHandler.sendMessage(updateTimePreferenceMsg);
19385                     }
19386                     BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
19387                     synchronized (stats) {
19388                         stats.noteCurrentTimeChangedLocked();
19389                     }
19390                     break;
19391                 case Intent.ACTION_CLEAR_DNS_CACHE:
19392                     mHandler.sendEmptyMessage(CLEAR_DNS_CACHE_MSG);
19393                     break;
19394                 case Proxy.PROXY_CHANGE_ACTION:
19395                     ProxyInfo proxy = intent.getParcelableExtra(Proxy.EXTRA_PROXY_INFO);
19396                     mHandler.sendMessage(mHandler.obtainMessage(UPDATE_HTTP_PROXY_MSG, proxy));
19397                     break;
19398                 case android.hardware.Camera.ACTION_NEW_PICTURE:
19399                 case android.hardware.Camera.ACTION_NEW_VIDEO:
19400                     // In N we just turned these off; in O we are turing them back on partly,
19401                     // only for registered receivers.  This will still address the main problem
19402                     // (a spam of apps waking up when a picture is taken putting significant
19403                     // memory pressure on the system at a bad point), while still allowing apps
19404                     // that are already actively running to know about this happening.
19405                     intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY);
19406                     break;
19407                 case android.security.KeyChain.ACTION_TRUST_STORE_CHANGED:
19408                     mHandler.sendEmptyMessage(HANDLE_TRUST_STORAGE_UPDATE_MSG);
19409                     break;
19410                 case "com.android.launcher.action.INSTALL_SHORTCUT":
19411                     // As of O, we no longer support this broadcasts, even for pre-O apps.
19412                     // Apps should now be using ShortcutManager.pinRequestShortcut().
19413                     Log.w(TAG, "Broadcast " + action
19414                             + " no longer supported. It will not be delivered.");
19415                     return ActivityManager.BROADCAST_SUCCESS;
19416             }
19417
19418             if (Intent.ACTION_PACKAGE_ADDED.equals(action) ||
19419                     Intent.ACTION_PACKAGE_REMOVED.equals(action) ||
19420                     Intent.ACTION_PACKAGE_REPLACED.equals(action)) {
19421                 final int uid = getUidFromIntent(intent);
19422                 if (uid != -1) {
19423                     final UidRecord uidRec = mActiveUids.get(uid);
19424                     if (uidRec != null) {
19425                         uidRec.updateHasInternetPermission();
19426                     }
19427                 }
19428             }
19429         }
19430
19431         // Add to the sticky list if requested.
19432         if (sticky) {
19433             if (checkPermission(android.Manifest.permission.BROADCAST_STICKY,
19434                     callingPid, callingUid)
19435                     != PackageManager.PERMISSION_GRANTED) {
19436                 String msg = "Permission Denial: broadcastIntent() requesting a sticky broadcast from pid="
19437                         + callingPid + ", uid=" + callingUid
19438                         + " requires " + android.Manifest.permission.BROADCAST_STICKY;
19439                 Slog.w(TAG, msg);
19440                 throw new SecurityException(msg);
19441             }
19442             if (requiredPermissions != null && requiredPermissions.length > 0) {
19443                 Slog.w(TAG, "Can't broadcast sticky intent " + intent
19444                         + " and enforce permissions " + Arrays.toString(requiredPermissions));
19445                 return ActivityManager.BROADCAST_STICKY_CANT_HAVE_PERMISSION;
19446             }
19447             if (intent.getComponent() != null) {
19448                 throw new SecurityException(
19449                         "Sticky broadcasts can't target a specific component");
19450             }
19451             // We use userId directly here, since the "all" target is maintained
19452             // as a separate set of sticky broadcasts.
19453             if (userId != UserHandle.USER_ALL) {
19454                 // But first, if this is not a broadcast to all users, then
19455                 // make sure it doesn't conflict with an existing broadcast to
19456                 // all users.
19457                 ArrayMap<String, ArrayList<Intent>> stickies = mStickyBroadcasts.get(
19458                         UserHandle.USER_ALL);
19459                 if (stickies != null) {
19460                     ArrayList<Intent> list = stickies.get(intent.getAction());
19461                     if (list != null) {
19462                         int N = list.size();
19463                         int i;
19464                         for (i=0; i<N; i++) {
19465                             if (intent.filterEquals(list.get(i))) {
19466                                 throw new IllegalArgumentException(
19467                                         "Sticky broadcast " + intent + " for user "
19468                                         + userId + " conflicts with existing global broadcast");
19469                             }
19470                         }
19471                     }
19472                 }
19473             }
19474             ArrayMap<String, ArrayList<Intent>> stickies = mStickyBroadcasts.get(userId);
19475             if (stickies == null) {
19476                 stickies = new ArrayMap<>();
19477                 mStickyBroadcasts.put(userId, stickies);
19478             }
19479             ArrayList<Intent> list = stickies.get(intent.getAction());
19480             if (list == null) {
19481                 list = new ArrayList<>();
19482                 stickies.put(intent.getAction(), list);
19483             }
19484             final int stickiesCount = list.size();
19485             int i;
19486             for (i = 0; i < stickiesCount; i++) {
19487                 if (intent.filterEquals(list.get(i))) {
19488                     // This sticky already exists, replace it.
19489                     list.set(i, new Intent(intent));
19490                     break;
19491                 }
19492             }
19493             if (i >= stickiesCount) {
19494                 list.add(new Intent(intent));
19495             }
19496         }
19497
19498         int[] users;
19499         if (userId == UserHandle.USER_ALL) {
19500             // Caller wants broadcast to go to all started users.
19501             users = mUserController.getStartedUserArrayLocked();
19502         } else {
19503             // Caller wants broadcast to go to one specific user.
19504             users = new int[] {userId};
19505         }
19506
19507         // Figure out who all will receive this broadcast.
19508         List receivers = null;
19509         List<BroadcastFilter> registeredReceivers = null;
19510         // Need to resolve the intent to interested receivers...
19511         if ((intent.getFlags()&Intent.FLAG_RECEIVER_REGISTERED_ONLY)
19512                  == 0) {
19513             receivers = collectReceiverComponents(intent, resolvedType, callingUid, users);
19514         }
19515         if (intent.getComponent() == null) {
19516             if (userId == UserHandle.USER_ALL && callingUid == SHELL_UID) {
19517                 // Query one target user at a time, excluding shell-restricted users
19518                 for (int i = 0; i < users.length; i++) {
19519                     if (mUserController.hasUserRestriction(
19520                             UserManager.DISALLOW_DEBUGGING_FEATURES, users[i])) {
19521                         continue;
19522                     }
19523                     List<BroadcastFilter> registeredReceiversForUser =
19524                             mReceiverResolver.queryIntent(intent,
19525                                     resolvedType, false /*defaultOnly*/, users[i]);
19526                     if (registeredReceivers == null) {
19527                         registeredReceivers = registeredReceiversForUser;
19528                     } else if (registeredReceiversForUser != null) {
19529                         registeredReceivers.addAll(registeredReceiversForUser);
19530                     }
19531                 }
19532             } else {
19533                 registeredReceivers = mReceiverResolver.queryIntent(intent,
19534                         resolvedType, false /*defaultOnly*/, userId);
19535             }
19536         }
19537
19538         final boolean replacePending =
19539                 (intent.getFlags()&Intent.FLAG_RECEIVER_REPLACE_PENDING) != 0;
19540
19541         if (DEBUG_BROADCAST) Slog.v(TAG_BROADCAST, "Enqueueing broadcast: " + intent.getAction()
19542                 + " replacePending=" + replacePending);
19543
19544         int NR = registeredReceivers != null ? registeredReceivers.size() : 0;
19545         if (!ordered && NR > 0) {
19546             // If we are not serializing this broadcast, then send the
19547             // registered receivers separately so they don't wait for the
19548             // components to be launched.
19549             if (isCallerSystem) {
19550                 checkBroadcastFromSystem(intent, callerApp, callerPackage, callingUid,
19551                         isProtectedBroadcast, registeredReceivers);
19552             }
19553             final BroadcastQueue queue = broadcastQueueForIntent(intent);
19554             BroadcastRecord r = new BroadcastRecord(queue, intent, callerApp,
19555                     callerPackage, callingPid, callingUid, callerInstantApp, resolvedType,
19556                     requiredPermissions, appOp, brOptions, registeredReceivers, resultTo,
19557                     resultCode, resultData, resultExtras, ordered, sticky, false, userId);
19558             if (DEBUG_BROADCAST) Slog.v(TAG_BROADCAST, "Enqueueing parallel broadcast " + r);
19559             final boolean replaced = replacePending
19560                     && (queue.replaceParallelBroadcastLocked(r) != null);
19561             // Note: We assume resultTo is null for non-ordered broadcasts.
19562             if (!replaced) {
19563                 queue.enqueueParallelBroadcastLocked(r);
19564                 queue.scheduleBroadcastsLocked();
19565             }
19566             registeredReceivers = null;
19567             NR = 0;
19568         }
19569
19570         // Merge into one list.
19571         int ir = 0;
19572         if (receivers != null) {
19573             // A special case for PACKAGE_ADDED: do not allow the package
19574             // being added to see this broadcast.  This prevents them from
19575             // using this as a back door to get run as soon as they are
19576             // installed.  Maybe in the future we want to have a special install
19577             // broadcast or such for apps, but we'd like to deliberately make
19578             // this decision.
19579             String skipPackages[] = null;
19580             if (Intent.ACTION_PACKAGE_ADDED.equals(intent.getAction())
19581                     || Intent.ACTION_PACKAGE_RESTARTED.equals(intent.getAction())
19582                     || Intent.ACTION_PACKAGE_DATA_CLEARED.equals(intent.getAction())) {
19583                 Uri data = intent.getData();
19584                 if (data != null) {
19585                     String pkgName = data.getSchemeSpecificPart();
19586                     if (pkgName != null) {
19587                         skipPackages = new String[] { pkgName };
19588                     }
19589                 }
19590             } else if (Intent.ACTION_EXTERNAL_APPLICATIONS_AVAILABLE.equals(intent.getAction())) {
19591                 skipPackages = intent.getStringArrayExtra(Intent.EXTRA_CHANGED_PACKAGE_LIST);
19592             }
19593             if (skipPackages != null && (skipPackages.length > 0)) {
19594                 for (String skipPackage : skipPackages) {
19595                     if (skipPackage != null) {
19596                         int NT = receivers.size();
19597                         for (int it=0; it<NT; it++) {
19598                             ResolveInfo curt = (ResolveInfo)receivers.get(it);
19599                             if (curt.activityInfo.packageName.equals(skipPackage)) {
19600                                 receivers.remove(it);
19601                                 it--;
19602                                 NT--;
19603                             }
19604                         }
19605                     }
19606                 }
19607             }
19608
19609             int NT = receivers != null ? receivers.size() : 0;
19610             int it = 0;
19611             ResolveInfo curt = null;
19612             BroadcastFilter curr = null;
19613             while (it < NT && ir < NR) {
19614                 if (curt == null) {
19615                     curt = (ResolveInfo)receivers.get(it);
19616                 }
19617                 if (curr == null) {
19618                     curr = registeredReceivers.get(ir);
19619                 }
19620                 if (curr.getPriority() >= curt.priority) {
19621                     // Insert this broadcast record into the final list.
19622                     receivers.add(it, curr);
19623                     ir++;
19624                     curr = null;
19625                     it++;
19626                     NT++;
19627                 } else {
19628                     // Skip to the next ResolveInfo in the final list.
19629                     it++;
19630                     curt = null;
19631                 }
19632             }
19633         }
19634         while (ir < NR) {
19635             if (receivers == null) {
19636                 receivers = new ArrayList();
19637             }
19638             receivers.add(registeredReceivers.get(ir));
19639             ir++;
19640         }
19641
19642         if (isCallerSystem) {
19643             checkBroadcastFromSystem(intent, callerApp, callerPackage, callingUid,
19644                     isProtectedBroadcast, receivers);
19645         }
19646
19647         if ((receivers != null && receivers.size() > 0)
19648                 || resultTo != null) {
19649             BroadcastQueue queue = broadcastQueueForIntent(intent);
19650             BroadcastRecord r = new BroadcastRecord(queue, intent, callerApp,
19651                     callerPackage, callingPid, callingUid, callerInstantApp, resolvedType,
19652                     requiredPermissions, appOp, brOptions, receivers, resultTo, resultCode,
19653                     resultData, resultExtras, ordered, sticky, false, userId);
19654
19655             if (DEBUG_BROADCAST) Slog.v(TAG_BROADCAST, "Enqueueing ordered broadcast " + r
19656                     + ": prev had " + queue.mOrderedBroadcasts.size());
19657             if (DEBUG_BROADCAST) Slog.i(TAG_BROADCAST,
19658                     "Enqueueing broadcast " + r.intent.getAction());
19659
19660             final BroadcastRecord oldRecord =
19661                     replacePending ? queue.replaceOrderedBroadcastLocked(r) : null;
19662             if (oldRecord != null) {
19663                 // Replaced, fire the result-to receiver.
19664                 if (oldRecord.resultTo != null) {
19665                     final BroadcastQueue oldQueue = broadcastQueueForIntent(oldRecord.intent);
19666                     try {
19667                         oldQueue.performReceiveLocked(oldRecord.callerApp, oldRecord.resultTo,
19668                                 oldRecord.intent,
19669                                 Activity.RESULT_CANCELED, null, null,
19670                                 false, false, oldRecord.userId);
19671                     } catch (RemoteException e) {
19672                         Slog.w(TAG, "Failure ["
19673                                 + queue.mQueueName + "] sending broadcast result of "
19674                                 + intent, e);
19675
19676                     }
19677                 }
19678             } else {
19679                 queue.enqueueOrderedBroadcastLocked(r);
19680                 queue.scheduleBroadcastsLocked();
19681             }
19682         } else {
19683             // There was nobody interested in the broadcast, but we still want to record
19684             // that it happened.
19685             if (intent.getComponent() == null && intent.getPackage() == null
19686                     && (intent.getFlags()&Intent.FLAG_RECEIVER_REGISTERED_ONLY) == 0) {
19687                 // This was an implicit broadcast... let's record it for posterity.
19688                 addBroadcastStatLocked(intent.getAction(), callerPackage, 0, 0, 0);
19689             }
19690         }
19691
19692         return ActivityManager.BROADCAST_SUCCESS;
19693     }
19694
19695     /**
19696      * @return uid from the extra field {@link Intent#EXTRA_UID} if present, Otherwise -1
19697      */
19698     private int getUidFromIntent(Intent intent) {
19699         if (intent == null) {
19700             return -1;
19701         }
19702         final Bundle intentExtras = intent.getExtras();
19703         return intent.hasExtra(Intent.EXTRA_UID)
19704                 ? intentExtras.getInt(Intent.EXTRA_UID) : -1;
19705     }
19706
19707     final void rotateBroadcastStatsIfNeededLocked() {
19708         final long now = SystemClock.elapsedRealtime();
19709         if (mCurBroadcastStats == null ||
19710                 (mCurBroadcastStats.mStartRealtime +(24*60*60*1000) < now)) {
19711             mLastBroadcastStats = mCurBroadcastStats;
19712             if (mLastBroadcastStats != null) {
19713                 mLastBroadcastStats.mEndRealtime = SystemClock.elapsedRealtime();
19714                 mLastBroadcastStats.mEndUptime = SystemClock.uptimeMillis();
19715             }
19716             mCurBroadcastStats = new BroadcastStats();
19717         }
19718     }
19719
19720     final void addBroadcastStatLocked(String action, String srcPackage, int receiveCount,
19721             int skipCount, long dispatchTime) {
19722         rotateBroadcastStatsIfNeededLocked();
19723         mCurBroadcastStats.addBroadcast(action, srcPackage, receiveCount, skipCount, dispatchTime);
19724     }
19725
19726     final void addBackgroundCheckViolationLocked(String action, String targetPackage) {
19727         rotateBroadcastStatsIfNeededLocked();
19728         mCurBroadcastStats.addBackgroundCheckViolation(action, targetPackage);
19729     }
19730
19731     final Intent verifyBroadcastLocked(Intent intent) {
19732         // Refuse possible leaked file descriptors
19733         if (intent != null && intent.hasFileDescriptors() == true) {
19734             throw new IllegalArgumentException("File descriptors passed in Intent");
19735         }
19736
19737         int flags = intent.getFlags();
19738
19739         if (!mProcessesReady) {
19740             // if the caller really truly claims to know what they're doing, go
19741             // ahead and allow the broadcast without launching any receivers
19742             if ((flags&Intent.FLAG_RECEIVER_REGISTERED_ONLY_BEFORE_BOOT) != 0) {
19743                 // This will be turned into a FLAG_RECEIVER_REGISTERED_ONLY later on if needed.
19744             } else if ((flags&Intent.FLAG_RECEIVER_REGISTERED_ONLY) == 0) {
19745                 Slog.e(TAG, "Attempt to launch receivers of broadcast intent " + intent
19746                         + " before boot completion");
19747                 throw new IllegalStateException("Cannot broadcast before boot completed");
19748             }
19749         }
19750
19751         if ((flags&Intent.FLAG_RECEIVER_BOOT_UPGRADE) != 0) {
19752             throw new IllegalArgumentException(
19753                     "Can't use FLAG_RECEIVER_BOOT_UPGRADE here");
19754         }
19755
19756         if ((flags & Intent.FLAG_RECEIVER_FROM_SHELL) != 0) {
19757             switch (Binder.getCallingUid()) {
19758                 case ROOT_UID:
19759                 case SHELL_UID:
19760                     break;
19761                 default:
19762                     Slog.w(TAG, "Removing FLAG_RECEIVER_FROM_SHELL because caller is UID "
19763                             + Binder.getCallingUid());
19764                     intent.removeFlags(Intent.FLAG_RECEIVER_FROM_SHELL);
19765                     break;
19766             }
19767         }
19768
19769         return intent;
19770     }
19771
19772     public final int broadcastIntent(IApplicationThread caller,
19773             Intent intent, String resolvedType, IIntentReceiver resultTo,
19774             int resultCode, String resultData, Bundle resultExtras,
19775             String[] requiredPermissions, int appOp, Bundle bOptions,
19776             boolean serialized, boolean sticky, int userId) {
19777         enforceNotIsolatedCaller("broadcastIntent");
19778         synchronized(this) {
19779             intent = verifyBroadcastLocked(intent);
19780
19781             final ProcessRecord callerApp = getRecordForAppLocked(caller);
19782             final int callingPid = Binder.getCallingPid();
19783             final int callingUid = Binder.getCallingUid();
19784             final long origId = Binder.clearCallingIdentity();
19785             int res = broadcastIntentLocked(callerApp,
19786                     callerApp != null ? callerApp.info.packageName : null,
19787                     intent, resolvedType, resultTo, resultCode, resultData, resultExtras,
19788                     requiredPermissions, appOp, bOptions, serialized, sticky,
19789                     callingPid, callingUid, userId);
19790             Binder.restoreCallingIdentity(origId);
19791             return res;
19792         }
19793     }
19794
19795
19796     int broadcastIntentInPackage(String packageName, int uid,
19797             Intent intent, String resolvedType, IIntentReceiver resultTo,
19798             int resultCode, String resultData, Bundle resultExtras,
19799             String requiredPermission, Bundle bOptions, boolean serialized, boolean sticky,
19800             int userId) {
19801         synchronized(this) {
19802             intent = verifyBroadcastLocked(intent);
19803
19804             final long origId = Binder.clearCallingIdentity();
19805             String[] requiredPermissions = requiredPermission == null ? null
19806                     : new String[] {requiredPermission};
19807             int res = broadcastIntentLocked(null, packageName, intent, resolvedType,
19808                     resultTo, resultCode, resultData, resultExtras,
19809                     requiredPermissions, AppOpsManager.OP_NONE, bOptions, serialized,
19810                     sticky, -1, uid, userId);
19811             Binder.restoreCallingIdentity(origId);
19812             return res;
19813         }
19814     }
19815
19816     public final void unbroadcastIntent(IApplicationThread caller, Intent intent, int userId) {
19817         // Refuse possible leaked file descriptors
19818         if (intent != null && intent.hasFileDescriptors() == true) {
19819             throw new IllegalArgumentException("File descriptors passed in Intent");
19820         }
19821
19822         userId = mUserController.handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(),
19823                 userId, true, ALLOW_NON_FULL, "removeStickyBroadcast", null);
19824
19825         synchronized(this) {
19826             if (checkCallingPermission(android.Manifest.permission.BROADCAST_STICKY)
19827                     != PackageManager.PERMISSION_GRANTED) {
19828                 String msg = "Permission Denial: unbroadcastIntent() from pid="
19829                         + Binder.getCallingPid()
19830                         + ", uid=" + Binder.getCallingUid()
19831                         + " requires " + android.Manifest.permission.BROADCAST_STICKY;
19832                 Slog.w(TAG, msg);
19833                 throw new SecurityException(msg);
19834             }
19835             ArrayMap<String, ArrayList<Intent>> stickies = mStickyBroadcasts.get(userId);
19836             if (stickies != null) {
19837                 ArrayList<Intent> list = stickies.get(intent.getAction());
19838                 if (list != null) {
19839                     int N = list.size();
19840                     int i;
19841                     for (i=0; i<N; i++) {
19842                         if (intent.filterEquals(list.get(i))) {
19843                             list.remove(i);
19844                             break;
19845                         }
19846                     }
19847                     if (list.size() <= 0) {
19848                         stickies.remove(intent.getAction());
19849                     }
19850                 }
19851                 if (stickies.size() <= 0) {
19852                     mStickyBroadcasts.remove(userId);
19853                 }
19854             }
19855         }
19856     }
19857
19858     void backgroundServicesFinishedLocked(int userId) {
19859         for (BroadcastQueue queue : mBroadcastQueues) {
19860             queue.backgroundServicesFinishedLocked(userId);
19861         }
19862     }
19863
19864     public void finishReceiver(IBinder who, int resultCode, String resultData,
19865             Bundle resultExtras, boolean resultAbort, int flags) {
19866         if (DEBUG_BROADCAST) Slog.v(TAG_BROADCAST, "Finish receiver: " + who);
19867
19868         // Refuse possible leaked file descriptors
19869         if (resultExtras != null && resultExtras.hasFileDescriptors()) {
19870             throw new IllegalArgumentException("File descriptors passed in Bundle");
19871         }
19872
19873         final long origId = Binder.clearCallingIdentity();
19874         try {
19875             boolean doNext = false;
19876             BroadcastRecord r;
19877
19878             synchronized(this) {
19879                 BroadcastQueue queue = (flags & Intent.FLAG_RECEIVER_FOREGROUND) != 0
19880                         ? mFgBroadcastQueue : mBgBroadcastQueue;
19881                 r = queue.getMatchingOrderedReceiver(who);
19882                 if (r != null) {
19883                     doNext = r.queue.finishReceiverLocked(r, resultCode,
19884                         resultData, resultExtras, resultAbort, true);
19885                 }
19886             }
19887
19888             if (doNext) {
19889                 r.queue.processNextBroadcast(false);
19890             }
19891             trimApplications();
19892         } finally {
19893             Binder.restoreCallingIdentity(origId);
19894         }
19895     }
19896
19897     // =========================================================
19898     // INSTRUMENTATION
19899     // =========================================================
19900
19901     public boolean startInstrumentation(ComponentName className,
19902             String profileFile, int flags, Bundle arguments,
19903             IInstrumentationWatcher watcher, IUiAutomationConnection uiAutomationConnection,
19904             int userId, String abiOverride) {
19905         enforceNotIsolatedCaller("startInstrumentation");
19906         userId = mUserController.handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(),
19907                 userId, false, ALLOW_FULL_ONLY, "startInstrumentation", null);
19908         // Refuse possible leaked file descriptors
19909         if (arguments != null && arguments.hasFileDescriptors()) {
19910             throw new IllegalArgumentException("File descriptors passed in Bundle");
19911         }
19912
19913         synchronized(this) {
19914             InstrumentationInfo ii = null;
19915             ApplicationInfo ai = null;
19916             try {
19917                 ii = mContext.getPackageManager().getInstrumentationInfo(
19918                     className, STOCK_PM_FLAGS);
19919                 ai = AppGlobals.getPackageManager().getApplicationInfo(
19920                         ii.targetPackage, STOCK_PM_FLAGS, userId);
19921             } catch (PackageManager.NameNotFoundException e) {
19922             } catch (RemoteException e) {
19923             }
19924             if (ii == null) {
19925                 reportStartInstrumentationFailureLocked(watcher, className,
19926                         "Unable to find instrumentation info for: " + className);
19927                 return false;
19928             }
19929             if (ai == null) {
19930                 reportStartInstrumentationFailureLocked(watcher, className,
19931                         "Unable to find instrumentation target package: " + ii.targetPackage);
19932                 return false;
19933             }
19934             if (!ai.hasCode()) {
19935                 reportStartInstrumentationFailureLocked(watcher, className,
19936                         "Instrumentation target has no code: " + ii.targetPackage);
19937                 return false;
19938             }
19939
19940             int match = mContext.getPackageManager().checkSignatures(
19941                     ii.targetPackage, ii.packageName);
19942             if (match < 0 && match != PackageManager.SIGNATURE_FIRST_NOT_SIGNED) {
19943                 String msg = "Permission Denial: starting instrumentation "
19944                         + className + " from pid="
19945                         + Binder.getCallingPid()
19946                         + ", uid=" + Binder.getCallingPid()
19947                         + " not allowed because package " + ii.packageName
19948                         + " does not have a signature matching the target "
19949                         + ii.targetPackage;
19950                 reportStartInstrumentationFailureLocked(watcher, className, msg);
19951                 throw new SecurityException(msg);
19952             }
19953
19954             ActiveInstrumentation activeInstr = new ActiveInstrumentation(this);
19955             activeInstr.mClass = className;
19956             String defProcess = ai.processName;;
19957             if (ii.targetProcesses == null) {
19958                 activeInstr.mTargetProcesses = new String[]{ai.processName};
19959             } else if (ii.targetProcesses.equals("*")) {
19960                 activeInstr.mTargetProcesses = new String[0];
19961             } else {
19962                 activeInstr.mTargetProcesses = ii.targetProcesses.split(",");
19963                 defProcess = activeInstr.mTargetProcesses[0];
19964             }
19965             activeInstr.mTargetInfo = ai;
19966             activeInstr.mProfileFile = profileFile;
19967             activeInstr.mArguments = arguments;
19968             activeInstr.mWatcher = watcher;
19969             activeInstr.mUiAutomationConnection = uiAutomationConnection;
19970             activeInstr.mResultClass = className;
19971
19972             final long origId = Binder.clearCallingIdentity();
19973             // Instrumentation can kill and relaunch even persistent processes
19974             forceStopPackageLocked(ii.targetPackage, -1, true, false, true, true, false, userId,
19975                     "start instr");
19976             ProcessRecord app = addAppLocked(ai, defProcess, false, abiOverride);
19977             app.instr = activeInstr;
19978             activeInstr.mFinished = false;
19979             activeInstr.mRunningProcesses.add(app);
19980             if (!mActiveInstrumentation.contains(activeInstr)) {
19981                 mActiveInstrumentation.add(activeInstr);
19982             }
19983             Binder.restoreCallingIdentity(origId);
19984         }
19985
19986         return true;
19987     }
19988
19989     /**
19990      * Report errors that occur while attempting to start Instrumentation.  Always writes the
19991      * error to the logs, but if somebody is watching, send the report there too.  This enables
19992      * the "am" command to report errors with more information.
19993      *
19994      * @param watcher The IInstrumentationWatcher.  Null if there isn't one.
19995      * @param cn The component name of the instrumentation.
19996      * @param report The error report.
19997      */
19998     private void reportStartInstrumentationFailureLocked(IInstrumentationWatcher watcher,
19999             ComponentName cn, String report) {
20000         Slog.w(TAG, report);
20001         if (watcher != null) {
20002             Bundle results = new Bundle();
20003             results.putString(Instrumentation.REPORT_KEY_IDENTIFIER, "ActivityManagerService");
20004             results.putString("Error", report);
20005             mInstrumentationReporter.reportStatus(watcher, cn, -1, results);
20006         }
20007     }
20008
20009     void addInstrumentationResultsLocked(ProcessRecord app, Bundle results) {
20010         if (app.instr == null) {
20011             Slog.w(TAG, "finishInstrumentation called on non-instrumented: " + app);
20012             return;
20013         }
20014
20015         if (!app.instr.mFinished && results != null) {
20016             if (app.instr.mCurResults == null) {
20017                 app.instr.mCurResults = new Bundle(results);
20018             } else {
20019                 app.instr.mCurResults.putAll(results);
20020             }
20021         }
20022     }
20023
20024     public void addInstrumentationResults(IApplicationThread target, Bundle results) {
20025         int userId = UserHandle.getCallingUserId();
20026         // Refuse possible leaked file descriptors
20027         if (results != null && results.hasFileDescriptors()) {
20028             throw new IllegalArgumentException("File descriptors passed in Intent");
20029         }
20030
20031         synchronized(this) {
20032             ProcessRecord app = getRecordForAppLocked(target);
20033             if (app == null) {
20034                 Slog.w(TAG, "addInstrumentationResults: no app for " + target);
20035                 return;
20036             }
20037             final long origId = Binder.clearCallingIdentity();
20038             addInstrumentationResultsLocked(app, results);
20039             Binder.restoreCallingIdentity(origId);
20040         }
20041     }
20042
20043     void finishInstrumentationLocked(ProcessRecord app, int resultCode, Bundle results) {
20044         if (app.instr == null) {
20045             Slog.w(TAG, "finishInstrumentation called on non-instrumented: " + app);
20046             return;
20047         }
20048
20049         if (!app.instr.mFinished) {
20050             if (app.instr.mWatcher != null) {
20051                 Bundle finalResults = app.instr.mCurResults;
20052                 if (finalResults != null) {
20053                     if (app.instr.mCurResults != null && results != null) {
20054                         finalResults.putAll(results);
20055                     }
20056                 } else {
20057                     finalResults = results;
20058                 }
20059                 mInstrumentationReporter.reportFinished(app.instr.mWatcher,
20060                         app.instr.mClass, resultCode, finalResults);
20061             }
20062
20063             // Can't call out of the system process with a lock held, so post a message.
20064             if (app.instr.mUiAutomationConnection != null) {
20065                 mHandler.obtainMessage(SHUTDOWN_UI_AUTOMATION_CONNECTION_MSG,
20066                         app.instr.mUiAutomationConnection).sendToTarget();
20067             }
20068             app.instr.mFinished = true;
20069         }
20070
20071         app.instr.removeProcess(app);
20072         app.instr = null;
20073
20074         forceStopPackageLocked(app.info.packageName, -1, false, false, true, true, false, app.userId,
20075                 "finished inst");
20076     }
20077
20078     public void finishInstrumentation(IApplicationThread target,
20079             int resultCode, Bundle results) {
20080         int userId = UserHandle.getCallingUserId();
20081         // Refuse possible leaked file descriptors
20082         if (results != null && results.hasFileDescriptors()) {
20083             throw new IllegalArgumentException("File descriptors passed in Intent");
20084         }
20085
20086         synchronized(this) {
20087             ProcessRecord app = getRecordForAppLocked(target);
20088             if (app == null) {
20089                 Slog.w(TAG, "finishInstrumentation: no app for " + target);
20090                 return;
20091             }
20092             final long origId = Binder.clearCallingIdentity();
20093             finishInstrumentationLocked(app, resultCode, results);
20094             Binder.restoreCallingIdentity(origId);
20095         }
20096     }
20097
20098     // =========================================================
20099     // CONFIGURATION
20100     // =========================================================
20101
20102     public ConfigurationInfo getDeviceConfigurationInfo() {
20103         ConfigurationInfo config = new ConfigurationInfo();
20104         synchronized (this) {
20105             final Configuration globalConfig = getGlobalConfiguration();
20106             config.reqTouchScreen = globalConfig.touchscreen;
20107             config.reqKeyboardType = globalConfig.keyboard;
20108             config.reqNavigation = globalConfig.navigation;
20109             if (globalConfig.navigation == Configuration.NAVIGATION_DPAD
20110                     || globalConfig.navigation == Configuration.NAVIGATION_TRACKBALL) {
20111                 config.reqInputFeatures |= ConfigurationInfo.INPUT_FEATURE_FIVE_WAY_NAV;
20112             }
20113             if (globalConfig.keyboard != Configuration.KEYBOARD_UNDEFINED
20114                     && globalConfig.keyboard != Configuration.KEYBOARD_NOKEYS) {
20115                 config.reqInputFeatures |= ConfigurationInfo.INPUT_FEATURE_HARD_KEYBOARD;
20116             }
20117             config.reqGlEsVersion = GL_ES_VERSION;
20118         }
20119         return config;
20120     }
20121
20122     ActivityStack getFocusedStack() {
20123         return mStackSupervisor.getFocusedStack();
20124     }
20125
20126     @Override
20127     public int getFocusedStackId() throws RemoteException {
20128         ActivityStack focusedStack = getFocusedStack();
20129         if (focusedStack != null) {
20130             return focusedStack.getStackId();
20131         }
20132         return -1;
20133     }
20134
20135     public Configuration getConfiguration() {
20136         Configuration ci;
20137         synchronized(this) {
20138             ci = new Configuration(getGlobalConfiguration());
20139             ci.userSetLocale = false;
20140         }
20141         return ci;
20142     }
20143
20144     @Override
20145     public void suppressResizeConfigChanges(boolean suppress) throws RemoteException {
20146         enforceCallingPermission(MANAGE_ACTIVITY_STACKS, "suppressResizeConfigChanges()");
20147         synchronized (this) {
20148             mSuppressResizeConfigChanges = suppress;
20149         }
20150     }
20151
20152     /**
20153      * NOTE: For the pinned stack, this method is usually called after the bounds animation has
20154      *       animated the stack to the fullscreen, but can also be called if we are relaunching an
20155      *       activity and clearing the task at the same time.
20156      */
20157     @Override
20158     public void moveTasksToFullscreenStack(int fromStackId, boolean onTop) {
20159         enforceCallingPermission(MANAGE_ACTIVITY_STACKS, "moveTasksToFullscreenStack()");
20160         if (StackId.isHomeOrRecentsStack(fromStackId)) {
20161             throw new IllegalArgumentException("You can't move tasks from the home/recents stack.");
20162         }
20163         synchronized (this) {
20164             final long origId = Binder.clearCallingIdentity();
20165             try {
20166                 mStackSupervisor.moveTasksToFullscreenStackLocked(fromStackId, onTop);
20167             } finally {
20168                 Binder.restoreCallingIdentity(origId);
20169             }
20170         }
20171     }
20172
20173     @Override
20174     public void updatePersistentConfiguration(Configuration values) {
20175         enforceCallingPermission(CHANGE_CONFIGURATION, "updatePersistentConfiguration()");
20176         enforceWriteSettingsPermission("updatePersistentConfiguration()");
20177         if (values == null) {
20178             throw new NullPointerException("Configuration must not be null");
20179         }
20180
20181         int userId = UserHandle.getCallingUserId();
20182
20183         synchronized(this) {
20184             updatePersistentConfigurationLocked(values, userId);
20185         }
20186     }
20187
20188     private void updatePersistentConfigurationLocked(Configuration values, @UserIdInt int userId) {
20189         final long origId = Binder.clearCallingIdentity();
20190         try {
20191             updateConfigurationLocked(values, null, false, true, userId, false /* deferResume */);
20192         } finally {
20193             Binder.restoreCallingIdentity(origId);
20194         }
20195     }
20196
20197     private void updateFontScaleIfNeeded(@UserIdInt int userId) {
20198         final float scaleFactor = Settings.System.getFloatForUser(mContext.getContentResolver(),
20199                 FONT_SCALE, 1.0f, userId);
20200
20201         synchronized (this) {
20202             if (getGlobalConfiguration().fontScale == scaleFactor) {
20203                 return;
20204             }
20205
20206             final Configuration configuration
20207                     = mWindowManager.computeNewConfiguration(DEFAULT_DISPLAY);
20208             configuration.fontScale = scaleFactor;
20209             updatePersistentConfigurationLocked(configuration, userId);
20210         }
20211     }
20212
20213     private void enforceWriteSettingsPermission(String func) {
20214         int uid = Binder.getCallingUid();
20215         if (uid == ROOT_UID) {
20216             return;
20217         }
20218
20219         if (Settings.checkAndNoteWriteSettingsOperation(mContext, uid,
20220                 Settings.getPackageNameForUid(mContext, uid), false)) {
20221             return;
20222         }
20223
20224         String msg = "Permission Denial: " + func + " from pid="
20225                 + Binder.getCallingPid()
20226                 + ", uid=" + uid
20227                 + " requires " + android.Manifest.permission.WRITE_SETTINGS;
20228         Slog.w(TAG, msg);
20229         throw new SecurityException(msg);
20230     }
20231
20232     @Override
20233     public boolean updateConfiguration(Configuration values) {
20234         enforceCallingPermission(CHANGE_CONFIGURATION, "updateConfiguration()");
20235
20236         synchronized(this) {
20237             if (values == null && mWindowManager != null) {
20238                 // sentinel: fetch the current configuration from the window manager
20239                 values = mWindowManager.computeNewConfiguration(DEFAULT_DISPLAY);
20240             }
20241
20242             if (mWindowManager != null) {
20243                 // Update OOM levels based on display size.
20244                 mProcessList.applyDisplaySize(mWindowManager);
20245             }
20246
20247             final long origId = Binder.clearCallingIdentity();
20248             try {
20249                 if (values != null) {
20250                     Settings.System.clearConfiguration(values);
20251                 }
20252                 updateConfigurationLocked(values, null, false, false /* persistent */,
20253                         UserHandle.USER_NULL, false /* deferResume */,
20254                         mTmpUpdateConfigurationResult);
20255                 return mTmpUpdateConfigurationResult.changes != 0;
20256             } finally {
20257                 Binder.restoreCallingIdentity(origId);
20258             }
20259         }
20260     }
20261
20262     void updateUserConfigurationLocked() {
20263         final Configuration configuration = new Configuration(getGlobalConfiguration());
20264         final int currentUserId = mUserController.getCurrentUserIdLocked();
20265         Settings.System.adjustConfigurationForUser(mContext.getContentResolver(), configuration,
20266                 currentUserId, Settings.System.canWrite(mContext));
20267         updateConfigurationLocked(configuration, null /* starting */, false /* initLocale */,
20268                 false /* persistent */, currentUserId, false /* deferResume */);
20269     }
20270
20271     boolean updateConfigurationLocked(Configuration values, ActivityRecord starting,
20272             boolean initLocale) {
20273         return updateConfigurationLocked(values, starting, initLocale, false /* deferResume */);
20274     }
20275
20276     boolean updateConfigurationLocked(Configuration values, ActivityRecord starting,
20277             boolean initLocale, boolean deferResume) {
20278         // pass UserHandle.USER_NULL as userId because we don't persist configuration for any user
20279         return updateConfigurationLocked(values, starting, initLocale, false /* persistent */,
20280                 UserHandle.USER_NULL, deferResume);
20281     }
20282
20283     // To cache the list of supported system locales
20284     private String[] mSupportedSystemLocales = null;
20285
20286     private boolean updateConfigurationLocked(Configuration values, ActivityRecord starting,
20287             boolean initLocale, boolean persistent, int userId, boolean deferResume) {
20288         return updateConfigurationLocked(values, starting, initLocale, persistent, userId,
20289                 deferResume, null /* result */);
20290     }
20291
20292     /**
20293      * Do either or both things: (1) change the current configuration, and (2)
20294      * make sure the given activity is running with the (now) current
20295      * configuration.  Returns true if the activity has been left running, or
20296      * false if <var>starting</var> is being destroyed to match the new
20297      * configuration.
20298      *
20299      * @param userId is only used when persistent parameter is set to true to persist configuration
20300      *               for that particular user
20301      */
20302     private boolean updateConfigurationLocked(Configuration values, ActivityRecord starting,
20303             boolean initLocale, boolean persistent, int userId, boolean deferResume,
20304             UpdateConfigurationResult result) {
20305         int changes = 0;
20306         boolean kept = true;
20307
20308         if (mWindowManager != null) {
20309             mWindowManager.deferSurfaceLayout();
20310         }
20311         try {
20312             if (values != null) {
20313                 changes = updateGlobalConfiguration(values, initLocale, persistent, userId,
20314                         deferResume);
20315             }
20316
20317             kept = ensureConfigAndVisibilityAfterUpdate(starting, changes);
20318         } finally {
20319             if (mWindowManager != null) {
20320                 mWindowManager.continueSurfaceLayout();
20321             }
20322         }
20323
20324         if (result != null) {
20325             result.changes = changes;
20326             result.activityRelaunched = !kept;
20327         }
20328         return kept;
20329     }
20330
20331     /** Update default (global) configuration and notify listeners about changes. */
20332     private int updateGlobalConfiguration(@NonNull Configuration values, boolean initLocale,
20333             boolean persistent, int userId, boolean deferResume) {
20334         mTempConfig.setTo(getGlobalConfiguration());
20335         final int changes = mTempConfig.updateFrom(values);
20336         if (changes == 0) {
20337             // Since calling to Activity.setRequestedOrientation leads to freezing the window with
20338             // setting WindowManagerService.mWaitingForConfig to true, it is important that we call
20339             // performDisplayOverrideConfigUpdate in order to send the new display configuration
20340             // (even if there are no actual changes) to unfreeze the window.
20341             performDisplayOverrideConfigUpdate(values, deferResume, DEFAULT_DISPLAY);
20342             return 0;
20343         }
20344
20345         if (DEBUG_SWITCH || DEBUG_CONFIGURATION) Slog.i(TAG_CONFIGURATION,
20346                 "Updating global configuration to: " + values);
20347
20348         EventLog.writeEvent(EventLogTags.CONFIGURATION_CHANGED, changes);
20349
20350         if (!initLocale && !values.getLocales().isEmpty() && values.userSetLocale) {
20351             final LocaleList locales = values.getLocales();
20352             int bestLocaleIndex = 0;
20353             if (locales.size() > 1) {
20354                 if (mSupportedSystemLocales == null) {
20355                     mSupportedSystemLocales = Resources.getSystem().getAssets().getLocales();
20356                 }
20357                 bestLocaleIndex = Math.max(0, locales.getFirstMatchIndex(mSupportedSystemLocales));
20358             }
20359             SystemProperties.set("persist.sys.locale",
20360                     locales.get(bestLocaleIndex).toLanguageTag());
20361             LocaleList.setDefault(locales, bestLocaleIndex);
20362             mHandler.sendMessage(mHandler.obtainMessage(SEND_LOCALE_TO_MOUNT_DAEMON_MSG,
20363                     locales.get(bestLocaleIndex)));
20364         }
20365
20366         mConfigurationSeq = Math.max(++mConfigurationSeq, 1);
20367         mTempConfig.seq = mConfigurationSeq;
20368
20369         // Update stored global config and notify everyone about the change.
20370         mStackSupervisor.onConfigurationChanged(mTempConfig);
20371
20372         Slog.i(TAG, "Config changes=" + Integer.toHexString(changes) + " " + mTempConfig);
20373         // TODO(multi-display): Update UsageEvents#Event to include displayId.
20374         mUsageStatsService.reportConfigurationChange(mTempConfig,
20375                 mUserController.getCurrentUserIdLocked());
20376
20377         // TODO: If our config changes, should we auto dismiss any currently showing dialogs?
20378         mShowDialogs = shouldShowDialogs(mTempConfig);
20379
20380         AttributeCache ac = AttributeCache.instance();
20381         if (ac != null) {
20382             ac.updateConfiguration(mTempConfig);
20383         }
20384
20385         // Make sure all resources in our process are updated right now, so that anyone who is going
20386         // to retrieve resource values after we return will be sure to get the new ones. This is
20387         // especially important during boot, where the first config change needs to guarantee all
20388         // resources have that config before following boot code is executed.
20389         mSystemThread.applyConfigurationToResources(mTempConfig);
20390
20391         // We need another copy of global config because we're scheduling some calls instead of
20392         // running them in place. We need to be sure that object we send will be handled unchanged.
20393         final Configuration configCopy = new Configuration(mTempConfig);
20394         if (persistent && Settings.System.hasInterestingConfigurationChanges(changes)) {
20395             Message msg = mHandler.obtainMessage(UPDATE_CONFIGURATION_MSG);
20396             msg.obj = configCopy;
20397             msg.arg1 = userId;
20398             mHandler.sendMessage(msg);
20399         }
20400
20401         for (int i = mLruProcesses.size() - 1; i >= 0; i--) {
20402             ProcessRecord app = mLruProcesses.get(i);
20403             try {
20404                 if (app.thread != null) {
20405                     if (DEBUG_CONFIGURATION) Slog.v(TAG_CONFIGURATION, "Sending to proc "
20406                             + app.processName + " new config " + configCopy);
20407                     app.thread.scheduleConfigurationChanged(configCopy);
20408                 }
20409             } catch (Exception e) {
20410             }
20411         }
20412
20413         Intent intent = new Intent(Intent.ACTION_CONFIGURATION_CHANGED);
20414         intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY | Intent.FLAG_RECEIVER_REPLACE_PENDING
20415                 | Intent.FLAG_RECEIVER_FOREGROUND
20416                 | Intent.FLAG_RECEIVER_VISIBLE_TO_INSTANT_APPS);
20417         broadcastIntentLocked(null, null, intent, null, null, 0, null, null, null,
20418                 AppOpsManager.OP_NONE, null, false, false, MY_PID, SYSTEM_UID,
20419                 UserHandle.USER_ALL);
20420         if ((changes & ActivityInfo.CONFIG_LOCALE) != 0) {
20421             intent = new Intent(Intent.ACTION_LOCALE_CHANGED);
20422             intent.addFlags(Intent.FLAG_RECEIVER_FOREGROUND
20423                     | Intent.FLAG_RECEIVER_INCLUDE_BACKGROUND
20424                     | Intent.FLAG_RECEIVER_VISIBLE_TO_INSTANT_APPS);
20425             if (initLocale || !mProcessesReady) {
20426                 intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY);
20427             }
20428             broadcastIntentLocked(null, null, intent, null, null, 0, null, null, null,
20429                     AppOpsManager.OP_NONE, null, false, false, MY_PID, SYSTEM_UID,
20430                     UserHandle.USER_ALL);
20431         }
20432
20433         // Override configuration of the default display duplicates global config, so we need to
20434         // update it also. This will also notify WindowManager about changes.
20435         performDisplayOverrideConfigUpdate(mStackSupervisor.getConfiguration(), deferResume,
20436                 DEFAULT_DISPLAY);
20437
20438         return changes;
20439     }
20440
20441     @Override
20442     public boolean updateDisplayOverrideConfiguration(Configuration values, int displayId) {
20443         enforceCallingPermission(CHANGE_CONFIGURATION, "updateDisplayOverrideConfiguration()");
20444
20445         synchronized (this) {
20446             // Check if display is initialized in AM.
20447             if (!mStackSupervisor.isDisplayAdded(displayId)) {
20448                 // Call might come when display is not yet added or has already been removed.
20449                 if (DEBUG_CONFIGURATION) {
20450                     Slog.w(TAG, "Trying to update display configuration for non-existing displayId="
20451                             + displayId);
20452                 }
20453                 return false;
20454             }
20455
20456             if (values == null && mWindowManager != null) {
20457                 // sentinel: fetch the current configuration from the window manager
20458                 values = mWindowManager.computeNewConfiguration(displayId);
20459             }
20460
20461             if (mWindowManager != null) {
20462                 // Update OOM levels based on display size.
20463                 mProcessList.applyDisplaySize(mWindowManager);
20464             }
20465
20466             final long origId = Binder.clearCallingIdentity();
20467             try {
20468                 if (values != null) {
20469                     Settings.System.clearConfiguration(values);
20470                 }
20471                 updateDisplayOverrideConfigurationLocked(values, null /* starting */,
20472                         false /* deferResume */, displayId, mTmpUpdateConfigurationResult);
20473                 return mTmpUpdateConfigurationResult.changes != 0;
20474             } finally {
20475                 Binder.restoreCallingIdentity(origId);
20476             }
20477         }
20478     }
20479
20480     boolean updateDisplayOverrideConfigurationLocked(Configuration values, ActivityRecord starting,
20481             boolean deferResume, int displayId) {
20482         return updateDisplayOverrideConfigurationLocked(values, starting, deferResume /* deferResume */,
20483                 displayId, null /* result */);
20484     }
20485
20486     /**
20487      * Updates override configuration specific for the selected display. If no config is provided,
20488      * new one will be computed in WM based on current display info.
20489      */
20490     private boolean updateDisplayOverrideConfigurationLocked(Configuration values,
20491             ActivityRecord starting, boolean deferResume, int displayId,
20492             UpdateConfigurationResult result) {
20493         int changes = 0;
20494         boolean kept = true;
20495
20496         if (mWindowManager != null) {
20497             mWindowManager.deferSurfaceLayout();
20498         }
20499         try {
20500             if (values != null) {
20501                 if (displayId == DEFAULT_DISPLAY) {
20502                     // Override configuration of the default display duplicates global config, so
20503                     // we're calling global config update instead for default display. It will also
20504                     // apply the correct override config.
20505                     changes = updateGlobalConfiguration(values, false /* initLocale */,
20506                             false /* persistent */, UserHandle.USER_NULL /* userId */, deferResume);
20507                 } else {
20508                     changes = performDisplayOverrideConfigUpdate(values, deferResume, displayId);
20509                 }
20510             }
20511
20512             kept = ensureConfigAndVisibilityAfterUpdate(starting, changes);
20513         } finally {
20514             if (mWindowManager != null) {
20515                 mWindowManager.continueSurfaceLayout();
20516             }
20517         }
20518
20519         if (result != null) {
20520             result.changes = changes;
20521             result.activityRelaunched = !kept;
20522         }
20523         return kept;
20524     }
20525
20526     private int performDisplayOverrideConfigUpdate(Configuration values, boolean deferResume,
20527             int displayId) {
20528         mTempConfig.setTo(mStackSupervisor.getDisplayOverrideConfiguration(displayId));
20529         final int changes = mTempConfig.updateFrom(values);
20530         if (changes != 0) {
20531             Slog.i(TAG, "Override config changes=" + Integer.toHexString(changes) + " "
20532                     + mTempConfig + " for displayId=" + displayId);
20533             mStackSupervisor.setDisplayOverrideConfiguration(mTempConfig, displayId);
20534
20535             final boolean isDensityChange = (changes & ActivityInfo.CONFIG_DENSITY) != 0;
20536             if (isDensityChange && displayId == DEFAULT_DISPLAY) {
20537                 // Reset the unsupported display size dialog.
20538                 mUiHandler.sendEmptyMessage(SHOW_UNSUPPORTED_DISPLAY_SIZE_DIALOG_MSG);
20539
20540                 killAllBackgroundProcessesExcept(N,
20541                         ActivityManager.PROCESS_STATE_FOREGROUND_SERVICE);
20542             }
20543         }
20544
20545         // Update the configuration with WM first and check if any of the stacks need to be resized
20546         // due to the configuration change. If so, resize the stacks now and do any relaunches if
20547         // necessary. This way we don't need to relaunch again afterwards in
20548         // ensureActivityConfigurationLocked().
20549         if (mWindowManager != null) {
20550             final int[] resizedStacks =
20551                     mWindowManager.setNewDisplayOverrideConfiguration(mTempConfig, displayId);
20552             if (resizedStacks != null) {
20553                 for (int stackId : resizedStacks) {
20554                     resizeStackWithBoundsFromWindowManager(stackId, deferResume);
20555                 }
20556             }
20557         }
20558
20559         return changes;
20560     }
20561
20562     /** Applies latest configuration and/or visibility updates if needed. */
20563     private boolean ensureConfigAndVisibilityAfterUpdate(ActivityRecord starting, int changes) {
20564         boolean kept = true;
20565         final ActivityStack mainStack = mStackSupervisor.getFocusedStack();
20566         // mainStack is null during startup.
20567         if (mainStack != null) {
20568             if (changes != 0 && starting == null) {
20569                 // If the configuration changed, and the caller is not already
20570                 // in the process of starting an activity, then find the top
20571                 // activity to check if its configuration needs to change.
20572                 starting = mainStack.topRunningActivityLocked();
20573             }
20574
20575             if (starting != null) {
20576                 kept = starting.ensureActivityConfigurationLocked(changes,
20577                         false /* preserveWindow */);
20578                 // And we need to make sure at this point that all other activities
20579                 // are made visible with the correct configuration.
20580                 mStackSupervisor.ensureActivitiesVisibleLocked(starting, changes,
20581                         !PRESERVE_WINDOWS);
20582             }
20583         }
20584
20585         return kept;
20586     }
20587
20588     /** Helper method that requests bounds from WM and applies them to stack. */
20589     private void resizeStackWithBoundsFromWindowManager(int stackId, boolean deferResume) {
20590         final Rect newStackBounds = new Rect();
20591         mStackSupervisor.getStack(stackId).getBoundsForNewConfiguration(newStackBounds);
20592         mStackSupervisor.resizeStackLocked(
20593                 stackId, !newStackBounds.isEmpty() ? newStackBounds : null /* bounds */,
20594                 null /* tempTaskBounds */, null /* tempTaskInsetBounds */,
20595                 false /* preserveWindows */, false /* allowResizeInDockedMode */, deferResume);
20596     }
20597
20598     /**
20599      * Decide based on the configuration whether we should show the ANR,
20600      * crash, etc dialogs.  The idea is that if there is no affordance to
20601      * press the on-screen buttons, or the user experience would be more
20602      * greatly impacted than the crash itself, we shouldn't show the dialog.
20603      *
20604      * A thought: SystemUI might also want to get told about this, the Power
20605      * dialog / global actions also might want different behaviors.
20606      */
20607     private static boolean shouldShowDialogs(Configuration config) {
20608         final boolean inputMethodExists = !(config.keyboard == Configuration.KEYBOARD_NOKEYS
20609                                    && config.touchscreen == Configuration.TOUCHSCREEN_NOTOUCH
20610                                    && config.navigation == Configuration.NAVIGATION_NONAV);
20611         int modeType = config.uiMode & Configuration.UI_MODE_TYPE_MASK;
20612         final boolean uiModeSupportsDialogs = (modeType != Configuration.UI_MODE_TYPE_CAR
20613                 && !(modeType == Configuration.UI_MODE_TYPE_WATCH && "user".equals(Build.TYPE))
20614                 && modeType != Configuration.UI_MODE_TYPE_TELEVISION
20615                 && modeType != Configuration.UI_MODE_TYPE_VR_HEADSET);
20616         return inputMethodExists && uiModeSupportsDialogs;
20617     }
20618
20619     @Override
20620     public boolean shouldUpRecreateTask(IBinder token, String destAffinity) {
20621         synchronized (this) {
20622             ActivityRecord srec = ActivityRecord.forTokenLocked(token);
20623             if (srec != null) {
20624                 return srec.getStack().shouldUpRecreateTaskLocked(srec, destAffinity);
20625             }
20626         }
20627         return false;
20628     }
20629
20630     public boolean navigateUpTo(IBinder token, Intent destIntent, int resultCode,
20631             Intent resultData) {
20632
20633         synchronized (this) {
20634             final ActivityRecord r = ActivityRecord.forTokenLocked(token);
20635             if (r != null) {
20636                 return r.getStack().navigateUpToLocked(r, destIntent, resultCode, resultData);
20637             }
20638             return false;
20639         }
20640     }
20641
20642     public int getLaunchedFromUid(IBinder activityToken) {
20643         ActivityRecord srec;
20644         synchronized (this) {
20645             srec = ActivityRecord.forTokenLocked(activityToken);
20646         }
20647         if (srec == null) {
20648             return -1;
20649         }
20650         return srec.launchedFromUid;
20651     }
20652
20653     public String getLaunchedFromPackage(IBinder activityToken) {
20654         ActivityRecord srec;
20655         synchronized (this) {
20656             srec = ActivityRecord.forTokenLocked(activityToken);
20657         }
20658         if (srec == null) {
20659             return null;
20660         }
20661         return srec.launchedFromPackage;
20662     }
20663
20664     // =========================================================
20665     // LIFETIME MANAGEMENT
20666     // =========================================================
20667
20668     // Returns whether the app is receiving broadcast.
20669     // If receiving, fetch all broadcast queues which the app is
20670     // the current [or imminent] receiver on.
20671     private boolean isReceivingBroadcastLocked(ProcessRecord app,
20672             ArraySet<BroadcastQueue> receivingQueues) {
20673         if (!app.curReceivers.isEmpty()) {
20674             for (BroadcastRecord r : app.curReceivers) {
20675                 receivingQueues.add(r.queue);
20676             }
20677             return true;
20678         }
20679
20680         // It's not the current receiver, but it might be starting up to become one
20681         for (BroadcastQueue queue : mBroadcastQueues) {
20682             final BroadcastRecord r = queue.mPendingBroadcast;
20683             if (r != null && r.curApp == app) {
20684                 // found it; report which queue it's in
20685                 receivingQueues.add(queue);
20686             }
20687         }
20688
20689         return !receivingQueues.isEmpty();
20690     }
20691
20692     Association startAssociationLocked(int sourceUid, String sourceProcess, int sourceState,
20693             int targetUid, ComponentName targetComponent, String targetProcess) {
20694         if (!mTrackingAssociations) {
20695             return null;
20696         }
20697         ArrayMap<ComponentName, SparseArray<ArrayMap<String, Association>>> components
20698                 = mAssociations.get(targetUid);
20699         if (components == null) {
20700             components = new ArrayMap<>();
20701             mAssociations.put(targetUid, components);
20702         }
20703         SparseArray<ArrayMap<String, Association>> sourceUids = components.get(targetComponent);
20704         if (sourceUids == null) {
20705             sourceUids = new SparseArray<>();
20706             components.put(targetComponent, sourceUids);
20707         }
20708         ArrayMap<String, Association> sourceProcesses = sourceUids.get(sourceUid);
20709         if (sourceProcesses == null) {
20710             sourceProcesses = new ArrayMap<>();
20711             sourceUids.put(sourceUid, sourceProcesses);
20712         }
20713         Association ass = sourceProcesses.get(sourceProcess);
20714         if (ass == null) {
20715             ass = new Association(sourceUid, sourceProcess, targetUid, targetComponent,
20716                     targetProcess);
20717             sourceProcesses.put(sourceProcess, ass);
20718         }
20719         ass.mCount++;
20720         ass.mNesting++;
20721         if (ass.mNesting == 1) {
20722             ass.mStartTime = ass.mLastStateUptime = SystemClock.uptimeMillis();
20723             ass.mLastState = sourceState;
20724         }
20725         return ass;
20726     }
20727
20728     void stopAssociationLocked(int sourceUid, String sourceProcess, int targetUid,
20729             ComponentName targetComponent) {
20730         if (!mTrackingAssociations) {
20731             return;
20732         }
20733         ArrayMap<ComponentName, SparseArray<ArrayMap<String, Association>>> components
20734                 = mAssociations.get(targetUid);
20735         if (components == null) {
20736             return;
20737         }
20738         SparseArray<ArrayMap<String, Association>> sourceUids = components.get(targetComponent);
20739         if (sourceUids == null) {
20740             return;
20741         }
20742         ArrayMap<String, Association> sourceProcesses = sourceUids.get(sourceUid);
20743         if (sourceProcesses == null) {
20744             return;
20745         }
20746         Association ass = sourceProcesses.get(sourceProcess);
20747         if (ass == null || ass.mNesting <= 0) {
20748             return;
20749         }
20750         ass.mNesting--;
20751         if (ass.mNesting == 0) {
20752             long uptime = SystemClock.uptimeMillis();
20753             ass.mTime += uptime - ass.mStartTime;
20754             ass.mStateTimes[ass.mLastState-ActivityManager.MIN_PROCESS_STATE]
20755                     += uptime - ass.mLastStateUptime;
20756             ass.mLastState = ActivityManager.MAX_PROCESS_STATE + 2;
20757         }
20758     }
20759
20760     private void noteUidProcessState(final int uid, final int state) {
20761         mBatteryStatsService.noteUidProcessState(uid, state);
20762         if (mTrackingAssociations) {
20763             for (int i1=0, N1=mAssociations.size(); i1<N1; i1++) {
20764                 ArrayMap<ComponentName, SparseArray<ArrayMap<String, Association>>> targetComponents
20765                         = mAssociations.valueAt(i1);
20766                 for (int i2=0, N2=targetComponents.size(); i2<N2; i2++) {
20767                     SparseArray<ArrayMap<String, Association>> sourceUids
20768                             = targetComponents.valueAt(i2);
20769                     ArrayMap<String, Association> sourceProcesses = sourceUids.get(uid);
20770                     if (sourceProcesses != null) {
20771                         for (int i4=0, N4=sourceProcesses.size(); i4<N4; i4++) {
20772                             Association ass = sourceProcesses.valueAt(i4);
20773                             if (ass.mNesting >= 1) {
20774                                 // currently associated
20775                                 long uptime = SystemClock.uptimeMillis();
20776                                 ass.mStateTimes[ass.mLastState-ActivityManager.MIN_PROCESS_STATE]
20777                                         += uptime - ass.mLastStateUptime;
20778                                 ass.mLastState = state;
20779                                 ass.mLastStateUptime = uptime;
20780                             }
20781                         }
20782                     }
20783                 }
20784             }
20785         }
20786     }
20787
20788     private final int computeOomAdjLocked(ProcessRecord app, int cachedAdj, ProcessRecord TOP_APP,
20789             boolean doingAll, long now) {
20790         if (mAdjSeq == app.adjSeq) {
20791             // This adjustment has already been computed.
20792             return app.curRawAdj;
20793         }
20794
20795         if (app.thread == null) {
20796             app.adjSeq = mAdjSeq;
20797             app.curSchedGroup = ProcessList.SCHED_GROUP_BACKGROUND;
20798             app.curProcState = ActivityManager.PROCESS_STATE_CACHED_EMPTY;
20799             return (app.curAdj=app.curRawAdj=ProcessList.CACHED_APP_MAX_ADJ);
20800         }
20801
20802         app.adjTypeCode = ActivityManager.RunningAppProcessInfo.REASON_UNKNOWN;
20803         app.adjSource = null;
20804         app.adjTarget = null;
20805         app.empty = false;
20806         app.cached = false;
20807
20808         final int activitiesSize = app.activities.size();
20809
20810         if (app.maxAdj <= ProcessList.FOREGROUND_APP_ADJ) {
20811             // The max adjustment doesn't allow this app to be anything
20812             // below foreground, so it is not worth doing work for it.
20813             if (DEBUG_OOM_ADJ_REASON) Slog.d(TAG, "Making fixed: " + app);
20814             app.adjType = "fixed";
20815             app.adjSeq = mAdjSeq;
20816             app.curRawAdj = app.maxAdj;
20817             app.foregroundActivities = false;
20818             app.curSchedGroup = ProcessList.SCHED_GROUP_DEFAULT;
20819             app.curProcState = ActivityManager.PROCESS_STATE_PERSISTENT;
20820             // System processes can do UI, and when they do we want to have
20821             // them trim their memory after the user leaves the UI.  To
20822             // facilitate this, here we need to determine whether or not it
20823             // is currently showing UI.
20824             app.systemNoUi = true;
20825             if (app == TOP_APP) {
20826                 app.systemNoUi = false;
20827                 app.curSchedGroup = ProcessList.SCHED_GROUP_TOP_APP;
20828                 app.adjType = "pers-top-activity";
20829             } else if (app.hasTopUi) {
20830                 app.systemNoUi = false;
20831                 app.curSchedGroup = ProcessList.SCHED_GROUP_TOP_APP;
20832                 app.adjType = "pers-top-ui";
20833             } else if (activitiesSize > 0) {
20834                 for (int j = 0; j < activitiesSize; j++) {
20835                     final ActivityRecord r = app.activities.get(j);
20836                     if (r.visible) {
20837                         app.systemNoUi = false;
20838                     }
20839                 }
20840             }
20841             if (!app.systemNoUi) {
20842                 app.curProcState = ActivityManager.PROCESS_STATE_PERSISTENT_UI;
20843             }
20844             return (app.curAdj=app.maxAdj);
20845         }
20846
20847         app.systemNoUi = false;
20848
20849         final int PROCESS_STATE_CUR_TOP = mTopProcessState;
20850
20851         // Determine the importance of the process, starting with most
20852         // important to least, and assign an appropriate OOM adjustment.
20853         int adj;
20854         int schedGroup;
20855         int procState;
20856         boolean foregroundActivities = false;
20857         mTmpBroadcastQueue.clear();
20858         if (app == TOP_APP) {
20859             // The last app on the list is the foreground app.
20860             adj = ProcessList.FOREGROUND_APP_ADJ;
20861             schedGroup = ProcessList.SCHED_GROUP_TOP_APP;
20862             app.adjType = "top-activity";
20863             foregroundActivities = true;
20864             procState = PROCESS_STATE_CUR_TOP;
20865             if (DEBUG_OOM_ADJ_REASON) Slog.d(TAG, "Making top: " + app);
20866         } else if (app.instr != null) {
20867             // Don't want to kill running instrumentation.
20868             adj = ProcessList.FOREGROUND_APP_ADJ;
20869             schedGroup = ProcessList.SCHED_GROUP_DEFAULT;
20870             app.adjType = "instrumentation";
20871             procState = ActivityManager.PROCESS_STATE_FOREGROUND_SERVICE;
20872             if (DEBUG_OOM_ADJ_REASON) Slog.d(TAG, "Making instrumentation: " + app);
20873         } else if (isReceivingBroadcastLocked(app, mTmpBroadcastQueue)) {
20874             // An app that is currently receiving a broadcast also
20875             // counts as being in the foreground for OOM killer purposes.
20876             // It's placed in a sched group based on the nature of the
20877             // broadcast as reflected by which queue it's active in.
20878             adj = ProcessList.FOREGROUND_APP_ADJ;
20879             schedGroup = (mTmpBroadcastQueue.contains(mFgBroadcastQueue))
20880                     ? ProcessList.SCHED_GROUP_DEFAULT : ProcessList.SCHED_GROUP_BACKGROUND;
20881             app.adjType = "broadcast";
20882             procState = ActivityManager.PROCESS_STATE_RECEIVER;
20883             if (DEBUG_OOM_ADJ_REASON) Slog.d(TAG, "Making broadcast: " + app);
20884         } else if (app.executingServices.size() > 0) {
20885             // An app that is currently executing a service callback also
20886             // counts as being in the foreground.
20887             adj = ProcessList.FOREGROUND_APP_ADJ;
20888             schedGroup = app.execServicesFg ?
20889                     ProcessList.SCHED_GROUP_DEFAULT : ProcessList.SCHED_GROUP_BACKGROUND;
20890             app.adjType = "exec-service";
20891             procState = ActivityManager.PROCESS_STATE_SERVICE;
20892             if (DEBUG_OOM_ADJ_REASON) Slog.d(TAG, "Making exec-service: " + app);
20893             //Slog.i(TAG, "EXEC " + (app.execServicesFg ? "FG" : "BG") + ": " + app);
20894         } else {
20895             // As far as we know the process is empty.  We may change our mind later.
20896             schedGroup = ProcessList.SCHED_GROUP_BACKGROUND;
20897             // At this point we don't actually know the adjustment.  Use the cached adj
20898             // value that the caller wants us to.
20899             adj = cachedAdj;
20900             procState = ActivityManager.PROCESS_STATE_CACHED_EMPTY;
20901             app.cached = true;
20902             app.empty = true;
20903             app.adjType = "cch-empty";
20904             if (DEBUG_OOM_ADJ_REASON) Slog.d(TAG, "Making empty: " + app);
20905         }
20906
20907         // Examine all activities if not already foreground.
20908         if (!foregroundActivities && activitiesSize > 0) {
20909             int minLayer = ProcessList.VISIBLE_APP_LAYER_MAX;
20910             for (int j = 0; j < activitiesSize; j++) {
20911                 final ActivityRecord r = app.activities.get(j);
20912                 if (r.app != app) {
20913                     Log.e(TAG, "Found activity " + r + " in proc activity list using " + r.app
20914                             + " instead of expected " + app);
20915                     if (r.app == null || (r.app.uid == app.uid)) {
20916                         // Only fix things up when they look sane
20917                         r.app = app;
20918                     } else {
20919                         continue;
20920                     }
20921                 }
20922                 if (r.visible) {
20923                     // App has a visible activity; only upgrade adjustment.
20924                     if (adj > ProcessList.VISIBLE_APP_ADJ) {
20925                         adj = ProcessList.VISIBLE_APP_ADJ;
20926                         app.adjType = "vis-activity";
20927                         if (DEBUG_OOM_ADJ_REASON) Slog.d(TAG, "Raise to vis-activity: " + app);
20928                     }
20929                     if (procState > PROCESS_STATE_CUR_TOP) {
20930                         procState = PROCESS_STATE_CUR_TOP;
20931                         app.adjType = "vis-activity";
20932                         if (DEBUG_OOM_ADJ_REASON) Slog.d(TAG, "Raise to vis-activity: " + app);
20933                     }
20934                     schedGroup = ProcessList.SCHED_GROUP_DEFAULT;
20935                     app.cached = false;
20936                     app.empty = false;
20937                     foregroundActivities = true;
20938                     final TaskRecord task = r.getTask();
20939                     if (task != null && minLayer > 0) {
20940                         final int layer = task.mLayerRank;
20941                         if (layer >= 0 && minLayer > layer) {
20942                             minLayer = layer;
20943                         }
20944                     }
20945                     break;
20946                 } else if (r.state == ActivityState.PAUSING || r.state == ActivityState.PAUSED) {
20947                     if (adj > ProcessList.PERCEPTIBLE_APP_ADJ) {
20948                         adj = ProcessList.PERCEPTIBLE_APP_ADJ;
20949                         app.adjType = "pause-activity";
20950                         if (DEBUG_OOM_ADJ_REASON) Slog.d(TAG, "Raise to pause-activity: " + app);
20951                     }
20952                     if (procState > PROCESS_STATE_CUR_TOP) {
20953                         procState = PROCESS_STATE_CUR_TOP;
20954                         app.adjType = "pause-activity";
20955                         if (DEBUG_OOM_ADJ_REASON) Slog.d(TAG, "Raise to pause-activity: " + app);
20956                     }
20957                     schedGroup = ProcessList.SCHED_GROUP_DEFAULT;
20958                     app.cached = false;
20959                     app.empty = false;
20960                     foregroundActivities = true;
20961                 } else if (r.state == ActivityState.STOPPING) {
20962                     if (adj > ProcessList.PERCEPTIBLE_APP_ADJ) {
20963                         adj = ProcessList.PERCEPTIBLE_APP_ADJ;
20964                         app.adjType = "stop-activity";
20965                         if (DEBUG_OOM_ADJ_REASON) Slog.d(TAG, "Raise to stop-activity: " + app);
20966                     }
20967                     // For the process state, we will at this point consider the
20968                     // process to be cached.  It will be cached either as an activity
20969                     // or empty depending on whether the activity is finishing.  We do
20970                     // this so that we can treat the process as cached for purposes of
20971                     // memory trimming (determing current memory level, trim command to
20972                     // send to process) since there can be an arbitrary number of stopping
20973                     // processes and they should soon all go into the cached state.
20974                     if (!r.finishing) {
20975                         if (procState > ActivityManager.PROCESS_STATE_LAST_ACTIVITY) {
20976                             procState = ActivityManager.PROCESS_STATE_LAST_ACTIVITY;
20977                             app.adjType = "stop-activity";
20978                             if (DEBUG_OOM_ADJ_REASON) Slog.d(TAG, "Raise to stop-activity: " + app);
20979                         }
20980                     }
20981                     app.cached = false;
20982                     app.empty = false;
20983                     foregroundActivities = true;
20984                 } else {
20985                     if (procState > ActivityManager.PROCESS_STATE_CACHED_ACTIVITY) {
20986                         procState = ActivityManager.PROCESS_STATE_CACHED_ACTIVITY;
20987                         app.adjType = "cch-act";
20988                         if (DEBUG_OOM_ADJ_REASON) Slog.d(TAG, "Raise to cached activity: " + app);
20989                     }
20990                 }
20991             }
20992             if (adj == ProcessList.VISIBLE_APP_ADJ) {
20993                 adj += minLayer;
20994             }
20995         }
20996
20997         if (adj > ProcessList.PERCEPTIBLE_APP_ADJ
20998                 || procState > ActivityManager.PROCESS_STATE_FOREGROUND_SERVICE) {
20999             if (app.foregroundServices) {
21000                 // The user is aware of this app, so make it visible.
21001                 adj = ProcessList.PERCEPTIBLE_APP_ADJ;
21002                 procState = ActivityManager.PROCESS_STATE_FOREGROUND_SERVICE;
21003                 app.cached = false;
21004                 app.adjType = "fg-service";
21005                 schedGroup = ProcessList.SCHED_GROUP_DEFAULT;
21006                 if (DEBUG_OOM_ADJ_REASON) Slog.d(TAG, "Raise to fg service: " + app);
21007             } else if (app.hasOverlayUi) {
21008                 // The process is display an overlay UI.
21009                 adj = ProcessList.PERCEPTIBLE_APP_ADJ;
21010                 procState = ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND;
21011                 app.cached = false;
21012                 app.adjType = "has-overlay-ui";
21013                 schedGroup = ProcessList.SCHED_GROUP_DEFAULT;
21014                 if (DEBUG_OOM_ADJ_REASON) Slog.d(TAG, "Raise to overlay ui: " + app);
21015             }
21016         }
21017
21018         if (adj > ProcessList.PERCEPTIBLE_APP_ADJ
21019                 || procState > ActivityManager.PROCESS_STATE_TRANSIENT_BACKGROUND) {
21020             if (app.forcingToImportant != null) {
21021                 // This is currently used for toasts...  they are not interactive, and
21022                 // we don't want them to cause the app to become fully foreground (and
21023                 // thus out of background check), so we yes the best background level we can.
21024                 adj = ProcessList.PERCEPTIBLE_APP_ADJ;
21025                 procState = ActivityManager.PROCESS_STATE_TRANSIENT_BACKGROUND;
21026                 app.cached = false;
21027                 app.adjType = "force-imp";
21028                 app.adjSource = app.forcingToImportant;
21029                 schedGroup = ProcessList.SCHED_GROUP_DEFAULT;
21030                 if (DEBUG_OOM_ADJ_REASON) Slog.d(TAG, "Raise to force imp: " + app);
21031             }
21032         }
21033
21034         if (app == mHeavyWeightProcess) {
21035             if (adj > ProcessList.HEAVY_WEIGHT_APP_ADJ) {
21036                 // We don't want to kill the current heavy-weight process.
21037                 adj = ProcessList.HEAVY_WEIGHT_APP_ADJ;
21038                 schedGroup = ProcessList.SCHED_GROUP_BACKGROUND;
21039                 app.cached = false;
21040                 app.adjType = "heavy";
21041                 if (DEBUG_OOM_ADJ_REASON) Slog.d(TAG, "Raise to heavy: " + app);
21042             }
21043             if (procState > ActivityManager.PROCESS_STATE_HEAVY_WEIGHT) {
21044                 procState = ActivityManager.PROCESS_STATE_HEAVY_WEIGHT;
21045                 app.adjType = "heavy";
21046                 if (DEBUG_OOM_ADJ_REASON) Slog.d(TAG, "Raise to heavy: " + app);
21047             }
21048         }
21049
21050         if (app == mHomeProcess) {
21051             if (adj > ProcessList.HOME_APP_ADJ) {
21052                 // This process is hosting what we currently consider to be the
21053                 // home app, so we don't want to let it go into the background.
21054                 adj = ProcessList.HOME_APP_ADJ;
21055                 schedGroup = ProcessList.SCHED_GROUP_BACKGROUND;
21056                 app.cached = false;
21057                 app.adjType = "home";
21058                 if (DEBUG_OOM_ADJ_REASON) Slog.d(TAG, "Raise to home: " + app);
21059             }
21060             if (procState > ActivityManager.PROCESS_STATE_HOME) {
21061                 procState = ActivityManager.PROCESS_STATE_HOME;
21062                 app.adjType = "home";
21063                 if (DEBUG_OOM_ADJ_REASON) Slog.d(TAG, "Raise to home: " + app);
21064             }
21065         }
21066
21067         if (app == mPreviousProcess && app.activities.size() > 0) {
21068             if (adj > ProcessList.PREVIOUS_APP_ADJ) {
21069                 // This was the previous process that showed UI to the user.
21070                 // We want to try to keep it around more aggressively, to give
21071                 // a good experience around switching between two apps.
21072                 adj = ProcessList.PREVIOUS_APP_ADJ;
21073                 schedGroup = ProcessList.SCHED_GROUP_BACKGROUND;
21074                 app.cached = false;
21075                 app.adjType = "previous";
21076                 if (DEBUG_OOM_ADJ_REASON) Slog.d(TAG, "Raise to prev: " + app);
21077             }
21078             if (procState > ActivityManager.PROCESS_STATE_LAST_ACTIVITY) {
21079                 procState = ActivityManager.PROCESS_STATE_LAST_ACTIVITY;
21080                 app.adjType = "previous";
21081                 if (DEBUG_OOM_ADJ_REASON) Slog.d(TAG, "Raise to prev: " + app);
21082             }
21083         }
21084
21085         if (false) Slog.i(TAG, "OOM " + app + ": initial adj=" + adj
21086                 + " reason=" + app.adjType);
21087
21088         // By default, we use the computed adjustment.  It may be changed if
21089         // there are applications dependent on our services or providers, but
21090         // this gives us a baseline and makes sure we don't get into an
21091         // infinite recursion.
21092         app.adjSeq = mAdjSeq;
21093         app.curRawAdj = adj;
21094         app.hasStartedServices = false;
21095
21096         if (mBackupTarget != null && app == mBackupTarget.app) {
21097             // If possible we want to avoid killing apps while they're being backed up
21098             if (adj > ProcessList.BACKUP_APP_ADJ) {
21099                 if (DEBUG_BACKUP) Slog.v(TAG_BACKUP, "oom BACKUP_APP_ADJ for " + app);
21100                 adj = ProcessList.BACKUP_APP_ADJ;
21101                 if (procState > ActivityManager.PROCESS_STATE_TRANSIENT_BACKGROUND) {
21102                     procState = ActivityManager.PROCESS_STATE_TRANSIENT_BACKGROUND;
21103                 }
21104                 app.adjType = "backup";
21105                 if (DEBUG_OOM_ADJ_REASON) Slog.d(TAG, "Raise to backup: " + app);
21106                 app.cached = false;
21107             }
21108             if (procState > ActivityManager.PROCESS_STATE_BACKUP) {
21109                 procState = ActivityManager.PROCESS_STATE_BACKUP;
21110                 app.adjType = "backup";
21111                 if (DEBUG_OOM_ADJ_REASON) Slog.d(TAG, "Raise to backup: " + app);
21112             }
21113         }
21114
21115         boolean mayBeTop = false;
21116         String mayBeTopType = null;
21117         Object mayBeTopSource = null;
21118         Object mayBeTopTarget = null;
21119
21120         for (int is = app.services.size()-1;
21121                 is >= 0 && (adj > ProcessList.FOREGROUND_APP_ADJ
21122                         || schedGroup == ProcessList.SCHED_GROUP_BACKGROUND
21123                         || procState > ActivityManager.PROCESS_STATE_TOP);
21124                 is--) {
21125             ServiceRecord s = app.services.valueAt(is);
21126             if (s.startRequested) {
21127                 app.hasStartedServices = true;
21128                 if (procState > ActivityManager.PROCESS_STATE_SERVICE) {
21129                     procState = ActivityManager.PROCESS_STATE_SERVICE;
21130                     app.adjType = "started-services";
21131                     if (DEBUG_OOM_ADJ_REASON) Slog.d(TAG, "Raise to started service: " + app);
21132                 }
21133                 if (app.hasShownUi && app != mHomeProcess) {
21134                     // If this process has shown some UI, let it immediately
21135                     // go to the LRU list because it may be pretty heavy with
21136                     // UI stuff.  We'll tag it with a label just to help
21137                     // debug and understand what is going on.
21138                     if (adj > ProcessList.SERVICE_ADJ) {
21139                         app.adjType = "cch-started-ui-services";
21140                     }
21141                 } else {
21142                     if (now < (s.lastActivity + mConstants.MAX_SERVICE_INACTIVITY)) {
21143                         // This service has seen some activity within
21144                         // recent memory, so we will keep its process ahead
21145                         // of the background processes.
21146                         if (adj > ProcessList.SERVICE_ADJ) {
21147                             adj = ProcessList.SERVICE_ADJ;
21148                             app.adjType = "started-services";
21149                             if (DEBUG_OOM_ADJ_REASON) Slog.d(TAG, "Raise to started service: " + app);
21150                             app.cached = false;
21151                         }
21152                     }
21153                     // If we have let the service slide into the background
21154                     // state, still have some text describing what it is doing
21155                     // even though the service no longer has an impact.
21156                     if (adj > ProcessList.SERVICE_ADJ) {
21157                         app.adjType = "cch-started-services";
21158                     }
21159                 }
21160             }
21161
21162             for (int conni = s.connections.size()-1;
21163                     conni >= 0 && (adj > ProcessList.FOREGROUND_APP_ADJ
21164                             || schedGroup == ProcessList.SCHED_GROUP_BACKGROUND
21165                             || procState > ActivityManager.PROCESS_STATE_TOP);
21166                     conni--) {
21167                 ArrayList<ConnectionRecord> clist = s.connections.valueAt(conni);
21168                 for (int i = 0;
21169                         i < clist.size() && (adj > ProcessList.FOREGROUND_APP_ADJ
21170                                 || schedGroup == ProcessList.SCHED_GROUP_BACKGROUND
21171                                 || procState > ActivityManager.PROCESS_STATE_TOP);
21172                         i++) {
21173                     // XXX should compute this based on the max of
21174                     // all connected clients.
21175                     ConnectionRecord cr = clist.get(i);
21176                     if (cr.binding.client == app) {
21177                         // Binding to ourself is not interesting.
21178                         continue;
21179                     }
21180
21181                     if ((cr.flags&Context.BIND_WAIVE_PRIORITY) == 0) {
21182                         ProcessRecord client = cr.binding.client;
21183                         int clientAdj = computeOomAdjLocked(client, cachedAdj,
21184                                 TOP_APP, doingAll, now);
21185                         int clientProcState = client.curProcState;
21186                         if (clientProcState >= ActivityManager.PROCESS_STATE_CACHED_ACTIVITY) {
21187                             // If the other app is cached for any reason, for purposes here
21188                             // we are going to consider it empty.  The specific cached state
21189                             // doesn't propagate except under certain conditions.
21190                             clientProcState = ActivityManager.PROCESS_STATE_CACHED_EMPTY;
21191                         }
21192                         String adjType = null;
21193                         if ((cr.flags&Context.BIND_ALLOW_OOM_MANAGEMENT) != 0) {
21194                             // Not doing bind OOM management, so treat
21195                             // this guy more like a started service.
21196                             if (app.hasShownUi && app != mHomeProcess) {
21197                                 // If this process has shown some UI, let it immediately
21198                                 // go to the LRU list because it may be pretty heavy with
21199                                 // UI stuff.  We'll tag it with a label just to help
21200                                 // debug and understand what is going on.
21201                                 if (adj > clientAdj) {
21202                                     adjType = "cch-bound-ui-services";
21203                                 }
21204                                 app.cached = false;
21205                                 clientAdj = adj;
21206                                 clientProcState = procState;
21207                             } else {
21208                                 if (now >= (s.lastActivity + mConstants.MAX_SERVICE_INACTIVITY)) {
21209                                     // This service has not seen activity within
21210                                     // recent memory, so allow it to drop to the
21211                                     // LRU list if there is no other reason to keep
21212                                     // it around.  We'll also tag it with a label just
21213                                     // to help debug and undertand what is going on.
21214                                     if (adj > clientAdj) {
21215                                         adjType = "cch-bound-services";
21216                                     }
21217                                     clientAdj = adj;
21218                                 }
21219                             }
21220                         }
21221                         if (adj > clientAdj) {
21222                             // If this process has recently shown UI, and
21223                             // the process that is binding to it is less
21224                             // important than being visible, then we don't
21225                             // care about the binding as much as we care
21226                             // about letting this process get into the LRU
21227                             // list to be killed and restarted if needed for
21228                             // memory.
21229                             if (app.hasShownUi && app != mHomeProcess
21230                                     && clientAdj > ProcessList.PERCEPTIBLE_APP_ADJ) {
21231                                 if (adj >= ProcessList.CACHED_APP_MIN_ADJ) {
21232                                     adjType = "cch-bound-ui-services";
21233                                 }
21234                             } else {
21235                                 int newAdj;
21236                                 if ((cr.flags&(Context.BIND_ABOVE_CLIENT
21237                                         |Context.BIND_IMPORTANT)) != 0) {
21238                                     newAdj = clientAdj >= ProcessList.PERSISTENT_SERVICE_ADJ
21239                                             ? clientAdj : ProcessList.PERSISTENT_SERVICE_ADJ;
21240                                 } else if ((cr.flags&Context.BIND_NOT_VISIBLE) != 0
21241                                         && clientAdj < ProcessList.PERCEPTIBLE_APP_ADJ
21242                                         && adj > ProcessList.PERCEPTIBLE_APP_ADJ) {
21243                                     newAdj = ProcessList.PERCEPTIBLE_APP_ADJ;
21244                                 } else if (clientAdj >= ProcessList.PERCEPTIBLE_APP_ADJ) {
21245                                     newAdj = clientAdj;
21246                                 } else {
21247                                     if (adj > ProcessList.VISIBLE_APP_ADJ) {
21248                                         newAdj = Math.max(clientAdj, ProcessList.VISIBLE_APP_ADJ);
21249                                     } else {
21250                                         newAdj = adj;
21251                                     }
21252                                 }
21253                                 if (!client.cached) {
21254                                     app.cached = false;
21255                                 }
21256                                 if (adj >  newAdj) {
21257                                     adj = newAdj;
21258                                     adjType = "service";
21259                                 }
21260                             }
21261                         }
21262                         if ((cr.flags & (Context.BIND_NOT_FOREGROUND
21263                                 | Context.BIND_IMPORTANT_BACKGROUND)) == 0) {
21264                             // This will treat important bound services identically to
21265                             // the top app, which may behave differently than generic
21266                             // foreground work.
21267                             if (client.curSchedGroup > schedGroup) {
21268                                 if ((cr.flags&Context.BIND_IMPORTANT) != 0) {
21269                                     schedGroup = client.curSchedGroup;
21270                                 } else {
21271                                     schedGroup = ProcessList.SCHED_GROUP_DEFAULT;
21272                                 }
21273                             }
21274                             if (clientProcState <= ActivityManager.PROCESS_STATE_TOP) {
21275                                 if (clientProcState == ActivityManager.PROCESS_STATE_TOP) {
21276                                     // Special handling of clients who are in the top state.
21277                                     // We *may* want to consider this process to be in the
21278                                     // top state as well, but only if there is not another
21279                                     // reason for it to be running.  Being on the top is a
21280                                     // special state, meaning you are specifically running
21281                                     // for the current top app.  If the process is already
21282                                     // running in the background for some other reason, it
21283                                     // is more important to continue considering it to be
21284                                     // in the background state.
21285                                     mayBeTop = true;
21286                                     mayBeTopType = "service";
21287                                     mayBeTopSource = cr.binding.client;
21288                                     mayBeTopTarget = s.name;
21289                                     clientProcState = ActivityManager.PROCESS_STATE_CACHED_EMPTY;
21290                                 } else {
21291                                     // Special handling for above-top states (persistent
21292                                     // processes).  These should not bring the current process
21293                                     // into the top state, since they are not on top.  Instead
21294                                     // give them the best state after that.
21295                                     if ((cr.flags&Context.BIND_FOREGROUND_SERVICE) != 0) {
21296                                         clientProcState =
21297                                                 ActivityManager.PROCESS_STATE_BOUND_FOREGROUND_SERVICE;
21298                                     } else if (mWakefulness
21299                                                     == PowerManagerInternal.WAKEFULNESS_AWAKE &&
21300                                             (cr.flags&Context.BIND_FOREGROUND_SERVICE_WHILE_AWAKE)
21301                                                     != 0) {
21302                                         clientProcState =
21303                                                 ActivityManager.PROCESS_STATE_BOUND_FOREGROUND_SERVICE;
21304                                     } else {
21305                                         clientProcState =
21306                                                 ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND;
21307                                     }
21308                                 }
21309                             }
21310                         } else if ((cr.flags & Context.BIND_IMPORTANT_BACKGROUND) == 0) {
21311                             if (clientProcState <
21312                                     ActivityManager.PROCESS_STATE_TRANSIENT_BACKGROUND) {
21313                                 clientProcState =
21314                                         ActivityManager.PROCESS_STATE_TRANSIENT_BACKGROUND;
21315                             }
21316                         } else {
21317                             if (clientProcState <
21318                                     ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND) {
21319                                 clientProcState =
21320                                         ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND;
21321                             }
21322                         }
21323                         if (procState > clientProcState) {
21324                             procState = clientProcState;
21325                             if (adjType == null) {
21326                                 adjType = "service";
21327                             }
21328                         }
21329                         if (procState < ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND
21330                                 && (cr.flags&Context.BIND_SHOWING_UI) != 0) {
21331                             app.pendingUiClean = true;
21332                         }
21333                         if (adjType != null) {
21334                             app.adjType = adjType;
21335                             app.adjTypeCode = ActivityManager.RunningAppProcessInfo
21336                                     .REASON_SERVICE_IN_USE;
21337                             app.adjSource = cr.binding.client;
21338                             app.adjSourceProcState = clientProcState;
21339                             app.adjTarget = s.name;
21340                             if (DEBUG_OOM_ADJ_REASON) Slog.d(TAG, "Raise to " + adjType
21341                                     + ": " + app + ", due to " + cr.binding.client
21342                                     + " adj=" + adj + " procState=" + procState);
21343                         }
21344                     }
21345                     if ((cr.flags&Context.BIND_TREAT_LIKE_ACTIVITY) != 0) {
21346                         app.treatLikeActivity = true;
21347                     }
21348                     final ActivityRecord a = cr.activity;
21349                     if ((cr.flags&Context.BIND_ADJUST_WITH_ACTIVITY) != 0) {
21350                         if (a != null && adj > ProcessList.FOREGROUND_APP_ADJ &&
21351                             (a.visible || a.state == ActivityState.RESUMED ||
21352                              a.state == ActivityState.PAUSING)) {
21353                             adj = ProcessList.FOREGROUND_APP_ADJ;
21354                             if ((cr.flags&Context.BIND_NOT_FOREGROUND) == 0) {
21355                                 if ((cr.flags&Context.BIND_IMPORTANT) != 0) {
21356                                     schedGroup = ProcessList.SCHED_GROUP_TOP_APP_BOUND;
21357                                 } else {
21358                                     schedGroup = ProcessList.SCHED_GROUP_DEFAULT;
21359                                 }
21360                             }
21361                             app.cached = false;
21362                             app.adjType = "service";
21363                             app.adjTypeCode = ActivityManager.RunningAppProcessInfo
21364                                     .REASON_SERVICE_IN_USE;
21365                             app.adjSource = a;
21366                             app.adjSourceProcState = procState;
21367                             app.adjTarget = s.name;
21368                             if (DEBUG_OOM_ADJ_REASON) Slog.d(TAG, "Raise to service w/activity: "
21369                                     + app);
21370                         }
21371                     }
21372                 }
21373             }
21374         }
21375
21376         for (int provi = app.pubProviders.size()-1;
21377                 provi >= 0 && (adj > ProcessList.FOREGROUND_APP_ADJ
21378                         || schedGroup == ProcessList.SCHED_GROUP_BACKGROUND
21379                         || procState > ActivityManager.PROCESS_STATE_TOP);
21380                 provi--) {
21381             ContentProviderRecord cpr = app.pubProviders.valueAt(provi);
21382             for (int i = cpr.connections.size()-1;
21383                     i >= 0 && (adj > ProcessList.FOREGROUND_APP_ADJ
21384                             || schedGroup == ProcessList.SCHED_GROUP_BACKGROUND
21385                             || procState > ActivityManager.PROCESS_STATE_TOP);
21386                     i--) {
21387                 ContentProviderConnection conn = cpr.connections.get(i);
21388                 ProcessRecord client = conn.client;
21389                 if (client == app) {
21390                     // Being our own client is not interesting.
21391                     continue;
21392                 }
21393                 int clientAdj = computeOomAdjLocked(client, cachedAdj, TOP_APP, doingAll, now);
21394                 int clientProcState = client.curProcState;
21395                 if (clientProcState >= ActivityManager.PROCESS_STATE_CACHED_ACTIVITY) {
21396                     // If the other app is cached for any reason, for purposes here
21397                     // we are going to consider it empty.
21398                     clientProcState = ActivityManager.PROCESS_STATE_CACHED_EMPTY;
21399                 }
21400                 String adjType = null;
21401                 if (adj > clientAdj) {
21402                     if (app.hasShownUi && app != mHomeProcess
21403                             && clientAdj > ProcessList.PERCEPTIBLE_APP_ADJ) {
21404                         adjType = "cch-ui-provider";
21405                     } else {
21406                         adj = clientAdj > ProcessList.FOREGROUND_APP_ADJ
21407                                 ? clientAdj : ProcessList.FOREGROUND_APP_ADJ;
21408                         adjType = "provider";
21409                     }
21410                     app.cached &= client.cached;
21411                 }
21412                 if (clientProcState <= ActivityManager.PROCESS_STATE_TOP) {
21413                     if (clientProcState == ActivityManager.PROCESS_STATE_TOP) {
21414                         // Special handling of clients who are in the top state.
21415                         // We *may* want to consider this process to be in the
21416                         // top state as well, but only if there is not another
21417                         // reason for it to be running.  Being on the top is a
21418                         // special state, meaning you are specifically running
21419                         // for the current top app.  If the process is already
21420                         // running in the background for some other reason, it
21421                         // is more important to continue considering it to be
21422                         // in the background state.
21423                         mayBeTop = true;
21424                         clientProcState = ActivityManager.PROCESS_STATE_CACHED_EMPTY;
21425                         mayBeTopType = adjType = "provider-top";
21426                         mayBeTopSource = client;
21427                         mayBeTopTarget = cpr.name;
21428                     } else {
21429                         // Special handling for above-top states (persistent
21430                         // processes).  These should not bring the current process
21431                         // into the top state, since they are not on top.  Instead
21432                         // give them the best state after that.
21433                         clientProcState =
21434                                 ActivityManager.PROCESS_STATE_BOUND_FOREGROUND_SERVICE;
21435                         if (adjType == null) {
21436                             adjType = "provider";
21437                         }
21438                     }
21439                 }
21440                 if (procState > clientProcState) {
21441                     procState = clientProcState;
21442                 }
21443                 if (client.curSchedGroup > schedGroup) {
21444                     schedGroup = ProcessList.SCHED_GROUP_DEFAULT;
21445                 }
21446                 if (adjType != null) {
21447                     app.adjType = adjType;
21448                     app.adjTypeCode = ActivityManager.RunningAppProcessInfo
21449                             .REASON_PROVIDER_IN_USE;
21450                     app.adjSource = client;
21451                     app.adjSourceProcState = clientProcState;
21452                     app.adjTarget = cpr.name;
21453                     if (DEBUG_OOM_ADJ_REASON) Slog.d(TAG, "Raise to " + adjType
21454                             + ": " + app + ", due to " + client
21455                             + " adj=" + adj + " procState=" + procState);
21456                 }
21457             }
21458             // If the provider has external (non-framework) process
21459             // dependencies, ensure that its adjustment is at least
21460             // FOREGROUND_APP_ADJ.
21461             if (cpr.hasExternalProcessHandles()) {
21462                 if (adj > ProcessList.FOREGROUND_APP_ADJ) {
21463                     adj = ProcessList.FOREGROUND_APP_ADJ;
21464                     schedGroup = ProcessList.SCHED_GROUP_DEFAULT;
21465                     app.cached = false;
21466                     app.adjType = "ext-provider";
21467                     app.adjTarget = cpr.name;
21468                     if (DEBUG_OOM_ADJ_REASON) Slog.d(TAG, "Raise to external provider: " + app);
21469                 }
21470                 if (procState > ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND) {
21471                     procState = ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND;
21472                 }
21473             }
21474         }
21475
21476         if (app.lastProviderTime > 0 &&
21477                 (app.lastProviderTime+mConstants.CONTENT_PROVIDER_RETAIN_TIME) > now) {
21478             if (adj > ProcessList.PREVIOUS_APP_ADJ) {
21479                 adj = ProcessList.PREVIOUS_APP_ADJ;
21480                 schedGroup = ProcessList.SCHED_GROUP_BACKGROUND;
21481                 app.cached = false;
21482                 app.adjType = "recent-provider";
21483                 if (DEBUG_OOM_ADJ_REASON) Slog.d(TAG, "Raise to recent provider: " + app);
21484             }
21485             if (procState > ActivityManager.PROCESS_STATE_LAST_ACTIVITY) {
21486                 procState = ActivityManager.PROCESS_STATE_LAST_ACTIVITY;
21487                 app.adjType = "recent-provider";
21488                 if (DEBUG_OOM_ADJ_REASON) Slog.d(TAG, "Raise to recent provider: " + app);
21489             }
21490         }
21491
21492         if (mayBeTop && procState > ActivityManager.PROCESS_STATE_TOP) {
21493             // A client of one of our services or providers is in the top state.  We
21494             // *may* want to be in the top state, but not if we are already running in
21495             // the background for some other reason.  For the decision here, we are going
21496             // to pick out a few specific states that we want to remain in when a client
21497             // is top (states that tend to be longer-term) and otherwise allow it to go
21498             // to the top state.
21499             switch (procState) {
21500                 case ActivityManager.PROCESS_STATE_BOUND_FOREGROUND_SERVICE:
21501                     // Something else is keeping it at this level, just leave it.
21502                     break;
21503                 case ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND:
21504                 case ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND:
21505                 case ActivityManager.PROCESS_STATE_TRANSIENT_BACKGROUND:
21506                 case ActivityManager.PROCESS_STATE_SERVICE:
21507                     // These all are longer-term states, so pull them up to the top
21508                     // of the background states, but not all the way to the top state.
21509                     procState = ActivityManager.PROCESS_STATE_BOUND_FOREGROUND_SERVICE;
21510                     app.adjType = mayBeTopType;
21511                     app.adjSource = mayBeTopSource;
21512                     app.adjTarget = mayBeTopTarget;
21513                     if (DEBUG_OOM_ADJ_REASON) Slog.d(TAG, "May be top raise to " + mayBeTopType
21514                             + ": " + app + ", due to " + mayBeTopSource
21515                             + " adj=" + adj + " procState=" + procState);
21516                     break;
21517                 default:
21518                     // Otherwise, top is a better choice, so take it.
21519                     procState = ActivityManager.PROCESS_STATE_TOP;
21520                     app.adjType = mayBeTopType;
21521                     app.adjSource = mayBeTopSource;
21522                     app.adjTarget = mayBeTopTarget;
21523                     if (DEBUG_OOM_ADJ_REASON) Slog.d(TAG, "May be top raise to " + mayBeTopType
21524                             + ": " + app + ", due to " + mayBeTopSource
21525                             + " adj=" + adj + " procState=" + procState);
21526                     break;
21527             }
21528         }
21529
21530         if (procState >= ActivityManager.PROCESS_STATE_CACHED_EMPTY) {
21531             if (app.hasClientActivities) {
21532                 // This is a cached process, but with client activities.  Mark it so.
21533                 procState = ActivityManager.PROCESS_STATE_CACHED_ACTIVITY_CLIENT;
21534                 app.adjType = "cch-client-act";
21535             } else if (app.treatLikeActivity) {
21536                 // This is a cached process, but somebody wants us to treat it like it has
21537                 // an activity, okay!
21538                 procState = ActivityManager.PROCESS_STATE_CACHED_ACTIVITY;
21539                 app.adjType = "cch-as-act";
21540             }
21541         }
21542
21543         if (adj == ProcessList.SERVICE_ADJ) {
21544             if (doingAll) {
21545                 app.serviceb = mNewNumAServiceProcs > (mNumServiceProcs/3);
21546                 mNewNumServiceProcs++;
21547                 //Slog.i(TAG, "ADJ " + app + " serviceb=" + app.serviceb);
21548                 if (!app.serviceb) {
21549                     // This service isn't far enough down on the LRU list to
21550                     // normally be a B service, but if we are low on RAM and it
21551                     // is large we want to force it down since we would prefer to
21552                     // keep launcher over it.
21553                     if (mLastMemoryLevel > ProcessStats.ADJ_MEM_FACTOR_NORMAL
21554                             && app.lastPss >= mProcessList.getCachedRestoreThresholdKb()) {
21555                         app.serviceHighRam = true;
21556                         app.serviceb = true;
21557                         //Slog.i(TAG, "ADJ " + app + " high ram!");
21558                     } else {
21559                         mNewNumAServiceProcs++;
21560                         //Slog.i(TAG, "ADJ " + app + " not high ram!");
21561                     }
21562                 } else {
21563                     app.serviceHighRam = false;
21564                 }
21565             }
21566             if (app.serviceb) {
21567                 adj = ProcessList.SERVICE_B_ADJ;
21568             }
21569         }
21570
21571         app.curRawAdj = adj;
21572
21573         //Slog.i(TAG, "OOM ADJ " + app + ": pid=" + app.pid +
21574         //      " adj=" + adj + " curAdj=" + app.curAdj + " maxAdj=" + app.maxAdj);
21575         if (adj > app.maxAdj) {
21576             adj = app.maxAdj;
21577             if (app.maxAdj <= ProcessList.PERCEPTIBLE_APP_ADJ) {
21578                 schedGroup = ProcessList.SCHED_GROUP_DEFAULT;
21579             }
21580         }
21581
21582         // Do final modification to adj.  Everything we do between here and applying
21583         // the final setAdj must be done in this function, because we will also use
21584         // it when computing the final cached adj later.  Note that we don't need to
21585         // worry about this for max adj above, since max adj will always be used to
21586         // keep it out of the cached vaues.
21587         app.curAdj = app.modifyRawOomAdj(adj);
21588         app.curSchedGroup = schedGroup;
21589         app.curProcState = procState;
21590         app.foregroundActivities = foregroundActivities;
21591
21592         return app.curRawAdj;
21593     }
21594
21595     /**
21596      * Record new PSS sample for a process.
21597      */
21598     void recordPssSampleLocked(ProcessRecord proc, int procState, long pss, long uss, long swapPss,
21599             long now) {
21600         EventLogTags.writeAmPss(proc.pid, proc.uid, proc.processName, pss * 1024, uss * 1024,
21601                 swapPss * 1024);
21602         proc.lastPssTime = now;
21603         proc.baseProcessTracker.addPss(pss, uss, true, proc.pkgList);
21604         if (DEBUG_PSS) Slog.d(TAG_PSS,
21605                 "PSS of " + proc.toShortString() + ": " + pss + " lastPss=" + proc.lastPss
21606                 + " state=" + ProcessList.makeProcStateString(procState));
21607         if (proc.initialIdlePss == 0) {
21608             proc.initialIdlePss = pss;
21609         }
21610         proc.lastPss = pss;
21611         proc.lastSwapPss = swapPss;
21612         if (procState >= ActivityManager.PROCESS_STATE_HOME) {
21613             proc.lastCachedPss = pss;
21614             proc.lastCachedSwapPss = swapPss;
21615         }
21616
21617         final SparseArray<Pair<Long, String>> watchUids
21618                 = mMemWatchProcesses.getMap().get(proc.processName);
21619         Long check = null;
21620         if (watchUids != null) {
21621             Pair<Long, String> val = watchUids.get(proc.uid);
21622             if (val == null) {
21623                 val = watchUids.get(0);
21624             }
21625             if (val != null) {
21626                 check = val.first;
21627             }
21628         }
21629         if (check != null) {
21630             if ((pss * 1024) >= check && proc.thread != null && mMemWatchDumpProcName == null) {
21631                 boolean isDebuggable = "1".equals(SystemProperties.get(SYSTEM_DEBUGGABLE, "0"));
21632                 if (!isDebuggable) {
21633                     if ((proc.info.flags&ApplicationInfo.FLAG_DEBUGGABLE) != 0) {
21634                         isDebuggable = true;
21635                     }
21636                 }
21637                 if (isDebuggable) {
21638                     Slog.w(TAG, "Process " + proc + " exceeded pss limit " + check + "; reporting");
21639                     final ProcessRecord myProc = proc;
21640                     final File heapdumpFile = DumpHeapProvider.getJavaFile();
21641                     mMemWatchDumpProcName = proc.processName;
21642                     mMemWatchDumpFile = heapdumpFile.toString();
21643                     mMemWatchDumpPid = proc.pid;
21644                     mMemWatchDumpUid = proc.uid;
21645                     BackgroundThread.getHandler().post(new Runnable() {
21646                         @Override
21647                         public void run() {
21648                             revokeUriPermission(ActivityThread.currentActivityThread()
21649                                             .getApplicationThread(),
21650                                     null, DumpHeapActivity.JAVA_URI,
21651                                     Intent.FLAG_GRANT_READ_URI_PERMISSION
21652                                             | Intent.FLAG_GRANT_WRITE_URI_PERMISSION,
21653                                     UserHandle.myUserId());
21654                             ParcelFileDescriptor fd = null;
21655                             try {
21656                                 heapdumpFile.delete();
21657                                 fd = ParcelFileDescriptor.open(heapdumpFile,
21658                                         ParcelFileDescriptor.MODE_CREATE |
21659                                                 ParcelFileDescriptor.MODE_TRUNCATE |
21660                                                 ParcelFileDescriptor.MODE_WRITE_ONLY |
21661                                                 ParcelFileDescriptor.MODE_APPEND);
21662                                 IApplicationThread thread = myProc.thread;
21663                                 if (thread != null) {
21664                                     try {
21665                                         if (DEBUG_PSS) Slog.d(TAG_PSS,
21666                                                 "Requesting dump heap from "
21667                                                 + myProc + " to " + heapdumpFile);
21668                                         thread.dumpHeap(true, heapdumpFile.toString(), fd);
21669                                     } catch (RemoteException e) {
21670                                     }
21671                                 }
21672                             } catch (FileNotFoundException e) {
21673                                 e.printStackTrace();
21674                             } finally {
21675                                 if (fd != null) {
21676                                     try {
21677                                         fd.close();
21678                                     } catch (IOException e) {
21679                                     }
21680                                 }
21681                             }
21682                         }
21683                     });
21684                 } else {
21685                     Slog.w(TAG, "Process " + proc + " exceeded pss limit " + check
21686                             + ", but debugging not enabled");
21687                 }
21688             }
21689         }
21690     }
21691
21692     /**
21693      * Schedule PSS collection of a process.
21694      */
21695     void requestPssLocked(ProcessRecord proc, int procState) {
21696         if (mPendingPssProcesses.contains(proc)) {
21697             return;
21698         }
21699         if (mPendingPssProcesses.size() == 0) {
21700             mBgHandler.sendEmptyMessage(COLLECT_PSS_BG_MSG);
21701         }
21702         if (DEBUG_PSS) Slog.d(TAG_PSS, "Requesting PSS of: " + proc);
21703         proc.pssProcState = procState;
21704         mPendingPssProcesses.add(proc);
21705     }
21706
21707     /**
21708      * Schedule PSS collection of all processes.
21709      */
21710     void requestPssAllProcsLocked(long now, boolean always, boolean memLowered) {
21711         if (!always) {
21712             if (now < (mLastFullPssTime +
21713                     (memLowered ? mConstants.FULL_PSS_LOWERED_INTERVAL
21714                             : mConstants.FULL_PSS_MIN_INTERVAL))) {
21715                 return;
21716             }
21717         }
21718         if (DEBUG_PSS) Slog.d(TAG_PSS, "Requesting PSS of all procs!  memLowered=" + memLowered);
21719         mLastFullPssTime = now;
21720         mFullPssPending = true;
21721         mPendingPssProcesses.ensureCapacity(mLruProcesses.size());
21722         mPendingPssProcesses.clear();
21723         for (int i = mLruProcesses.size() - 1; i >= 0; i--) {
21724             ProcessRecord app = mLruProcesses.get(i);
21725             if (app.thread == null
21726                     || app.curProcState == ActivityManager.PROCESS_STATE_NONEXISTENT) {
21727                 continue;
21728             }
21729             if (memLowered || now > (app.lastStateTime+ProcessList.PSS_ALL_INTERVAL)) {
21730                 app.pssProcState = app.setProcState;
21731                 app.nextPssTime = ProcessList.computeNextPssTime(app.curProcState, true,
21732                         mTestPssMode, isSleepingLocked(), now);
21733                 mPendingPssProcesses.add(app);
21734             }
21735         }
21736         mBgHandler.sendEmptyMessage(COLLECT_PSS_BG_MSG);
21737     }
21738
21739     public void setTestPssMode(boolean enabled) {
21740         synchronized (this) {
21741             mTestPssMode = enabled;
21742             if (enabled) {
21743                 // Whenever we enable the mode, we want to take a snapshot all of current
21744                 // process mem use.
21745                 requestPssAllProcsLocked(SystemClock.uptimeMillis(), true, true);
21746             }
21747         }
21748     }
21749
21750     /**
21751      * Ask a given process to GC right now.
21752      */
21753     final void performAppGcLocked(ProcessRecord app) {
21754         try {
21755             app.lastRequestedGc = SystemClock.uptimeMillis();
21756             if (app.thread != null) {
21757                 if (app.reportLowMemory) {
21758                     app.reportLowMemory = false;
21759                     app.thread.scheduleLowMemory();
21760                 } else {
21761                     app.thread.processInBackground();
21762                 }
21763             }
21764         } catch (Exception e) {
21765             // whatever.
21766         }
21767     }
21768
21769     /**
21770      * Returns true if things are idle enough to perform GCs.
21771      */
21772     private final boolean canGcNowLocked() {
21773         boolean processingBroadcasts = false;
21774         for (BroadcastQueue q : mBroadcastQueues) {
21775             if (q.mParallelBroadcasts.size() != 0 || q.mOrderedBroadcasts.size() != 0) {
21776                 processingBroadcasts = true;
21777             }
21778         }
21779         return !processingBroadcasts
21780                 && (isSleepingLocked() || mStackSupervisor.allResumedActivitiesIdle());
21781     }
21782
21783     /**
21784      * Perform GCs on all processes that are waiting for it, but only
21785      * if things are idle.
21786      */
21787     final void performAppGcsLocked() {
21788         final int N = mProcessesToGc.size();
21789         if (N <= 0) {
21790             return;
21791         }
21792         if (canGcNowLocked()) {
21793             while (mProcessesToGc.size() > 0) {
21794                 ProcessRecord proc = mProcessesToGc.remove(0);
21795                 if (proc.curRawAdj > ProcessList.PERCEPTIBLE_APP_ADJ || proc.reportLowMemory) {
21796                     if ((proc.lastRequestedGc+mConstants.GC_MIN_INTERVAL)
21797                             <= SystemClock.uptimeMillis()) {
21798                         // To avoid spamming the system, we will GC processes one
21799                         // at a time, waiting a few seconds between each.
21800                         performAppGcLocked(proc);
21801                         scheduleAppGcsLocked();
21802                         return;
21803                     } else {
21804                         // It hasn't been long enough since we last GCed this
21805                         // process...  put it in the list to wait for its time.
21806                         addProcessToGcListLocked(proc);
21807                         break;
21808                     }
21809                 }
21810             }
21811
21812             scheduleAppGcsLocked();
21813         }
21814     }
21815
21816     /**
21817      * If all looks good, perform GCs on all processes waiting for them.
21818      */
21819     final void performAppGcsIfAppropriateLocked() {
21820         if (canGcNowLocked()) {
21821             performAppGcsLocked();
21822             return;
21823         }
21824         // Still not idle, wait some more.
21825         scheduleAppGcsLocked();
21826     }
21827
21828     /**
21829      * Schedule the execution of all pending app GCs.
21830      */
21831     final void scheduleAppGcsLocked() {
21832         mHandler.removeMessages(GC_BACKGROUND_PROCESSES_MSG);
21833
21834         if (mProcessesToGc.size() > 0) {
21835             // Schedule a GC for the time to the next process.
21836             ProcessRecord proc = mProcessesToGc.get(0);
21837             Message msg = mHandler.obtainMessage(GC_BACKGROUND_PROCESSES_MSG);
21838
21839             long when = proc.lastRequestedGc + mConstants.GC_MIN_INTERVAL;
21840             long now = SystemClock.uptimeMillis();
21841             if (when < (now+mConstants.GC_TIMEOUT)) {
21842                 when = now + mConstants.GC_TIMEOUT;
21843             }
21844             mHandler.sendMessageAtTime(msg, when);
21845         }
21846     }
21847
21848     /**
21849      * Add a process to the array of processes waiting to be GCed.  Keeps the
21850      * list in sorted order by the last GC time.  The process can't already be
21851      * on the list.
21852      */
21853     final void addProcessToGcListLocked(ProcessRecord proc) {
21854         boolean added = false;
21855         for (int i=mProcessesToGc.size()-1; i>=0; i--) {
21856             if (mProcessesToGc.get(i).lastRequestedGc <
21857                     proc.lastRequestedGc) {
21858                 added = true;
21859                 mProcessesToGc.add(i+1, proc);
21860                 break;
21861             }
21862         }
21863         if (!added) {
21864             mProcessesToGc.add(0, proc);
21865         }
21866     }
21867
21868     /**
21869      * Set up to ask a process to GC itself.  This will either do it
21870      * immediately, or put it on the list of processes to gc the next
21871      * time things are idle.
21872      */
21873     final void scheduleAppGcLocked(ProcessRecord app) {
21874         long now = SystemClock.uptimeMillis();
21875         if ((app.lastRequestedGc+mConstants.GC_MIN_INTERVAL) > now) {
21876             return;
21877         }
21878         if (!mProcessesToGc.contains(app)) {
21879             addProcessToGcListLocked(app);
21880             scheduleAppGcsLocked();
21881         }
21882     }
21883
21884     final void checkExcessivePowerUsageLocked(boolean doKills) {
21885         updateCpuStatsNow();
21886
21887         BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
21888         boolean doWakeKills = doKills;
21889         boolean doCpuKills = doKills;
21890         if (mLastPowerCheckRealtime == 0) {
21891             doWakeKills = false;
21892         }
21893         if (mLastPowerCheckUptime == 0) {
21894             doCpuKills = false;
21895         }
21896         if (stats.isScreenOn()) {
21897             doWakeKills = false;
21898         }
21899         final long curRealtime = SystemClock.elapsedRealtime();
21900         final long realtimeSince = curRealtime - mLastPowerCheckRealtime;
21901         final long curUptime = SystemClock.uptimeMillis();
21902         final long uptimeSince = curUptime - mLastPowerCheckUptime;
21903         mLastPowerCheckRealtime = curRealtime;
21904         mLastPowerCheckUptime = curUptime;
21905         if (realtimeSince < mConstants.WAKE_LOCK_MIN_CHECK_DURATION) {
21906             doWakeKills = false;
21907         }
21908         if (uptimeSince < mConstants.CPU_MIN_CHECK_DURATION) {
21909             doCpuKills = false;
21910         }
21911         int i = mLruProcesses.size();
21912         while (i > 0) {
21913             i--;
21914             ProcessRecord app = mLruProcesses.get(i);
21915             if (app.setProcState >= ActivityManager.PROCESS_STATE_HOME) {
21916                 long wtime;
21917                 synchronized (stats) {
21918                     wtime = stats.getProcessWakeTime(app.info.uid,
21919                             app.pid, curRealtime);
21920                 }
21921                 long wtimeUsed = wtime - app.lastWakeTime;
21922                 long cputimeUsed = app.curCpuTime - app.lastCpuTime;
21923                 if (DEBUG_POWER) {
21924                     StringBuilder sb = new StringBuilder(128);
21925                     sb.append("Wake for ");
21926                     app.toShortString(sb);
21927                     sb.append(": over ");
21928                     TimeUtils.formatDuration(realtimeSince, sb);
21929                     sb.append(" used ");
21930                     TimeUtils.formatDuration(wtimeUsed, sb);
21931                     sb.append(" (");
21932                     sb.append((wtimeUsed*100)/realtimeSince);
21933                     sb.append("%)");
21934                     Slog.i(TAG_POWER, sb.toString());
21935                     sb.setLength(0);
21936                     sb.append("CPU for ");
21937                     app.toShortString(sb);
21938                     sb.append(": over ");
21939                     TimeUtils.formatDuration(uptimeSince, sb);
21940                     sb.append(" used ");
21941                     TimeUtils.formatDuration(cputimeUsed, sb);
21942                     sb.append(" (");
21943                     sb.append((cputimeUsed*100)/uptimeSince);
21944                     sb.append("%)");
21945                     Slog.i(TAG_POWER, sb.toString());
21946                 }
21947                 // If a process has held a wake lock for more
21948                 // than 50% of the time during this period,
21949                 // that sounds bad.  Kill!
21950                 if (doWakeKills && realtimeSince > 0
21951                         && ((wtimeUsed*100)/realtimeSince) >= 50) {
21952                     synchronized (stats) {
21953                         stats.reportExcessiveWakeLocked(app.info.uid, app.processName,
21954                                 realtimeSince, wtimeUsed);
21955                     }
21956                     app.kill("excessive wake held " + wtimeUsed + " during " + realtimeSince, true);
21957                     app.baseProcessTracker.reportExcessiveWake(app.pkgList);
21958                 } else if (doCpuKills && uptimeSince > 0
21959                         && ((cputimeUsed*100)/uptimeSince) >= 25) {
21960                     synchronized (stats) {
21961                         stats.reportExcessiveCpuLocked(app.info.uid, app.processName,
21962                                 uptimeSince, cputimeUsed);
21963                     }
21964                     app.kill("excessive cpu " + cputimeUsed + " during " + uptimeSince, true);
21965                     app.baseProcessTracker.reportExcessiveCpu(app.pkgList);
21966                 } else {
21967                     app.lastWakeTime = wtime;
21968                     app.lastCpuTime = app.curCpuTime;
21969                 }
21970             }
21971         }
21972     }
21973
21974     private final boolean applyOomAdjLocked(ProcessRecord app, boolean doingAll, long now,
21975             long nowElapsed) {
21976         boolean success = true;
21977
21978         if (app.curRawAdj != app.setRawAdj) {
21979             app.setRawAdj = app.curRawAdj;
21980         }
21981
21982         int changes = 0;
21983
21984         if (app.curAdj != app.setAdj) {
21985             ProcessList.setOomAdj(app.pid, app.info.uid, app.curAdj);
21986             if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG_OOM_ADJ,
21987                     "Set " + app.pid + " " + app.processName + " adj " + app.curAdj + ": "
21988                     + app.adjType);
21989             app.setAdj = app.curAdj;
21990             app.verifiedAdj = ProcessList.INVALID_ADJ;
21991         }
21992
21993         if (app.setSchedGroup != app.curSchedGroup) {
21994             int oldSchedGroup = app.setSchedGroup;
21995             app.setSchedGroup = app.curSchedGroup;
21996             if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG_OOM_ADJ,
21997                     "Setting sched group of " + app.processName
21998                     + " to " + app.curSchedGroup);
21999             if (app.waitingToKill != null && app.curReceivers.isEmpty()
22000                     && app.setSchedGroup == ProcessList.SCHED_GROUP_BACKGROUND) {
22001                 app.kill(app.waitingToKill, true);
22002                 success = false;
22003             } else {
22004                 int processGroup;
22005                 switch (app.curSchedGroup) {
22006                     case ProcessList.SCHED_GROUP_BACKGROUND:
22007                         processGroup = THREAD_GROUP_BG_NONINTERACTIVE;
22008                         break;
22009                     case ProcessList.SCHED_GROUP_TOP_APP:
22010                     case ProcessList.SCHED_GROUP_TOP_APP_BOUND:
22011                         processGroup = THREAD_GROUP_TOP_APP;
22012                         break;
22013                     default:
22014                         processGroup = THREAD_GROUP_DEFAULT;
22015                         break;
22016                 }
22017                 long oldId = Binder.clearCallingIdentity();
22018                 try {
22019                     setProcessGroup(app.pid, processGroup);
22020                     if (app.curSchedGroup == ProcessList.SCHED_GROUP_TOP_APP) {
22021                         // do nothing if we already switched to RT
22022                         if (oldSchedGroup != ProcessList.SCHED_GROUP_TOP_APP) {
22023                             mVrController.onTopProcChangedLocked(app);
22024                             if (mUseFifoUiScheduling) {
22025                                 // Switch UI pipeline for app to SCHED_FIFO
22026                                 app.savedPriority = Process.getThreadPriority(app.pid);
22027                                 scheduleAsFifoPriority(app.pid, /* suppressLogs */true);
22028                                 if (app.renderThreadTid != 0) {
22029                                     scheduleAsFifoPriority(app.renderThreadTid,
22030                                         /* suppressLogs */true);
22031                                     if (DEBUG_OOM_ADJ) {
22032                                         Slog.d("UI_FIFO", "Set RenderThread (TID " +
22033                                             app.renderThreadTid + ") to FIFO");
22034                                     }
22035                                 } else {
22036                                     if (DEBUG_OOM_ADJ) {
22037                                         Slog.d("UI_FIFO", "Not setting RenderThread TID");
22038                                     }
22039                                 }
22040                             } else {
22041                                 // Boost priority for top app UI and render threads
22042                                 setThreadPriority(app.pid, TOP_APP_PRIORITY_BOOST);
22043                                 if (app.renderThreadTid != 0) {
22044                                     try {
22045                                         setThreadPriority(app.renderThreadTid,
22046                                                 TOP_APP_PRIORITY_BOOST);
22047                                     } catch (IllegalArgumentException e) {
22048                                         // thread died, ignore
22049                                     }
22050                                 }
22051                             }
22052                         }
22053                     } else if (oldSchedGroup == ProcessList.SCHED_GROUP_TOP_APP &&
22054                                app.curSchedGroup != ProcessList.SCHED_GROUP_TOP_APP) {
22055                         mVrController.onTopProcChangedLocked(app);
22056                         if (mUseFifoUiScheduling) {
22057                             // Reset UI pipeline to SCHED_OTHER
22058                             setThreadScheduler(app.pid, SCHED_OTHER, 0);
22059                             setThreadPriority(app.pid, app.savedPriority);
22060                             if (app.renderThreadTid != 0) {
22061                                 setThreadScheduler(app.renderThreadTid,
22062                                     SCHED_OTHER, 0);
22063                                 setThreadPriority(app.renderThreadTid, -4);
22064                             }
22065                         } else {
22066                             // Reset priority for top app UI and render threads
22067                             setThreadPriority(app.pid, 0);
22068                             if (app.renderThreadTid != 0) {
22069                                 setThreadPriority(app.renderThreadTid, 0);
22070                             }
22071                         }
22072                     }
22073                 } catch (Exception e) {
22074                     if (false) {
22075                         Slog.w(TAG, "Failed setting process group of " + app.pid
22076                                 + " to " + app.curSchedGroup);
22077                         Slog.w(TAG, "at location", e);
22078                     }
22079                 } finally {
22080                     Binder.restoreCallingIdentity(oldId);
22081                 }
22082             }
22083         }
22084         if (app.repForegroundActivities != app.foregroundActivities) {
22085             app.repForegroundActivities = app.foregroundActivities;
22086             changes |= ProcessChangeItem.CHANGE_ACTIVITIES;
22087         }
22088         if (app.repProcState != app.curProcState) {
22089             app.repProcState = app.curProcState;
22090             if (app.thread != null) {
22091                 try {
22092                     if (false) {
22093                         //RuntimeException h = new RuntimeException("here");
22094                         Slog.i(TAG, "Sending new process state " + app.repProcState
22095                                 + " to " + app /*, h*/);
22096                     }
22097                     app.thread.setProcessState(app.repProcState);
22098                 } catch (RemoteException e) {
22099                 }
22100             }
22101         }
22102         if (app.setProcState == ActivityManager.PROCESS_STATE_NONEXISTENT
22103                 || ProcessList.procStatesDifferForMem(app.curProcState, app.setProcState)) {
22104             if (false && mTestPssMode && app.setProcState >= 0 && app.lastStateTime <= (now-200)) {
22105                 // Experimental code to more aggressively collect pss while
22106                 // running test...  the problem is that this tends to collect
22107                 // the data right when a process is transitioning between process
22108                 // states, which well tend to give noisy data.
22109                 long start = SystemClock.uptimeMillis();
22110                 long pss = Debug.getPss(app.pid, mTmpLong, null);
22111                 recordPssSampleLocked(app, app.curProcState, pss, mTmpLong[0], mTmpLong[1], now);
22112                 mPendingPssProcesses.remove(app);
22113                 Slog.i(TAG, "Recorded pss for " + app + " state " + app.setProcState
22114                         + " to " + app.curProcState + ": "
22115                         + (SystemClock.uptimeMillis()-start) + "ms");
22116             }
22117             app.lastStateTime = now;
22118             app.nextPssTime = ProcessList.computeNextPssTime(app.curProcState, true,
22119                     mTestPssMode, isSleepingLocked(), now);
22120             if (DEBUG_PSS) Slog.d(TAG_PSS, "Process state change from "
22121                     + ProcessList.makeProcStateString(app.setProcState) + " to "
22122                     + ProcessList.makeProcStateString(app.curProcState) + " next pss in "
22123                     + (app.nextPssTime-now) + ": " + app);
22124         } else {
22125             if (now > app.nextPssTime || (now > (app.lastPssTime+ProcessList.PSS_MAX_INTERVAL)
22126                     && now > (app.lastStateTime+ProcessList.minTimeFromStateChange(
22127                     mTestPssMode)))) {
22128                 requestPssLocked(app, app.setProcState);
22129                 app.nextPssTime = ProcessList.computeNextPssTime(app.curProcState, false,
22130                         mTestPssMode, isSleepingLocked(), now);
22131             } else if (false && DEBUG_PSS) Slog.d(TAG_PSS,
22132                     "Not requesting PSS of " + app + ": next=" + (app.nextPssTime-now));
22133         }
22134         if (app.setProcState != app.curProcState) {
22135             if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG_OOM_ADJ,
22136                     "Proc state change of " + app.processName
22137                             + " to " + app.curProcState);
22138             boolean setImportant = app.setProcState < ActivityManager.PROCESS_STATE_SERVICE;
22139             boolean curImportant = app.curProcState < ActivityManager.PROCESS_STATE_SERVICE;
22140             if (setImportant && !curImportant) {
22141                 // This app is no longer something we consider important enough to allow to
22142                 // use arbitrary amounts of battery power.  Note
22143                 // its current wake lock time to later know to kill it if
22144                 // it is not behaving well.
22145                 BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
22146                 synchronized (stats) {
22147                     app.lastWakeTime = stats.getProcessWakeTime(app.info.uid,
22148                             app.pid, nowElapsed);
22149                 }
22150                 app.lastCpuTime = app.curCpuTime;
22151
22152             }
22153             // Inform UsageStats of important process state change
22154             // Must be called before updating setProcState
22155             maybeUpdateUsageStatsLocked(app, nowElapsed);
22156
22157             app.setProcState = app.curProcState;
22158             if (app.setProcState >= ActivityManager.PROCESS_STATE_HOME) {
22159                 app.notCachedSinceIdle = false;
22160             }
22161             if (!doingAll) {
22162                 setProcessTrackerStateLocked(app, mProcessStats.getMemFactorLocked(), now);
22163             } else {
22164                 app.procStateChanged = true;
22165             }
22166         } else if (app.reportedInteraction && (nowElapsed-app.interactionEventTime)
22167                 > mConstants.USAGE_STATS_INTERACTION_INTERVAL) {
22168             // For apps that sit around for a long time in the interactive state, we need
22169             // to report this at least once a day so they don't go idle.
22170             maybeUpdateUsageStatsLocked(app, nowElapsed);
22171         }
22172
22173         if (changes != 0) {
22174             if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG_PROCESS_OBSERVERS,
22175                     "Changes in " + app + ": " + changes);
22176             int i = mPendingProcessChanges.size()-1;
22177             ProcessChangeItem item = null;
22178             while (i >= 0) {
22179                 item = mPendingProcessChanges.get(i);
22180                 if (item.pid == app.pid) {
22181                     if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG_PROCESS_OBSERVERS,
22182                             "Re-using existing item: " + item);
22183                     break;
22184                 }
22185                 i--;
22186             }
22187             if (i < 0) {
22188                 // No existing item in pending changes; need a new one.
22189                 final int NA = mAvailProcessChanges.size();
22190                 if (NA > 0) {
22191                     item = mAvailProcessChanges.remove(NA-1);
22192                     if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG_PROCESS_OBSERVERS,
22193                             "Retrieving available item: " + item);
22194                 } else {
22195                     item = new ProcessChangeItem();
22196                     if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG_PROCESS_OBSERVERS,
22197                             "Allocating new item: " + item);
22198                 }
22199                 item.changes = 0;
22200                 item.pid = app.pid;
22201                 item.uid = app.info.uid;
22202                 if (mPendingProcessChanges.size() == 0) {
22203                     if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG_PROCESS_OBSERVERS,
22204                             "*** Enqueueing dispatch processes changed!");
22205                     mUiHandler.obtainMessage(DISPATCH_PROCESSES_CHANGED_UI_MSG).sendToTarget();
22206                 }
22207                 mPendingProcessChanges.add(item);
22208             }
22209             item.changes |= changes;
22210             item.foregroundActivities = app.repForegroundActivities;
22211             if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG_PROCESS_OBSERVERS,
22212                     "Item " + Integer.toHexString(System.identityHashCode(item))
22213                     + " " + app.toShortString() + ": changes=" + item.changes
22214                     + " foreground=" + item.foregroundActivities
22215                     + " type=" + app.adjType + " source=" + app.adjSource
22216                     + " target=" + app.adjTarget);
22217         }
22218
22219         return success;
22220     }
22221
22222     private boolean isEphemeralLocked(int uid) {
22223         String packages[] = mContext.getPackageManager().getPackagesForUid(uid);
22224         if (packages == null || packages.length != 1) { // Ephemeral apps cannot share uid
22225             return false;
22226         }
22227         return getPackageManagerInternalLocked().isPackageEphemeral(UserHandle.getUserId(uid),
22228                 packages[0]);
22229     }
22230
22231     @VisibleForTesting
22232     final void enqueueUidChangeLocked(UidRecord uidRec, int uid, int change) {
22233         final UidRecord.ChangeItem pendingChange;
22234         if (uidRec == null || uidRec.pendingChange == null) {
22235             if (mPendingUidChanges.size() == 0) {
22236                 if (DEBUG_UID_OBSERVERS) Slog.i(TAG_UID_OBSERVERS,
22237                         "*** Enqueueing dispatch uid changed!");
22238                 mUiHandler.obtainMessage(DISPATCH_UIDS_CHANGED_UI_MSG).sendToTarget();
22239             }
22240             final int NA = mAvailUidChanges.size();
22241             if (NA > 0) {
22242                 pendingChange = mAvailUidChanges.remove(NA-1);
22243                 if (DEBUG_UID_OBSERVERS) Slog.i(TAG_UID_OBSERVERS,
22244                         "Retrieving available item: " + pendingChange);
22245             } else {
22246                 pendingChange = new UidRecord.ChangeItem();
22247                 if (DEBUG_UID_OBSERVERS) Slog.i(TAG_UID_OBSERVERS,
22248                         "Allocating new item: " + pendingChange);
22249             }
22250             if (uidRec != null) {
22251                 uidRec.pendingChange = pendingChange;
22252                 if (change == UidRecord.CHANGE_GONE && !uidRec.idle) {
22253                     // If this uid is going away, and we haven't yet reported it is gone,
22254                     // then do so now.
22255                     change = UidRecord.CHANGE_GONE_IDLE;
22256                 }
22257             } else if (uid < 0) {
22258                 throw new IllegalArgumentException("No UidRecord or uid");
22259             }
22260             pendingChange.uidRecord = uidRec;
22261             pendingChange.uid = uidRec != null ? uidRec.uid : uid;
22262             mPendingUidChanges.add(pendingChange);
22263         } else {
22264             pendingChange = uidRec.pendingChange;
22265             if (change == UidRecord.CHANGE_GONE && pendingChange.change == UidRecord.CHANGE_IDLE) {
22266                 change = UidRecord.CHANGE_GONE_IDLE;
22267             }
22268         }
22269         pendingChange.change = change;
22270         pendingChange.processState = uidRec != null
22271                 ? uidRec.setProcState : ActivityManager.PROCESS_STATE_NONEXISTENT;
22272         pendingChange.ephemeral = uidRec != null ? uidRec.ephemeral : isEphemeralLocked(uid);
22273         pendingChange.procStateSeq = uidRec != null ? uidRec.curProcStateSeq : 0;
22274         if (uidRec != null) {
22275             uidRec.updateLastDispatchedProcStateSeq(change);
22276         }
22277
22278         // Directly update the power manager, since we sit on top of it and it is critical
22279         // it be kept in sync (so wake locks will be held as soon as appropriate).
22280         if (mLocalPowerManager != null) {
22281             switch (change) {
22282                 case UidRecord.CHANGE_GONE:
22283                 case UidRecord.CHANGE_GONE_IDLE:
22284                     mLocalPowerManager.uidGone(pendingChange.uid);
22285                     break;
22286                 case UidRecord.CHANGE_IDLE:
22287                     mLocalPowerManager.uidIdle(pendingChange.uid);
22288                     break;
22289                 case UidRecord.CHANGE_ACTIVE:
22290                     mLocalPowerManager.uidActive(pendingChange.uid);
22291                     break;
22292                 default:
22293                     mLocalPowerManager.updateUidProcState(pendingChange.uid,
22294                             pendingChange.processState);
22295                     break;
22296             }
22297         }
22298     }
22299
22300     private void maybeUpdateProviderUsageStatsLocked(ProcessRecord app, String providerPkgName,
22301             String authority) {
22302         if (app == null) return;
22303         if (app.curProcState <= ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND) {
22304             UserState userState = mUserController.getStartedUserStateLocked(app.userId);
22305             if (userState == null) return;
22306             final long now = SystemClock.elapsedRealtime();
22307             Long lastReported = userState.mProviderLastReportedFg.get(authority);
22308             if (lastReported == null || lastReported < now - 60 * 1000L) {
22309                 if (mSystemReady) {
22310                     // Cannot touch the user stats if not system ready
22311                     mUsageStatsService.reportContentProviderUsage(
22312                             authority, providerPkgName, app.userId);
22313                 }
22314                 userState.mProviderLastReportedFg.put(authority, now);
22315             }
22316         }
22317     }
22318
22319     private void maybeUpdateUsageStatsLocked(ProcessRecord app, long nowElapsed) {
22320         if (DEBUG_USAGE_STATS) {
22321             Slog.d(TAG, "Checking proc [" + Arrays.toString(app.getPackageList())
22322                     + "] state changes: old = " + app.setProcState + ", new = "
22323                     + app.curProcState);
22324         }
22325         if (mUsageStatsService == null) {
22326             return;
22327         }
22328         boolean isInteraction;
22329         // To avoid some abuse patterns, we are going to be careful about what we consider
22330         // to be an app interaction.  Being the top activity doesn't count while the display
22331         // is sleeping, nor do short foreground services.
22332         if (app.curProcState <= ActivityManager.PROCESS_STATE_BOUND_FOREGROUND_SERVICE) {
22333             isInteraction = true;
22334             app.fgInteractionTime = 0;
22335         } else if (app.curProcState <= ActivityManager.PROCESS_STATE_TOP_SLEEPING) {
22336             if (app.fgInteractionTime == 0) {
22337                 app.fgInteractionTime = nowElapsed;
22338                 isInteraction = false;
22339             } else {
22340                 isInteraction = nowElapsed > app.fgInteractionTime
22341                         + mConstants.SERVICE_USAGE_INTERACTION_TIME;
22342             }
22343         } else {
22344             isInteraction = app.curProcState <= ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND;
22345             app.fgInteractionTime = 0;
22346         }
22347         if (isInteraction && (!app.reportedInteraction || (nowElapsed-app.interactionEventTime)
22348                 > mConstants.USAGE_STATS_INTERACTION_INTERVAL)) {
22349             app.interactionEventTime = nowElapsed;
22350             String[] packages = app.getPackageList();
22351             if (packages != null) {
22352                 for (int i = 0; i < packages.length; i++) {
22353                     mUsageStatsService.reportEvent(packages[i], app.userId,
22354                             UsageEvents.Event.SYSTEM_INTERACTION);
22355                 }
22356             }
22357         }
22358         app.reportedInteraction = isInteraction;
22359         if (!isInteraction) {
22360             app.interactionEventTime = 0;
22361         }
22362     }
22363
22364     private final void setProcessTrackerStateLocked(ProcessRecord proc, int memFactor, long now) {
22365         if (proc.thread != null) {
22366             if (proc.baseProcessTracker != null) {
22367                 proc.baseProcessTracker.setState(proc.repProcState, memFactor, now, proc.pkgList);
22368             }
22369         }
22370     }
22371
22372     private final boolean updateOomAdjLocked(ProcessRecord app, int cachedAdj,
22373             ProcessRecord TOP_APP, boolean doingAll, long now) {
22374         if (app.thread == null) {
22375             return false;
22376         }
22377
22378         computeOomAdjLocked(app, cachedAdj, TOP_APP, doingAll, now);
22379
22380         return applyOomAdjLocked(app, doingAll, now, SystemClock.elapsedRealtime());
22381     }
22382
22383     final void updateProcessForegroundLocked(ProcessRecord proc, boolean isForeground,
22384             boolean oomAdj) {
22385         if (isForeground != proc.foregroundServices) {
22386             proc.foregroundServices = isForeground;
22387             ArrayList<ProcessRecord> curProcs = mForegroundPackages.get(proc.info.packageName,
22388                     proc.info.uid);
22389             if (isForeground) {
22390                 if (curProcs == null) {
22391                     curProcs = new ArrayList<ProcessRecord>();
22392                     mForegroundPackages.put(proc.info.packageName, proc.info.uid, curProcs);
22393                 }
22394                 if (!curProcs.contains(proc)) {
22395                     curProcs.add(proc);
22396                     mBatteryStatsService.noteEvent(BatteryStats.HistoryItem.EVENT_FOREGROUND_START,
22397                             proc.info.packageName, proc.info.uid);
22398                 }
22399             } else {
22400                 if (curProcs != null) {
22401                     if (curProcs.remove(proc)) {
22402                         mBatteryStatsService.noteEvent(
22403                                 BatteryStats.HistoryItem.EVENT_FOREGROUND_FINISH,
22404                                 proc.info.packageName, proc.info.uid);
22405                         if (curProcs.size() <= 0) {
22406                             mForegroundPackages.remove(proc.info.packageName, proc.info.uid);
22407                         }
22408                     }
22409                 }
22410             }
22411             if (oomAdj) {
22412                 updateOomAdjLocked();
22413             }
22414         }
22415     }
22416
22417     private final ActivityRecord resumedAppLocked() {
22418         ActivityRecord act = mStackSupervisor.getResumedActivityLocked();
22419         String pkg;
22420         int uid;
22421         if (act != null) {
22422             pkg = act.packageName;
22423             uid = act.info.applicationInfo.uid;
22424         } else {
22425             pkg = null;
22426             uid = -1;
22427         }
22428         // Has the UID or resumed package name changed?
22429         if (uid != mCurResumedUid || (pkg != mCurResumedPackage
22430                 && (pkg == null || !pkg.equals(mCurResumedPackage)))) {
22431             if (mCurResumedPackage != null) {
22432                 mBatteryStatsService.noteEvent(BatteryStats.HistoryItem.EVENT_TOP_FINISH,
22433                         mCurResumedPackage, mCurResumedUid);
22434             }
22435             mCurResumedPackage = pkg;
22436             mCurResumedUid = uid;
22437             if (mCurResumedPackage != null) {
22438                 mBatteryStatsService.noteEvent(BatteryStats.HistoryItem.EVENT_TOP_START,
22439                         mCurResumedPackage, mCurResumedUid);
22440             }
22441         }
22442         return act;
22443     }
22444
22445     /**
22446      * Update OomAdj for a specific process.
22447      * @param app The process to update
22448      * @param oomAdjAll If it's ok to call updateOomAdjLocked() for all running apps
22449      *                  if necessary, or skip.
22450      * @return whether updateOomAdjLocked(app) was successful.
22451      */
22452     final boolean updateOomAdjLocked(ProcessRecord app, boolean oomAdjAll) {
22453         final ActivityRecord TOP_ACT = resumedAppLocked();
22454         final ProcessRecord TOP_APP = TOP_ACT != null ? TOP_ACT.app : null;
22455         final boolean wasCached = app.cached;
22456
22457         mAdjSeq++;
22458
22459         // This is the desired cached adjusment we want to tell it to use.
22460         // If our app is currently cached, we know it, and that is it.  Otherwise,
22461         // we don't know it yet, and it needs to now be cached we will then
22462         // need to do a complete oom adj.
22463         final int cachedAdj = app.curRawAdj >= ProcessList.CACHED_APP_MIN_ADJ
22464                 ? app.curRawAdj : ProcessList.UNKNOWN_ADJ;
22465         boolean success = updateOomAdjLocked(app, cachedAdj, TOP_APP, false,
22466                 SystemClock.uptimeMillis());
22467         if (oomAdjAll
22468                 && (wasCached != app.cached || app.curRawAdj == ProcessList.UNKNOWN_ADJ)) {
22469             // Changed to/from cached state, so apps after it in the LRU
22470             // list may also be changed.
22471             updateOomAdjLocked();
22472         }
22473         return success;
22474     }
22475
22476     final void updateOomAdjLocked() {
22477         final ActivityRecord TOP_ACT = resumedAppLocked();
22478         final ProcessRecord TOP_APP = TOP_ACT != null ? TOP_ACT.app : null;
22479         final long now = SystemClock.uptimeMillis();
22480         final long nowElapsed = SystemClock.elapsedRealtime();
22481         final long oldTime = now - ProcessList.MAX_EMPTY_TIME;
22482         final int N = mLruProcesses.size();
22483
22484         if (false) {
22485             RuntimeException e = new RuntimeException();
22486             e.fillInStackTrace();
22487             Slog.i(TAG, "updateOomAdj: top=" + TOP_ACT, e);
22488         }
22489
22490         // Reset state in all uid records.
22491         for (int i=mActiveUids.size()-1; i>=0; i--) {
22492             final UidRecord uidRec = mActiveUids.valueAt(i);
22493             if (false && DEBUG_UID_OBSERVERS) Slog.i(TAG_UID_OBSERVERS,
22494                     "Starting update of " + uidRec);
22495             uidRec.reset();
22496         }
22497
22498         mStackSupervisor.rankTaskLayersIfNeeded();
22499
22500         mAdjSeq++;
22501         mNewNumServiceProcs = 0;
22502         mNewNumAServiceProcs = 0;
22503
22504         final int emptyProcessLimit = mConstants.CUR_MAX_EMPTY_PROCESSES;
22505         final int cachedProcessLimit = mConstants.CUR_MAX_CACHED_PROCESSES - emptyProcessLimit;
22506
22507         // Let's determine how many processes we have running vs.
22508         // how many slots we have for background processes; we may want
22509         // to put multiple processes in a slot of there are enough of
22510         // them.
22511         int numSlots = (ProcessList.CACHED_APP_MAX_ADJ
22512                 - ProcessList.CACHED_APP_MIN_ADJ + 1) / 2;
22513         int numEmptyProcs = N - mNumNonCachedProcs - mNumCachedHiddenProcs;
22514         if (numEmptyProcs > cachedProcessLimit) {
22515             // If there are more empty processes than our limit on cached
22516             // processes, then use the cached process limit for the factor.
22517             // This ensures that the really old empty processes get pushed
22518             // down to the bottom, so if we are running low on memory we will
22519             // have a better chance at keeping around more cached processes
22520             // instead of a gazillion empty processes.
22521             numEmptyProcs = cachedProcessLimit;
22522         }
22523         int emptyFactor = numEmptyProcs/numSlots;
22524         if (emptyFactor < 1) emptyFactor = 1;
22525         int cachedFactor = (mNumCachedHiddenProcs > 0 ? mNumCachedHiddenProcs : 1)/numSlots;
22526         if (cachedFactor < 1) cachedFactor = 1;
22527         int stepCached = 0;
22528         int stepEmpty = 0;
22529         int numCached = 0;
22530         int numEmpty = 0;
22531         int numTrimming = 0;
22532
22533         mNumNonCachedProcs = 0;
22534         mNumCachedHiddenProcs = 0;
22535
22536         // First update the OOM adjustment for each of the
22537         // application processes based on their current state.
22538         int curCachedAdj = ProcessList.CACHED_APP_MIN_ADJ;
22539         int nextCachedAdj = curCachedAdj+1;
22540         int curEmptyAdj = ProcessList.CACHED_APP_MIN_ADJ;
22541         int nextEmptyAdj = curEmptyAdj+2;
22542         for (int i=N-1; i>=0; i--) {
22543             ProcessRecord app = mLruProcesses.get(i);
22544             if (!app.killedByAm && app.thread != null) {
22545                 app.procStateChanged = false;
22546                 computeOomAdjLocked(app, ProcessList.UNKNOWN_ADJ, TOP_APP, true, now);
22547
22548                 // If we haven't yet assigned the final cached adj
22549                 // to the process, do that now.
22550                 if (app.curAdj >= ProcessList.UNKNOWN_ADJ) {
22551                     switch (app.curProcState) {
22552                         case ActivityManager.PROCESS_STATE_CACHED_ACTIVITY:
22553                         case ActivityManager.PROCESS_STATE_CACHED_ACTIVITY_CLIENT:
22554                             // This process is a cached process holding activities...
22555                             // assign it the next cached value for that type, and then
22556                             // step that cached level.
22557                             app.curRawAdj = curCachedAdj;
22558                             app.curAdj = app.modifyRawOomAdj(curCachedAdj);
22559                             if (DEBUG_LRU && false) Slog.d(TAG_LRU, "Assigning activity LRU #" + i
22560                                     + " adj: " + app.curAdj + " (curCachedAdj=" + curCachedAdj
22561                                     + ")");
22562                             if (curCachedAdj != nextCachedAdj) {
22563                                 stepCached++;
22564                                 if (stepCached >= cachedFactor) {
22565                                     stepCached = 0;
22566                                     curCachedAdj = nextCachedAdj;
22567                                     nextCachedAdj += 2;
22568                                     if (nextCachedAdj > ProcessList.CACHED_APP_MAX_ADJ) {
22569                                         nextCachedAdj = ProcessList.CACHED_APP_MAX_ADJ;
22570                                     }
22571                                 }
22572                             }
22573                             break;
22574                         default:
22575                             // For everything else, assign next empty cached process
22576                             // level and bump that up.  Note that this means that
22577                             // long-running services that have dropped down to the
22578                             // cached level will be treated as empty (since their process
22579                             // state is still as a service), which is what we want.
22580                             app.curRawAdj = curEmptyAdj;
22581                             app.curAdj = app.modifyRawOomAdj(curEmptyAdj);
22582                             if (DEBUG_LRU && false) Slog.d(TAG_LRU, "Assigning empty LRU #" + i
22583                                     + " adj: " + app.curAdj + " (curEmptyAdj=" + curEmptyAdj
22584                                     + ")");
22585                             if (curEmptyAdj != nextEmptyAdj) {
22586                                 stepEmpty++;
22587                                 if (stepEmpty >= emptyFactor) {
22588                                     stepEmpty = 0;
22589                                     curEmptyAdj = nextEmptyAdj;
22590                                     nextEmptyAdj += 2;
22591                                     if (nextEmptyAdj > ProcessList.CACHED_APP_MAX_ADJ) {
22592                                         nextEmptyAdj = ProcessList.CACHED_APP_MAX_ADJ;
22593                                     }
22594                                 }
22595                             }
22596                             break;
22597                     }
22598                 }
22599
22600                 applyOomAdjLocked(app, true, now, nowElapsed);
22601
22602                 // Count the number of process types.
22603                 switch (app.curProcState) {
22604                     case ActivityManager.PROCESS_STATE_CACHED_ACTIVITY:
22605                     case ActivityManager.PROCESS_STATE_CACHED_ACTIVITY_CLIENT:
22606                         mNumCachedHiddenProcs++;
22607                         numCached++;
22608                         if (numCached > cachedProcessLimit) {
22609                             app.kill("cached #" + numCached, true);
22610                         }
22611                         break;
22612                     case ActivityManager.PROCESS_STATE_CACHED_EMPTY:
22613                         if (numEmpty > mConstants.CUR_TRIM_EMPTY_PROCESSES
22614                                 && app.lastActivityTime < oldTime) {
22615                             app.kill("empty for "
22616                                     + ((oldTime + ProcessList.MAX_EMPTY_TIME - app.lastActivityTime)
22617                                     / 1000) + "s", true);
22618                         } else {
22619                             numEmpty++;
22620                             if (numEmpty > emptyProcessLimit) {
22621                                 app.kill("empty #" + numEmpty, true);
22622                             }
22623                         }
22624                         break;
22625                     default:
22626                         mNumNonCachedProcs++;
22627                         break;
22628                 }
22629
22630                 if (app.isolated && app.services.size() <= 0) {
22631                     // If this is an isolated process, and there are no
22632                     // services running in it, then the process is no longer
22633                     // needed.  We agressively kill these because we can by
22634                     // definition not re-use the same process again, and it is
22635                     // good to avoid having whatever code was running in them
22636                     // left sitting around after no longer needed.
22637                     app.kill("isolated not needed", true);
22638                 } else {
22639                     // Keeping this process, update its uid.
22640                     final UidRecord uidRec = app.uidRecord;
22641                     if (uidRec != null) {
22642                         uidRec.ephemeral = app.info.isInstantApp();
22643                         if (uidRec.curProcState > app.curProcState) {
22644                             uidRec.curProcState = app.curProcState;
22645                         }
22646                         if (app.foregroundServices) {
22647                             uidRec.foregroundServices = true;
22648                         }
22649                     }
22650                 }
22651
22652                 if (app.curProcState >= ActivityManager.PROCESS_STATE_HOME
22653                         && !app.killedByAm) {
22654                     numTrimming++;
22655                 }
22656             }
22657         }
22658
22659         incrementProcStateSeqAndNotifyAppsLocked();
22660
22661         mNumServiceProcs = mNewNumServiceProcs;
22662
22663         // Now determine the memory trimming level of background processes.
22664         // Unfortunately we need to start at the back of the list to do this
22665         // properly.  We only do this if the number of background apps we
22666         // are managing to keep around is less than half the maximum we desire;
22667         // if we are keeping a good number around, we'll let them use whatever
22668         // memory they want.
22669         final int numCachedAndEmpty = numCached + numEmpty;
22670         int memFactor;
22671         if (numCached <= mConstants.CUR_TRIM_CACHED_PROCESSES
22672                 && numEmpty <= mConstants.CUR_TRIM_EMPTY_PROCESSES) {
22673             if (numCachedAndEmpty <= ProcessList.TRIM_CRITICAL_THRESHOLD) {
22674                 memFactor = ProcessStats.ADJ_MEM_FACTOR_CRITICAL;
22675             } else if (numCachedAndEmpty <= ProcessList.TRIM_LOW_THRESHOLD) {
22676                 memFactor = ProcessStats.ADJ_MEM_FACTOR_LOW;
22677             } else {
22678                 memFactor = ProcessStats.ADJ_MEM_FACTOR_MODERATE;
22679             }
22680         } else {
22681             memFactor = ProcessStats.ADJ_MEM_FACTOR_NORMAL;
22682         }
22683         // We always allow the memory level to go up (better).  We only allow it to go
22684         // down if we are in a state where that is allowed, *and* the total number of processes
22685         // has gone down since last time.
22686         if (DEBUG_OOM_ADJ) Slog.d(TAG_OOM_ADJ, "oom: memFactor=" + memFactor
22687                 + " last=" + mLastMemoryLevel + " allowLow=" + mAllowLowerMemLevel
22688                 + " numProcs=" + mLruProcesses.size() + " last=" + mLastNumProcesses);
22689         if (memFactor > mLastMemoryLevel) {
22690             if (!mAllowLowerMemLevel || mLruProcesses.size() >= mLastNumProcesses) {
22691                 memFactor = mLastMemoryLevel;
22692                 if (DEBUG_OOM_ADJ) Slog.d(TAG_OOM_ADJ, "Keeping last mem factor!");
22693             }
22694         }
22695         if (memFactor != mLastMemoryLevel) {
22696             EventLogTags.writeAmMemFactor(memFactor, mLastMemoryLevel);
22697         }
22698         mLastMemoryLevel = memFactor;
22699         mLastNumProcesses = mLruProcesses.size();
22700         boolean allChanged = mProcessStats.setMemFactorLocked(memFactor, !isSleepingLocked(), now);
22701         final int trackerMemFactor = mProcessStats.getMemFactorLocked();
22702         if (memFactor != ProcessStats.ADJ_MEM_FACTOR_NORMAL) {
22703             if (mLowRamStartTime == 0) {
22704                 mLowRamStartTime = now;
22705             }
22706             int step = 0;
22707             int fgTrimLevel;
22708             switch (memFactor) {
22709                 case ProcessStats.ADJ_MEM_FACTOR_CRITICAL:
22710                     fgTrimLevel = ComponentCallbacks2.TRIM_MEMORY_RUNNING_CRITICAL;
22711                     break;
22712                 case ProcessStats.ADJ_MEM_FACTOR_LOW:
22713                     fgTrimLevel = ComponentCallbacks2.TRIM_MEMORY_RUNNING_LOW;
22714                     break;
22715                 default:
22716                     fgTrimLevel = ComponentCallbacks2.TRIM_MEMORY_RUNNING_MODERATE;
22717                     break;
22718             }
22719             int factor = numTrimming/3;
22720             int minFactor = 2;
22721             if (mHomeProcess != null) minFactor++;
22722             if (mPreviousProcess != null) minFactor++;
22723             if (factor < minFactor) factor = minFactor;
22724             int curLevel = ComponentCallbacks2.TRIM_MEMORY_COMPLETE;
22725             for (int i=N-1; i>=0; i--) {
22726                 ProcessRecord app = mLruProcesses.get(i);
22727                 if (allChanged || app.procStateChanged) {
22728                     setProcessTrackerStateLocked(app, trackerMemFactor, now);
22729                     app.procStateChanged = false;
22730                 }
22731                 if (app.curProcState >= ActivityManager.PROCESS_STATE_HOME
22732                         && !app.killedByAm) {
22733                     if (app.trimMemoryLevel < curLevel && app.thread != null) {
22734                         try {
22735                             if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG_OOM_ADJ,
22736                                     "Trimming memory of " + app.processName + " to " + curLevel);
22737                             app.thread.scheduleTrimMemory(curLevel);
22738                         } catch (RemoteException e) {
22739                         }
22740                         if (false) {
22741                             // For now we won't do this; our memory trimming seems
22742                             // to be good enough at this point that destroying
22743                             // activities causes more harm than good.
22744                             if (curLevel >= ComponentCallbacks2.TRIM_MEMORY_COMPLETE
22745                                     && app != mHomeProcess && app != mPreviousProcess) {
22746                                 // Need to do this on its own message because the stack may not
22747                                 // be in a consistent state at this point.
22748                                 // For these apps we will also finish their activities
22749                                 // to help them free memory.
22750                                 mStackSupervisor.scheduleDestroyAllActivities(app, "trim");
22751                             }
22752                         }
22753                     }
22754                     app.trimMemoryLevel = curLevel;
22755                     step++;
22756                     if (step >= factor) {
22757                         step = 0;
22758                         switch (curLevel) {
22759                             case ComponentCallbacks2.TRIM_MEMORY_COMPLETE:
22760                                 curLevel = ComponentCallbacks2.TRIM_MEMORY_MODERATE;
22761                                 break;
22762                             case ComponentCallbacks2.TRIM_MEMORY_MODERATE:
22763                                 curLevel = ComponentCallbacks2.TRIM_MEMORY_BACKGROUND;
22764                                 break;
22765                         }
22766                     }
22767                 } else if (app.curProcState == ActivityManager.PROCESS_STATE_HEAVY_WEIGHT) {
22768                     if (app.trimMemoryLevel < ComponentCallbacks2.TRIM_MEMORY_BACKGROUND
22769                             && app.thread != null) {
22770                         try {
22771                             if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG_OOM_ADJ,
22772                                     "Trimming memory of heavy-weight " + app.processName
22773                                     + " to " + ComponentCallbacks2.TRIM_MEMORY_BACKGROUND);
22774                             app.thread.scheduleTrimMemory(
22775                                     ComponentCallbacks2.TRIM_MEMORY_BACKGROUND);
22776                         } catch (RemoteException e) {
22777                         }
22778                     }
22779                     app.trimMemoryLevel = ComponentCallbacks2.TRIM_MEMORY_BACKGROUND;
22780                 } else {
22781                     if ((app.curProcState >= ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND
22782                             || app.systemNoUi) && app.pendingUiClean) {
22783                         // If this application is now in the background and it
22784                         // had done UI, then give it the special trim level to
22785                         // have it free UI resources.
22786                         final int level = ComponentCallbacks2.TRIM_MEMORY_UI_HIDDEN;
22787                         if (app.trimMemoryLevel < level && app.thread != null) {
22788                             try {
22789                                 if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG_OOM_ADJ,
22790                                         "Trimming memory of bg-ui " + app.processName
22791                                         + " to " + level);
22792                                 app.thread.scheduleTrimMemory(level);
22793                             } catch (RemoteException e) {
22794                             }
22795                         }
22796                         app.pendingUiClean = false;
22797                     }
22798                     if (app.trimMemoryLevel < fgTrimLevel && app.thread != null) {
22799                         try {
22800                             if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG_OOM_ADJ,
22801                                     "Trimming memory of fg " + app.processName
22802                                     + " to " + fgTrimLevel);
22803                             app.thread.scheduleTrimMemory(fgTrimLevel);
22804                         } catch (RemoteException e) {
22805                         }
22806                     }
22807                     app.trimMemoryLevel = fgTrimLevel;
22808                 }
22809             }
22810         } else {
22811             if (mLowRamStartTime != 0) {
22812                 mLowRamTimeSinceLastIdle += now - mLowRamStartTime;
22813                 mLowRamStartTime = 0;
22814             }
22815             for (int i=N-1; i>=0; i--) {
22816                 ProcessRecord app = mLruProcesses.get(i);
22817                 if (allChanged || app.procStateChanged) {
22818                     setProcessTrackerStateLocked(app, trackerMemFactor, now);
22819                     app.procStateChanged = false;
22820                 }
22821                 if ((app.curProcState >= ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND
22822                         || app.systemNoUi) && app.pendingUiClean) {
22823                     if (app.trimMemoryLevel < ComponentCallbacks2.TRIM_MEMORY_UI_HIDDEN
22824                             && app.thread != null) {
22825                         try {
22826                             if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG_OOM_ADJ,
22827                                     "Trimming memory of ui hidden " + app.processName
22828                                     + " to " + ComponentCallbacks2.TRIM_MEMORY_UI_HIDDEN);
22829                             app.thread.scheduleTrimMemory(
22830                                     ComponentCallbacks2.TRIM_MEMORY_UI_HIDDEN);
22831                         } catch (RemoteException e) {
22832                         }
22833                     }
22834                     app.pendingUiClean = false;
22835                 }
22836                 app.trimMemoryLevel = 0;
22837             }
22838         }
22839
22840         if (mAlwaysFinishActivities) {
22841             // Need to do this on its own message because the stack may not
22842             // be in a consistent state at this point.
22843             mStackSupervisor.scheduleDestroyAllActivities(null, "always-finish");
22844         }
22845
22846         if (allChanged) {
22847             requestPssAllProcsLocked(now, false, mProcessStats.isMemFactorLowered());
22848         }
22849
22850         // Update from any uid changes.
22851         if (mLocalPowerManager != null) {
22852             mLocalPowerManager.startUidChanges();
22853         }
22854         for (int i=mActiveUids.size()-1; i>=0; i--) {
22855             final UidRecord uidRec = mActiveUids.valueAt(i);
22856             int uidChange = UidRecord.CHANGE_PROCSTATE;
22857             if (uidRec.setProcState != uidRec.curProcState
22858                     || uidRec.setWhitelist != uidRec.curWhitelist) {
22859                 if (DEBUG_UID_OBSERVERS) Slog.i(TAG_UID_OBSERVERS,
22860                         "Changes in " + uidRec + ": proc state from " + uidRec.setProcState
22861                         + " to " + uidRec.curProcState + ", whitelist from " + uidRec.setWhitelist
22862                         + " to " + uidRec.curWhitelist);
22863                 if (ActivityManager.isProcStateBackground(uidRec.curProcState)
22864                         && !uidRec.curWhitelist) {
22865                     // UID is now in the background (and not on the temp whitelist).  Was it
22866                     // previously in the foreground (or on the temp whitelist)?
22867                     if (!ActivityManager.isProcStateBackground(uidRec.setProcState)
22868                             || uidRec.setWhitelist) {
22869                         uidRec.lastBackgroundTime = nowElapsed;
22870                         if (!mHandler.hasMessages(IDLE_UIDS_MSG)) {
22871                             // Note: the background settle time is in elapsed realtime, while
22872                             // the handler time base is uptime.  All this means is that we may
22873                             // stop background uids later than we had intended, but that only
22874                             // happens because the device was sleeping so we are okay anyway.
22875                             mHandler.sendEmptyMessageDelayed(IDLE_UIDS_MSG,
22876                                     mConstants.BACKGROUND_SETTLE_TIME);
22877                         }
22878                     }
22879                 } else {
22880                     if (uidRec.idle) {
22881                         uidChange = UidRecord.CHANGE_ACTIVE;
22882                         EventLogTags.writeAmUidActive(uidRec.uid);
22883                         uidRec.idle = false;
22884                     }
22885                     uidRec.lastBackgroundTime = 0;
22886                 }
22887                 uidRec.setProcState = uidRec.curProcState;
22888                 uidRec.setWhitelist = uidRec.curWhitelist;
22889                 enqueueUidChangeLocked(uidRec, -1, uidChange);
22890                 noteUidProcessState(uidRec.uid, uidRec.curProcState);
22891                 if (uidRec.foregroundServices) {
22892                     mServices.foregroundServiceProcStateChangedLocked(uidRec);
22893                 }
22894             }
22895         }
22896         if (mLocalPowerManager != null) {
22897             mLocalPowerManager.finishUidChanges();
22898         }
22899
22900         if (mProcessStats.shouldWriteNowLocked(now)) {
22901             mHandler.post(new Runnable() {
22902                 @Override public void run() {
22903                     synchronized (ActivityManagerService.this) {
22904                         mProcessStats.writeStateAsyncLocked();
22905                     }
22906                 }
22907             });
22908         }
22909
22910         if (DEBUG_OOM_ADJ) {
22911             final long duration = SystemClock.uptimeMillis() - now;
22912             if (false) {
22913                 Slog.d(TAG_OOM_ADJ, "Did OOM ADJ in " + duration + "ms",
22914                         new RuntimeException("here").fillInStackTrace());
22915             } else {
22916                 Slog.d(TAG_OOM_ADJ, "Did OOM ADJ in " + duration + "ms");
22917             }
22918         }
22919     }
22920
22921     @Override
22922     public void makePackageIdle(String packageName, int userId) {
22923         if (checkCallingPermission(android.Manifest.permission.FORCE_STOP_PACKAGES)
22924                 != PackageManager.PERMISSION_GRANTED) {
22925             String msg = "Permission Denial: makePackageIdle() from pid="
22926                     + Binder.getCallingPid()
22927                     + ", uid=" + Binder.getCallingUid()
22928                     + " requires " + android.Manifest.permission.FORCE_STOP_PACKAGES;
22929             Slog.w(TAG, msg);
22930             throw new SecurityException(msg);
22931         }
22932         final int callingPid = Binder.getCallingPid();
22933         userId = mUserController.handleIncomingUser(callingPid, Binder.getCallingUid(),
22934                 userId, true, ALLOW_FULL_ONLY, "makePackageIdle", null);
22935         long callingId = Binder.clearCallingIdentity();
22936         synchronized(this) {
22937             try {
22938                 IPackageManager pm = AppGlobals.getPackageManager();
22939                 int pkgUid = -1;
22940                 try {
22941                     pkgUid = pm.getPackageUid(packageName, MATCH_UNINSTALLED_PACKAGES
22942                             | MATCH_DEBUG_TRIAGED_MISSING, UserHandle.USER_SYSTEM);
22943                 } catch (RemoteException e) {
22944                 }
22945                 if (pkgUid == -1) {
22946                     throw new IllegalArgumentException("Unknown package name " + packageName);
22947                 }
22948
22949                 if (mLocalPowerManager != null) {
22950                     mLocalPowerManager.startUidChanges();
22951                 }
22952                 final int appId = UserHandle.getAppId(pkgUid);
22953                 final int N = mActiveUids.size();
22954                 for (int i=N-1; i>=0; i--) {
22955                     final UidRecord uidRec = mActiveUids.valueAt(i);
22956                     final long bgTime = uidRec.lastBackgroundTime;
22957                     if (bgTime > 0 && !uidRec.idle) {
22958                         if (UserHandle.getAppId(uidRec.uid) == appId) {
22959                             if (userId == UserHandle.USER_ALL ||
22960                                     userId == UserHandle.getUserId(uidRec.uid)) {
22961                                 EventLogTags.writeAmUidIdle(uidRec.uid);
22962                                 uidRec.idle = true;
22963                                 Slog.w(TAG, "Idling uid " + UserHandle.formatUid(uidRec.uid)
22964                                         + " from package " + packageName + " user " + userId);
22965                                 doStopUidLocked(uidRec.uid, uidRec);
22966                             }
22967                         }
22968                     }
22969                 }
22970             } finally {
22971                 if (mLocalPowerManager != null) {
22972                     mLocalPowerManager.finishUidChanges();
22973                 }
22974                 Binder.restoreCallingIdentity(callingId);
22975             }
22976         }
22977     }
22978
22979     final void idleUids() {
22980         synchronized (this) {
22981             final int N = mActiveUids.size();
22982             if (N <= 0) {
22983                 return;
22984             }
22985             final long nowElapsed = SystemClock.elapsedRealtime();
22986             final long maxBgTime = nowElapsed - mConstants.BACKGROUND_SETTLE_TIME;
22987             long nextTime = 0;
22988             if (mLocalPowerManager != null) {
22989                 mLocalPowerManager.startUidChanges();
22990             }
22991             for (int i=N-1; i>=0; i--) {
22992                 final UidRecord uidRec = mActiveUids.valueAt(i);
22993                 final long bgTime = uidRec.lastBackgroundTime;
22994                 if (bgTime > 0 && !uidRec.idle) {
22995                     if (bgTime <= maxBgTime) {
22996                         EventLogTags.writeAmUidIdle(uidRec.uid);
22997                         uidRec.idle = true;
22998                         doStopUidLocked(uidRec.uid, uidRec);
22999                     } else {
23000                         if (nextTime == 0 || nextTime > bgTime) {
23001                             nextTime = bgTime;
23002                         }
23003                     }
23004                 }
23005             }
23006             if (mLocalPowerManager != null) {
23007                 mLocalPowerManager.finishUidChanges();
23008             }
23009             if (nextTime > 0) {
23010                 mHandler.removeMessages(IDLE_UIDS_MSG);
23011                 mHandler.sendEmptyMessageDelayed(IDLE_UIDS_MSG,
23012                         nextTime + mConstants.BACKGROUND_SETTLE_TIME - nowElapsed);
23013             }
23014         }
23015     }
23016
23017     /**
23018      * Checks if any uid is coming from background to foreground or vice versa and if so, increments
23019      * the {@link UidRecord#curProcStateSeq} corresponding to that uid using global seq counter
23020      * {@link #mProcStateSeqCounter} and notifies the app if it needs to block.
23021      */
23022     @VisibleForTesting
23023     @GuardedBy("this")
23024     void incrementProcStateSeqAndNotifyAppsLocked() {
23025         if (mWaitForNetworkTimeoutMs <= 0) {
23026             return;
23027         }
23028         // Used for identifying which uids need to block for network.
23029         ArrayList<Integer> blockingUids = null;
23030         for (int i = mActiveUids.size() - 1; i >= 0; --i) {
23031             final UidRecord uidRec = mActiveUids.valueAt(i);
23032             // If the network is not restricted for uid, then nothing to do here.
23033             if (!mInjector.isNetworkRestrictedForUid(uidRec.uid)) {
23034                 continue;
23035             }
23036             if (!UserHandle.isApp(uidRec.uid) || !uidRec.hasInternetPermission) {
23037                 continue;
23038             }
23039             // If process state is not changed, then there's nothing to do.
23040             if (uidRec.setProcState == uidRec.curProcState) {
23041                 continue;
23042             }
23043             final int blockState = getBlockStateForUid(uidRec);
23044             // No need to inform the app when the blockState is NETWORK_STATE_NO_CHANGE as
23045             // there's nothing the app needs to do in this scenario.
23046             if (blockState == NETWORK_STATE_NO_CHANGE) {
23047                 continue;
23048             }
23049             synchronized (uidRec.networkStateLock) {
23050                 uidRec.curProcStateSeq = ++mProcStateSeqCounter;
23051                 if (blockState == NETWORK_STATE_BLOCK) {
23052                     if (blockingUids == null) {
23053                         blockingUids = new ArrayList<>();
23054                     }
23055                     blockingUids.add(uidRec.uid);
23056                 } else {
23057                     if (DEBUG_NETWORK) {
23058                         Slog.d(TAG_NETWORK, "uid going to background, notifying all blocking"
23059                                 + " threads for uid: " + uidRec);
23060                     }
23061                     if (uidRec.waitingForNetwork) {
23062                         uidRec.networkStateLock.notifyAll();
23063                     }
23064                 }
23065             }
23066         }
23067
23068         // There are no uids that need to block, so nothing more to do.
23069         if (blockingUids == null) {
23070             return;
23071         }
23072
23073         for (int i = mLruProcesses.size() - 1; i >= 0; --i) {
23074             final ProcessRecord app = mLruProcesses.get(i);
23075             if (!blockingUids.contains(app.uid)) {
23076                 continue;
23077             }
23078             if (!app.killedByAm && app.thread != null) {
23079                 final UidRecord uidRec = mActiveUids.get(app.uid);
23080                 try {
23081                     if (DEBUG_NETWORK) {
23082                         Slog.d(TAG_NETWORK, "Informing app thread that it needs to block: "
23083                                 + uidRec);
23084                     }
23085                     app.thread.setNetworkBlockSeq(uidRec.curProcStateSeq);
23086                 } catch (RemoteException ignored) {
23087                 }
23088             }
23089         }
23090     }
23091
23092     /**
23093      * Checks if the uid is coming from background to foreground or vice versa and returns
23094      * appropriate block state based on this.
23095      *
23096      * @return blockState based on whether the uid is coming from background to foreground or
23097      *         vice versa. If bg->fg or fg->bg, then {@link #NETWORK_STATE_BLOCK} or
23098      *         {@link #NETWORK_STATE_UNBLOCK} respectively, otherwise
23099      *         {@link #NETWORK_STATE_NO_CHANGE}.
23100      */
23101     @VisibleForTesting
23102     int getBlockStateForUid(UidRecord uidRec) {
23103         // Denotes whether uid's process state is currently allowed network access.
23104         final boolean isAllowed = isProcStateAllowedWhileIdleOrPowerSaveMode(uidRec.curProcState)
23105                 || isProcStateAllowedWhileOnRestrictBackground(uidRec.curProcState);
23106         // Denotes whether uid's process state was previously allowed network access.
23107         final boolean wasAllowed = isProcStateAllowedWhileIdleOrPowerSaveMode(uidRec.setProcState)
23108                 || isProcStateAllowedWhileOnRestrictBackground(uidRec.setProcState);
23109
23110         // When the uid is coming to foreground, AMS should inform the app thread that it should
23111         // block for the network rules to get updated before launching an activity.
23112         if (!wasAllowed && isAllowed) {
23113             return NETWORK_STATE_BLOCK;
23114         }
23115         // When the uid is going to background, AMS should inform the app thread that if an
23116         // activity launch is blocked for the network rules to get updated, it should be unblocked.
23117         if (wasAllowed && !isAllowed) {
23118             return NETWORK_STATE_UNBLOCK;
23119         }
23120         return NETWORK_STATE_NO_CHANGE;
23121     }
23122
23123     final void runInBackgroundDisabled(int uid) {
23124         synchronized (this) {
23125             UidRecord uidRec = mActiveUids.get(uid);
23126             if (uidRec != null) {
23127                 // This uid is actually running...  should it be considered background now?
23128                 if (uidRec.idle) {
23129                     doStopUidLocked(uidRec.uid, uidRec);
23130                 }
23131             } else {
23132                 // This uid isn't actually running...  still send a report about it being "stopped".
23133                 doStopUidLocked(uid, null);
23134             }
23135         }
23136     }
23137
23138     final void doStopUidLocked(int uid, final UidRecord uidRec) {
23139         mServices.stopInBackgroundLocked(uid);
23140         enqueueUidChangeLocked(uidRec, uid, UidRecord.CHANGE_IDLE);
23141     }
23142
23143     /**
23144      * Whitelists {@code targetUid} to temporarily bypass Power Save mode.
23145      */
23146     void tempWhitelistForPendingIntentLocked(int callerPid, int callerUid, int targetUid,
23147             long duration, String tag) {
23148         if (DEBUG_WHITELISTS) {
23149             Slog.d(TAG, "tempWhitelistForPendingIntentLocked(" + callerPid + ", " + callerUid + ", "
23150                     + targetUid + ", " + duration + ")");
23151         }
23152
23153         synchronized (mPidsSelfLocked) {
23154             final ProcessRecord pr = mPidsSelfLocked.get(callerPid);
23155             if (pr == null) {
23156                 Slog.w(TAG, "tempWhitelistForPendingIntentLocked() no ProcessRecord for pid "
23157                         + callerPid);
23158                 return;
23159             }
23160             if (!pr.whitelistManager) {
23161                 if (checkPermission(CHANGE_DEVICE_IDLE_TEMP_WHITELIST, callerPid, callerUid)
23162                         != PackageManager.PERMISSION_GRANTED) {
23163                     if (DEBUG_WHITELISTS) {
23164                         Slog.d(TAG, "tempWhitelistForPendingIntentLocked() for target " + targetUid
23165                                 + ": pid " + callerPid + " is not allowed");
23166                     }
23167                     return;
23168                 }
23169             }
23170         }
23171
23172         tempWhitelistUidLocked(targetUid, duration, tag);
23173     }
23174
23175     /**
23176      * Whitelists {@code targetUid} to temporarily bypass Power Save mode.
23177      */
23178     void tempWhitelistUidLocked(int targetUid, long duration, String tag) {
23179         mPendingTempWhitelist.put(targetUid, new PendingTempWhitelist(targetUid, duration, tag));
23180         setUidTempWhitelistStateLocked(targetUid, true);
23181         mUiHandler.obtainMessage(PUSH_TEMP_WHITELIST_UI_MSG).sendToTarget();
23182     }
23183
23184     void pushTempWhitelist() {
23185         final int N;
23186         final PendingTempWhitelist[] list;
23187
23188         // First copy out the pending changes...  we need to leave them in the map for now,
23189         // in case someone needs to check what is coming up while we don't have the lock held.
23190         synchronized(this) {
23191             N = mPendingTempWhitelist.size();
23192             list = new PendingTempWhitelist[N];
23193             for (int i = 0; i < N; i++) {
23194                 list[i] = mPendingTempWhitelist.valueAt(i);
23195             }
23196         }
23197
23198         // Now safely dispatch changes to device idle controller.
23199         for (int i = 0; i < N; i++) {
23200             PendingTempWhitelist ptw = list[i];
23201             mLocalDeviceIdleController.addPowerSaveTempWhitelistAppDirect(ptw.targetUid,
23202                     ptw.duration, true, ptw.tag);
23203         }
23204
23205         // And now we can safely remove them from the map.
23206         synchronized(this) {
23207             for (int i = 0; i < N; i++) {
23208                 PendingTempWhitelist ptw = list[i];
23209                 int index = mPendingTempWhitelist.indexOfKey(ptw.targetUid);
23210                 if (index >= 0 && mPendingTempWhitelist.valueAt(index) == ptw) {
23211                     mPendingTempWhitelist.removeAt(index);
23212                 }
23213             }
23214         }
23215     }
23216
23217     final void setAppIdTempWhitelistStateLocked(int appId, boolean onWhitelist) {
23218         boolean changed = false;
23219         for (int i=mActiveUids.size()-1; i>=0; i--) {
23220             final UidRecord uidRec = mActiveUids.valueAt(i);
23221             if (UserHandle.getAppId(uidRec.uid) == appId && uidRec.curWhitelist != onWhitelist) {
23222                 uidRec.curWhitelist = onWhitelist;
23223                 changed = true;
23224             }
23225         }
23226         if (changed) {
23227             updateOomAdjLocked();
23228         }
23229     }
23230
23231     final void setUidTempWhitelistStateLocked(int uid, boolean onWhitelist) {
23232         boolean changed = false;
23233         final UidRecord uidRec = mActiveUids.get(uid);
23234         if (uidRec != null && uidRec.curWhitelist != onWhitelist) {
23235             uidRec.curWhitelist = onWhitelist;
23236             updateOomAdjLocked();
23237         }
23238     }
23239
23240     final void trimApplications() {
23241         synchronized (this) {
23242             int i;
23243
23244             // First remove any unused application processes whose package
23245             // has been removed.
23246             for (i=mRemovedProcesses.size()-1; i>=0; i--) {
23247                 final ProcessRecord app = mRemovedProcesses.get(i);
23248                 if (app.activities.size() == 0
23249                         && app.curReceivers.isEmpty() && app.services.size() == 0) {
23250                     Slog.i(
23251                         TAG, "Exiting empty application process "
23252                         + app.toShortString() + " ("
23253                         + (app.thread != null ? app.thread.asBinder() : null)
23254                         + ")\n");
23255                     if (app.pid > 0 && app.pid != MY_PID) {
23256                         app.kill("empty", false);
23257                     } else {
23258                         try {
23259                             app.thread.scheduleExit();
23260                         } catch (Exception e) {
23261                             // Ignore exceptions.
23262                         }
23263                     }
23264                     cleanUpApplicationRecordLocked(app, false, true, -1, false /*replacingPid*/);
23265                     mRemovedProcesses.remove(i);
23266
23267                     if (app.persistent) {
23268                         addAppLocked(app.info, null, false, null /* ABI override */);
23269                     }
23270                 }
23271             }
23272
23273             // Now update the oom adj for all processes.
23274             updateOomAdjLocked();
23275         }
23276     }
23277
23278     /** This method sends the specified signal to each of the persistent apps */
23279     public void signalPersistentProcesses(int sig) throws RemoteException {
23280         if (sig != SIGNAL_USR1) {
23281             throw new SecurityException("Only SIGNAL_USR1 is allowed");
23282         }
23283
23284         synchronized (this) {
23285             if (checkCallingPermission(android.Manifest.permission.SIGNAL_PERSISTENT_PROCESSES)
23286                     != PackageManager.PERMISSION_GRANTED) {
23287                 throw new SecurityException("Requires permission "
23288                         + android.Manifest.permission.SIGNAL_PERSISTENT_PROCESSES);
23289             }
23290
23291             for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) {
23292                 ProcessRecord r = mLruProcesses.get(i);
23293                 if (r.thread != null && r.persistent) {
23294                     sendSignal(r.pid, sig);
23295                 }
23296             }
23297         }
23298     }
23299
23300     private void stopProfilerLocked(ProcessRecord proc, int profileType) {
23301         if (proc == null || proc == mProfileProc) {
23302             proc = mProfileProc;
23303             profileType = mProfileType;
23304             clearProfilerLocked();
23305         }
23306         if (proc == null) {
23307             return;
23308         }
23309         try {
23310             proc.thread.profilerControl(false, null, profileType);
23311         } catch (RemoteException e) {
23312             throw new IllegalStateException("Process disappeared");
23313         }
23314     }
23315
23316     private void clearProfilerLocked() {
23317         if (mProfileFd != null) {
23318             try {
23319                 mProfileFd.close();
23320             } catch (IOException e) {
23321             }
23322         }
23323         mProfileApp = null;
23324         mProfileProc = null;
23325         mProfileFile = null;
23326         mProfileType = 0;
23327         mAutoStopProfiler = false;
23328         mStreamingOutput = false;
23329         mSamplingInterval = 0;
23330     }
23331
23332     public boolean profileControl(String process, int userId, boolean start,
23333             ProfilerInfo profilerInfo, int profileType) throws RemoteException {
23334
23335         try {
23336             synchronized (this) {
23337                 // note: hijacking SET_ACTIVITY_WATCHER, but should be changed to
23338                 // its own permission.
23339                 if (checkCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER)
23340                         != PackageManager.PERMISSION_GRANTED) {
23341                     throw new SecurityException("Requires permission "
23342                             + android.Manifest.permission.SET_ACTIVITY_WATCHER);
23343                 }
23344
23345                 if (start && (profilerInfo == null || profilerInfo.profileFd == null)) {
23346                     throw new IllegalArgumentException("null profile info or fd");
23347                 }
23348
23349                 ProcessRecord proc = null;
23350                 if (process != null) {
23351                     proc = findProcessLocked(process, userId, "profileControl");
23352                 }
23353
23354                 if (start && (proc == null || proc.thread == null)) {
23355                     throw new IllegalArgumentException("Unknown process: " + process);
23356                 }
23357
23358                 if (start) {
23359                     stopProfilerLocked(null, 0);
23360                     setProfileApp(proc.info, proc.processName, profilerInfo);
23361                     mProfileProc = proc;
23362                     mProfileType = profileType;
23363                     ParcelFileDescriptor fd = profilerInfo.profileFd;
23364                     try {
23365                         fd = fd.dup();
23366                     } catch (IOException e) {
23367                         fd = null;
23368                     }
23369                     profilerInfo.profileFd = fd;
23370                     proc.thread.profilerControl(start, profilerInfo, profileType);
23371                     fd = null;
23372                     try {
23373                         mProfileFd.close();
23374                     } catch (IOException e) {
23375                     }
23376                     mProfileFd = null;
23377                 } else {
23378                     stopProfilerLocked(proc, profileType);
23379                     if (profilerInfo != null && profilerInfo.profileFd != null) {
23380                         try {
23381                             profilerInfo.profileFd.close();
23382                         } catch (IOException e) {
23383                         }
23384                     }
23385                 }
23386
23387                 return true;
23388             }
23389         } catch (RemoteException e) {
23390             throw new IllegalStateException("Process disappeared");
23391         } finally {
23392             if (profilerInfo != null && profilerInfo.profileFd != null) {
23393                 try {
23394                     profilerInfo.profileFd.close();
23395                 } catch (IOException e) {
23396                 }
23397             }
23398         }
23399     }
23400
23401     private ProcessRecord findProcessLocked(String process, int userId, String callName) {
23402         userId = mUserController.handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(),
23403                 userId, true, ALLOW_FULL_ONLY, callName, null);
23404         ProcessRecord proc = null;
23405         try {
23406             int pid = Integer.parseInt(process);
23407             synchronized (mPidsSelfLocked) {
23408                 proc = mPidsSelfLocked.get(pid);
23409             }
23410         } catch (NumberFormatException e) {
23411         }
23412
23413         if (proc == null) {
23414             ArrayMap<String, SparseArray<ProcessRecord>> all
23415                     = mProcessNames.getMap();
23416             SparseArray<ProcessRecord> procs = all.get(process);
23417             if (procs != null && procs.size() > 0) {
23418                 proc = procs.valueAt(0);
23419                 if (userId != UserHandle.USER_ALL && proc.userId != userId) {
23420                     for (int i=1; i<procs.size(); i++) {
23421                         ProcessRecord thisProc = procs.valueAt(i);
23422                         if (thisProc.userId == userId) {
23423                             proc = thisProc;
23424                             break;
23425                         }
23426                     }
23427                 }
23428             }
23429         }
23430
23431         return proc;
23432     }
23433
23434     public boolean dumpHeap(String process, int userId, boolean managed,
23435             String path, ParcelFileDescriptor fd) throws RemoteException {
23436
23437         try {
23438             synchronized (this) {
23439                 // note: hijacking SET_ACTIVITY_WATCHER, but should be changed to
23440                 // its own permission (same as profileControl).
23441                 if (checkCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER)
23442                         != PackageManager.PERMISSION_GRANTED) {
23443                     throw new SecurityException("Requires permission "
23444                             + android.Manifest.permission.SET_ACTIVITY_WATCHER);
23445                 }
23446
23447                 if (fd == null) {
23448                     throw new IllegalArgumentException("null fd");
23449                 }
23450
23451                 ProcessRecord proc = findProcessLocked(process, userId, "dumpHeap");
23452                 if (proc == null || proc.thread == null) {
23453                     throw new IllegalArgumentException("Unknown process: " + process);
23454                 }
23455
23456                 boolean isDebuggable = "1".equals(SystemProperties.get(SYSTEM_DEBUGGABLE, "0"));
23457                 if (!isDebuggable) {
23458                     if ((proc.info.flags&ApplicationInfo.FLAG_DEBUGGABLE) == 0) {
23459                         throw new SecurityException("Process not debuggable: " + proc);
23460                     }
23461                 }
23462
23463                 proc.thread.dumpHeap(managed, path, fd);
23464                 fd = null;
23465                 return true;
23466             }
23467         } catch (RemoteException e) {
23468             throw new IllegalStateException("Process disappeared");
23469         } finally {
23470             if (fd != null) {
23471                 try {
23472                     fd.close();
23473                 } catch (IOException e) {
23474                 }
23475             }
23476         }
23477     }
23478
23479     @Override
23480     public void setDumpHeapDebugLimit(String processName, int uid, long maxMemSize,
23481             String reportPackage) {
23482         if (processName != null) {
23483             enforceCallingPermission(android.Manifest.permission.SET_DEBUG_APP,
23484                     "setDumpHeapDebugLimit()");
23485         } else {
23486             synchronized (mPidsSelfLocked) {
23487                 ProcessRecord proc = mPidsSelfLocked.get(Binder.getCallingPid());
23488                 if (proc == null) {
23489                     throw new SecurityException("No process found for calling pid "
23490                             + Binder.getCallingPid());
23491                 }
23492                 if (!Build.IS_DEBUGGABLE
23493                         && (proc.info.flags&ApplicationInfo.FLAG_DEBUGGABLE) == 0) {
23494                     throw new SecurityException("Not running a debuggable build");
23495                 }
23496                 processName = proc.processName;
23497                 uid = proc.uid;
23498                 if (reportPackage != null && !proc.pkgList.containsKey(reportPackage)) {
23499                     throw new SecurityException("Package " + reportPackage + " is not running in "
23500                             + proc);
23501                 }
23502             }
23503         }
23504         synchronized (this) {
23505             if (maxMemSize > 0) {
23506                 mMemWatchProcesses.put(processName, uid, new Pair(maxMemSize, reportPackage));
23507             } else {
23508                 if (uid != 0) {
23509                     mMemWatchProcesses.remove(processName, uid);
23510                 } else {
23511                     mMemWatchProcesses.getMap().remove(processName);
23512                 }
23513             }
23514         }
23515     }
23516
23517     @Override
23518     public void dumpHeapFinished(String path) {
23519         synchronized (this) {
23520             if (Binder.getCallingPid() != mMemWatchDumpPid) {
23521                 Slog.w(TAG, "dumpHeapFinished: Calling pid " + Binder.getCallingPid()
23522                         + " does not match last pid " + mMemWatchDumpPid);
23523                 return;
23524             }
23525             if (mMemWatchDumpFile == null || !mMemWatchDumpFile.equals(path)) {
23526                 Slog.w(TAG, "dumpHeapFinished: Calling path " + path
23527                         + " does not match last path " + mMemWatchDumpFile);
23528                 return;
23529             }
23530             if (DEBUG_PSS) Slog.d(TAG_PSS, "Dump heap finished for " + path);
23531             mHandler.sendEmptyMessage(POST_DUMP_HEAP_NOTIFICATION_MSG);
23532         }
23533     }
23534
23535     /** In this method we try to acquire our lock to make sure that we have not deadlocked */
23536     public void monitor() {
23537         synchronized (this) { }
23538     }
23539
23540     void onCoreSettingsChange(Bundle settings) {
23541         for (int i = mLruProcesses.size() - 1; i >= 0; i--) {
23542             ProcessRecord processRecord = mLruProcesses.get(i);
23543             try {
23544                 if (processRecord.thread != null) {
23545                     processRecord.thread.setCoreSettings(settings);
23546                 }
23547             } catch (RemoteException re) {
23548                 /* ignore */
23549             }
23550         }
23551     }
23552
23553     // Multi-user methods
23554
23555     /**
23556      * Start user, if its not already running, but don't bring it to foreground.
23557      */
23558     @Override
23559     public boolean startUserInBackground(final int userId) {
23560         return mUserController.startUser(userId, /* foreground */ false);
23561     }
23562
23563     @Override
23564     public boolean unlockUser(int userId, byte[] token, byte[] secret, IProgressListener listener) {
23565         return mUserController.unlockUser(userId, token, secret, listener);
23566     }
23567
23568     @Override
23569     public boolean switchUser(final int targetUserId) {
23570         enforceShellRestriction(UserManager.DISALLOW_DEBUGGING_FEATURES, targetUserId);
23571         int currentUserId;
23572         UserInfo targetUserInfo;
23573         synchronized (this) {
23574             currentUserId = mUserController.getCurrentUserIdLocked();
23575             targetUserInfo = mUserController.getUserInfo(targetUserId);
23576             if (targetUserId == currentUserId) {
23577                 Slog.i(TAG, "user #" + targetUserId + " is already the current user");
23578                 return true;
23579             }
23580             if (targetUserInfo == null) {
23581                 Slog.w(TAG, "No user info for user #" + targetUserId);
23582                 return false;
23583             }
23584             if (!targetUserInfo.isDemo() && UserManager.isDeviceInDemoMode(mContext)) {
23585                 Slog.w(TAG, "Cannot switch to non-demo user #" + targetUserId
23586                         + " when device is in demo mode");
23587                 return false;
23588             }
23589             if (!targetUserInfo.supportsSwitchTo()) {
23590                 Slog.w(TAG, "Cannot switch to User #" + targetUserId + ": not supported");
23591                 return false;
23592             }
23593             if (targetUserInfo.isManagedProfile()) {
23594                 Slog.w(TAG, "Cannot switch to User #" + targetUserId + ": not a full user");
23595                 return false;
23596             }
23597             mUserController.setTargetUserIdLocked(targetUserId);
23598         }
23599         if (mUserController.mUserSwitchUiEnabled) {
23600             UserInfo currentUserInfo = mUserController.getUserInfo(currentUserId);
23601             Pair<UserInfo, UserInfo> userNames = new Pair<>(currentUserInfo, targetUserInfo);
23602             mUiHandler.removeMessages(START_USER_SWITCH_UI_MSG);
23603             mUiHandler.sendMessage(mHandler.obtainMessage(
23604                     START_USER_SWITCH_UI_MSG, userNames));
23605         } else {
23606             mHandler.removeMessages(START_USER_SWITCH_FG_MSG);
23607             mHandler.sendMessage(mHandler.obtainMessage(
23608                     START_USER_SWITCH_FG_MSG, targetUserId, 0));
23609         }
23610         return true;
23611     }
23612
23613     void scheduleStartProfilesLocked() {
23614         if (!mHandler.hasMessages(START_PROFILES_MSG)) {
23615             mHandler.sendMessageDelayed(mHandler.obtainMessage(START_PROFILES_MSG),
23616                     DateUtils.SECOND_IN_MILLIS);
23617         }
23618     }
23619
23620     @Override
23621     public int stopUser(final int userId, boolean force, final IStopUserCallback callback) {
23622         return mUserController.stopUser(userId, force, callback);
23623     }
23624
23625     @Override
23626     public UserInfo getCurrentUser() {
23627         return mUserController.getCurrentUser();
23628     }
23629
23630     String getStartedUserState(int userId) {
23631         synchronized (this) {
23632             final UserState userState = mUserController.getStartedUserStateLocked(userId);
23633             return UserState.stateToString(userState.state);
23634         }
23635     }
23636
23637     @Override
23638     public boolean isUserRunning(int userId, int flags) {
23639         if (!mUserController.isSameProfileGroup(userId, UserHandle.getCallingUserId())
23640                 && checkCallingPermission(INTERACT_ACROSS_USERS)
23641                     != PackageManager.PERMISSION_GRANTED) {
23642             String msg = "Permission Denial: isUserRunning() from pid="
23643                     + Binder.getCallingPid()
23644                     + ", uid=" + Binder.getCallingUid()
23645                     + " requires " + INTERACT_ACROSS_USERS;
23646             Slog.w(TAG, msg);
23647             throw new SecurityException(msg);
23648         }
23649         synchronized (this) {
23650             return mUserController.isUserRunningLocked(userId, flags);
23651         }
23652     }
23653
23654     @Override
23655     public int[] getRunningUserIds() {
23656         if (checkCallingPermission(INTERACT_ACROSS_USERS)
23657                 != PackageManager.PERMISSION_GRANTED) {
23658             String msg = "Permission Denial: isUserRunning() from pid="
23659                     + Binder.getCallingPid()
23660                     + ", uid=" + Binder.getCallingUid()
23661                     + " requires " + INTERACT_ACROSS_USERS;
23662             Slog.w(TAG, msg);
23663             throw new SecurityException(msg);
23664         }
23665         synchronized (this) {
23666             return mUserController.getStartedUserArrayLocked();
23667         }
23668     }
23669
23670     @Override
23671     public void registerUserSwitchObserver(IUserSwitchObserver observer, String name) {
23672         mUserController.registerUserSwitchObserver(observer, name);
23673     }
23674
23675     @Override
23676     public void unregisterUserSwitchObserver(IUserSwitchObserver observer) {
23677         mUserController.unregisterUserSwitchObserver(observer);
23678     }
23679
23680     ApplicationInfo getAppInfoForUser(ApplicationInfo info, int userId) {
23681         if (info == null) return null;
23682         ApplicationInfo newInfo = new ApplicationInfo(info);
23683         newInfo.initForUser(userId);
23684         return newInfo;
23685     }
23686
23687     public boolean isUserStopped(int userId) {
23688         synchronized (this) {
23689             return mUserController.getStartedUserStateLocked(userId) == null;
23690         }
23691     }
23692
23693     ActivityInfo getActivityInfoForUser(ActivityInfo aInfo, int userId) {
23694         if (aInfo == null
23695                 || (userId < 1 && aInfo.applicationInfo.uid < UserHandle.PER_USER_RANGE)) {
23696             return aInfo;
23697         }
23698
23699         ActivityInfo info = new ActivityInfo(aInfo);
23700         info.applicationInfo = getAppInfoForUser(info.applicationInfo, userId);
23701         return info;
23702     }
23703
23704     private boolean processSanityChecksLocked(ProcessRecord process) {
23705         if (process == null || process.thread == null) {
23706             return false;
23707         }
23708
23709         boolean isDebuggable = "1".equals(SystemProperties.get(SYSTEM_DEBUGGABLE, "0"));
23710         if (!isDebuggable) {
23711             if ((process.info.flags&ApplicationInfo.FLAG_DEBUGGABLE) == 0) {
23712                 return false;
23713             }
23714         }
23715
23716         return true;
23717     }
23718
23719     public boolean startBinderTracking() throws RemoteException {
23720         synchronized (this) {
23721             mBinderTransactionTrackingEnabled = true;
23722             // TODO: hijacking SET_ACTIVITY_WATCHER, but should be changed to its own
23723             // permission (same as profileControl).
23724             if (checkCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER)
23725                     != PackageManager.PERMISSION_GRANTED) {
23726                 throw new SecurityException("Requires permission "
23727                         + android.Manifest.permission.SET_ACTIVITY_WATCHER);
23728             }
23729
23730             for (int i = 0; i < mLruProcesses.size(); i++) {
23731                 ProcessRecord process = mLruProcesses.get(i);
23732                 if (!processSanityChecksLocked(process)) {
23733                     continue;
23734                 }
23735                 try {
23736                     process.thread.startBinderTracking();
23737                 } catch (RemoteException e) {
23738                     Log.v(TAG, "Process disappared");
23739                 }
23740             }
23741             return true;
23742         }
23743     }
23744
23745     public boolean stopBinderTrackingAndDump(ParcelFileDescriptor fd) throws RemoteException {
23746         try {
23747             synchronized (this) {
23748                 mBinderTransactionTrackingEnabled = false;
23749                 // TODO: hijacking SET_ACTIVITY_WATCHER, but should be changed to its own
23750                 // permission (same as profileControl).
23751                 if (checkCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER)
23752                         != PackageManager.PERMISSION_GRANTED) {
23753                     throw new SecurityException("Requires permission "
23754                             + android.Manifest.permission.SET_ACTIVITY_WATCHER);
23755                 }
23756
23757                 if (fd == null) {
23758                     throw new IllegalArgumentException("null fd");
23759                 }
23760
23761                 PrintWriter pw = new FastPrintWriter(new FileOutputStream(fd.getFileDescriptor()));
23762                 pw.println("Binder transaction traces for all processes.\n");
23763                 for (ProcessRecord process : mLruProcesses) {
23764                     if (!processSanityChecksLocked(process)) {
23765                         continue;
23766                     }
23767
23768                     pw.println("Traces for process: " + process.processName);
23769                     pw.flush();
23770                     try {
23771                         TransferPipe tp = new TransferPipe();
23772                         try {
23773                             process.thread.stopBinderTrackingAndDump(tp.getWriteFd());
23774                             tp.go(fd.getFileDescriptor());
23775                         } finally {
23776                             tp.kill();
23777                         }
23778                     } catch (IOException e) {
23779                         pw.println("Failure while dumping IPC traces from " + process +
23780                                 ".  Exception: " + e);
23781                         pw.flush();
23782                     } catch (RemoteException e) {
23783                         pw.println("Got a RemoteException while dumping IPC traces from " +
23784                                 process + ".  Exception: " + e);
23785                         pw.flush();
23786                     }
23787                 }
23788                 fd = null;
23789                 return true;
23790             }
23791         } finally {
23792             if (fd != null) {
23793                 try {
23794                     fd.close();
23795                 } catch (IOException e) {
23796                 }
23797             }
23798         }
23799     }
23800
23801     @VisibleForTesting
23802     final class LocalService extends ActivityManagerInternal {
23803         @Override
23804         public void grantUriPermissionFromIntent(int callingUid, String targetPkg, Intent intent,
23805                 int targetUserId) {
23806             synchronized (ActivityManagerService.this) {
23807                 ActivityManagerService.this.grantUriPermissionFromIntentLocked(callingUid,
23808                         targetPkg, intent, null, targetUserId);
23809             }
23810         }
23811
23812         @Override
23813         public String checkContentProviderAccess(String authority, int userId) {
23814             return ActivityManagerService.this.checkContentProviderAccess(authority, userId);
23815         }
23816
23817         @Override
23818         public void onWakefulnessChanged(int wakefulness) {
23819             ActivityManagerService.this.onWakefulnessChanged(wakefulness);
23820         }
23821
23822         @Override
23823         public int startIsolatedProcess(String entryPoint, String[] entryPointArgs,
23824                 String processName, String abiOverride, int uid, Runnable crashHandler) {
23825             return ActivityManagerService.this.startIsolatedProcess(entryPoint, entryPointArgs,
23826                     processName, abiOverride, uid, crashHandler);
23827         }
23828
23829         @Override
23830         public SleepToken acquireSleepToken(String tag) {
23831             Preconditions.checkNotNull(tag);
23832
23833             synchronized (ActivityManagerService.this) {
23834                 SleepTokenImpl token = new SleepTokenImpl(tag);
23835                 mSleepTokens.add(token);
23836                 updateSleepIfNeededLocked();
23837                 return token;
23838             }
23839         }
23840
23841         @Override
23842         public ComponentName getHomeActivityForUser(int userId) {
23843             synchronized (ActivityManagerService.this) {
23844                 ActivityRecord homeActivity = mStackSupervisor.getHomeActivityForUser(userId);
23845                 return homeActivity == null ? null : homeActivity.realActivity;
23846             }
23847         }
23848
23849         @Override
23850         public void onUserRemoved(int userId) {
23851             synchronized (ActivityManagerService.this) {
23852                 ActivityManagerService.this.onUserStoppedLocked(userId);
23853             }
23854         }
23855
23856         @Override
23857         public void onLocalVoiceInteractionStarted(IBinder activity,
23858                 IVoiceInteractionSession voiceSession, IVoiceInteractor voiceInteractor) {
23859             synchronized (ActivityManagerService.this) {
23860                 ActivityManagerService.this.onLocalVoiceInteractionStartedLocked(activity,
23861                         voiceSession, voiceInteractor);
23862             }
23863         }
23864
23865         @Override
23866         public void notifyAppTransitionStarting(SparseIntArray reasons, long timestamp) {
23867             synchronized (ActivityManagerService.this) {
23868                 mStackSupervisor.mActivityMetricsLogger.notifyTransitionStarting(
23869                         reasons, timestamp);
23870             }
23871         }
23872
23873         @Override
23874         public void notifyAppTransitionFinished() {
23875             synchronized (ActivityManagerService.this) {
23876                 mStackSupervisor.notifyAppTransitionDone();
23877             }
23878         }
23879
23880         @Override
23881         public void notifyAppTransitionCancelled() {
23882             synchronized (ActivityManagerService.this) {
23883                 mStackSupervisor.notifyAppTransitionDone();
23884             }
23885         }
23886
23887         @Override
23888         public List<IBinder> getTopVisibleActivities() {
23889             synchronized (ActivityManagerService.this) {
23890                 return mStackSupervisor.getTopVisibleActivities();
23891             }
23892         }
23893
23894         @Override
23895         public void notifyDockedStackMinimizedChanged(boolean minimized) {
23896             synchronized (ActivityManagerService.this) {
23897                 mStackSupervisor.setDockedStackMinimized(minimized);
23898             }
23899         }
23900
23901         @Override
23902         public void killForegroundAppsForUser(int userHandle) {
23903             synchronized (ActivityManagerService.this) {
23904                 final ArrayList<ProcessRecord> procs = new ArrayList<>();
23905                 final int NP = mProcessNames.getMap().size();
23906                 for (int ip = 0; ip < NP; ip++) {
23907                     final SparseArray<ProcessRecord> apps = mProcessNames.getMap().valueAt(ip);
23908                     final int NA = apps.size();
23909                     for (int ia = 0; ia < NA; ia++) {
23910                         final ProcessRecord app = apps.valueAt(ia);
23911                         if (app.persistent) {
23912                             // We don't kill persistent processes.
23913                             continue;
23914                         }
23915                         if (app.removed) {
23916                             procs.add(app);
23917                         } else if (app.userId == userHandle && app.foregroundActivities) {
23918                             app.removed = true;
23919                             procs.add(app);
23920                         }
23921                     }
23922                 }
23923
23924                 final int N = procs.size();
23925                 for (int i = 0; i < N; i++) {
23926                     removeProcessLocked(procs.get(i), false, true, "kill all fg");
23927                 }
23928             }
23929         }
23930
23931         @Override
23932         public void setPendingIntentWhitelistDuration(IIntentSender target, IBinder whitelistToken,
23933                 long duration) {
23934             if (!(target instanceof PendingIntentRecord)) {
23935                 Slog.w(TAG, "markAsSentFromNotification(): not a PendingIntentRecord: " + target);
23936                 return;
23937             }
23938             synchronized (ActivityManagerService.this) {
23939                 ((PendingIntentRecord) target).setWhitelistDurationLocked(whitelistToken, duration);
23940             }
23941         }
23942
23943         @Override
23944         public void setDeviceIdleWhitelist(int[] appids) {
23945             synchronized (ActivityManagerService.this) {
23946                 mDeviceIdleWhitelist = appids;
23947             }
23948         }
23949
23950         @Override
23951         public void updateDeviceIdleTempWhitelist(int[] appids, int changingAppId, boolean adding) {
23952             synchronized (ActivityManagerService.this) {
23953                 mDeviceIdleTempWhitelist = appids;
23954                 setAppIdTempWhitelistStateLocked(changingAppId, adding);
23955             }
23956         }
23957
23958         @Override
23959         public void updatePersistentConfigurationForUser(@NonNull Configuration values,
23960                 int userId) {
23961             Preconditions.checkNotNull(values, "Configuration must not be null");
23962             Preconditions.checkArgumentNonnegative(userId, "userId " + userId + " not supported");
23963             synchronized (ActivityManagerService.this) {
23964                 updateConfigurationLocked(values, null, false, true, userId,
23965                         false /* deferResume */);
23966             }
23967         }
23968
23969         @Override
23970         public int startActivitiesAsPackage(String packageName, int userId, Intent[] intents,
23971                 Bundle bOptions) {
23972             Preconditions.checkNotNull(intents, "intents");
23973             final String[] resolvedTypes = new String[intents.length];
23974             for (int i = 0; i < intents.length; i++) {
23975                 resolvedTypes[i] = intents[i].resolveTypeIfNeeded(mContext.getContentResolver());
23976             }
23977
23978             // UID of the package on user userId.
23979             // "= 0" is needed because otherwise catch(RemoteException) would make it look like
23980             // packageUid may not be initialized.
23981             int packageUid = 0;
23982             try {
23983                 packageUid = AppGlobals.getPackageManager().getPackageUid(
23984                         packageName, PackageManager.MATCH_DEBUG_TRIAGED_MISSING, userId);
23985             } catch (RemoteException e) {
23986                 // Shouldn't happen.
23987             }
23988
23989             synchronized (ActivityManagerService.this) {
23990                 return startActivitiesInPackage(packageUid, packageName, intents, resolvedTypes,
23991                         /*resultTo*/ null, bOptions, userId);
23992             }
23993         }
23994
23995         @Override
23996         public int getUidProcessState(int uid) {
23997             return getUidState(uid);
23998         }
23999
24000         @Override
24001         public void notifyKeyguardFlagsChanged(@Nullable Runnable callback) {
24002             synchronized (ActivityManagerService.this) {
24003
24004                 // We might change the visibilities here, so prepare an empty app transition which
24005                 // might be overridden later if we actually change visibilities.
24006                 final boolean wasTransitionSet =
24007                         mWindowManager.getPendingAppTransition() != TRANSIT_NONE;
24008                 if (!wasTransitionSet) {
24009                     mWindowManager.prepareAppTransition(TRANSIT_NONE,
24010                             false /* alwaysKeepCurrent */);
24011                 }
24012                 mStackSupervisor.ensureActivitiesVisibleLocked(null, 0, !PRESERVE_WINDOWS);
24013
24014                 // If there was a transition set already we don't want to interfere with it as we
24015                 // might be starting it too early.
24016                 if (!wasTransitionSet) {
24017                     mWindowManager.executeAppTransition();
24018                 }
24019             }
24020             if (callback != null) {
24021                 callback.run();
24022             }
24023         }
24024
24025         @Override
24026         public boolean isSystemReady() {
24027             // no need to synchronize(this) just to read & return the value
24028             return mSystemReady;
24029         }
24030
24031         @Override
24032         public void notifyKeyguardTrustedChanged() {
24033             synchronized (ActivityManagerService.this) {
24034                 if (mKeyguardController.isKeyguardShowing()) {
24035                     mStackSupervisor.ensureActivitiesVisibleLocked(null, 0, !PRESERVE_WINDOWS);
24036                 }
24037             }
24038         }
24039
24040         /**
24041          * Sets if the given pid has an overlay UI or not.
24042          *
24043          * @param pid The pid we are setting overlay UI for.
24044          * @param hasOverlayUi True if the process has overlay UI.
24045          * @see android.view.WindowManager.LayoutParams#TYPE_APPLICATION_OVERLAY
24046          */
24047         @Override
24048         public void setHasOverlayUi(int pid, boolean hasOverlayUi) {
24049             synchronized (ActivityManagerService.this) {
24050                 final ProcessRecord pr;
24051                 synchronized (mPidsSelfLocked) {
24052                     pr = mPidsSelfLocked.get(pid);
24053                     if (pr == null) {
24054                         Slog.w(TAG, "setHasOverlayUi called on unknown pid: " + pid);
24055                         return;
24056                     }
24057                 }
24058                 if (pr.hasOverlayUi == hasOverlayUi) {
24059                     return;
24060                 }
24061                 pr.hasOverlayUi = hasOverlayUi;
24062                 //Slog.i(TAG, "Setting hasOverlayUi=" + pr.hasOverlayUi + " for pid=" + pid);
24063                 updateOomAdjLocked(pr, true);
24064             }
24065         }
24066
24067         /**
24068          * Called after the network policy rules are updated by
24069          * {@link com.android.server.net.NetworkPolicyManagerService} for a specific {@param uid}
24070          * and {@param procStateSeq}.
24071          */
24072         @Override
24073         public void notifyNetworkPolicyRulesUpdated(int uid, long procStateSeq) {
24074             if (DEBUG_NETWORK) {
24075                 Slog.d(TAG_NETWORK, "Got update from NPMS for uid: "
24076                         + uid + " seq: " + procStateSeq);
24077             }
24078             UidRecord record;
24079             synchronized (ActivityManagerService.this) {
24080                 record = mActiveUids.get(uid);
24081                 if (record == null) {
24082                     if (DEBUG_NETWORK) {
24083                         Slog.d(TAG_NETWORK, "No active uidRecord for uid: " + uid
24084                                 + " procStateSeq: " + procStateSeq);
24085                     }
24086                     return;
24087                 }
24088             }
24089             synchronized (record.networkStateLock) {
24090                 if (record.lastNetworkUpdatedProcStateSeq >= procStateSeq) {
24091                     if (DEBUG_NETWORK) {
24092                         Slog.d(TAG_NETWORK, "procStateSeq: " + procStateSeq + " has already"
24093                                 + " been handled for uid: " + uid);
24094                     }
24095                     return;
24096                 }
24097                 record.lastNetworkUpdatedProcStateSeq = procStateSeq;
24098                 if (record.curProcStateSeq > procStateSeq) {
24099                     if (DEBUG_NETWORK) {
24100                         Slog.d(TAG_NETWORK, "No need to handle older seq no., Uid: " + uid
24101                                 + ", curProcstateSeq: " + record.curProcStateSeq
24102                                 + ", procStateSeq: " + procStateSeq);
24103                     }
24104                     return;
24105                 }
24106                 if (record.waitingForNetwork) {
24107                     if (DEBUG_NETWORK) {
24108                         Slog.d(TAG_NETWORK, "Notifying all blocking threads for uid: " + uid
24109                                 + ", procStateSeq: " + procStateSeq);
24110                     }
24111                     record.networkStateLock.notifyAll();
24112                 }
24113             }
24114         }
24115
24116         /**
24117          * Called after virtual display Id is updated by
24118          * {@link com.android.server.vr.Vr2dDisplay} with a specific
24119          * {@param vrVr2dDisplayId}.
24120          */
24121         @Override
24122         public void setVr2dDisplayId(int vr2dDisplayId) {
24123             if (DEBUG_STACK) {
24124                 Slog.d(TAG, "setVr2dDisplayId called for: " +
24125                         vr2dDisplayId);
24126             }
24127             synchronized (ActivityManagerService.this) {
24128                 mVr2dDisplayId = vr2dDisplayId;
24129             }
24130         }
24131
24132         @Override
24133         public void saveANRState(String reason) {
24134             synchronized (ActivityManagerService.this) {
24135                 final StringWriter sw = new StringWriter();
24136                 final PrintWriter pw = new FastPrintWriter(sw, false, 1024);
24137                 pw.println("  ANR time: " + DateFormat.getDateTimeInstance().format(new Date()));
24138                 if (reason != null) {
24139                     pw.println("  Reason: " + reason);
24140                 }
24141                 pw.println();
24142                 mActivityStarter.dump(pw, "  ");
24143                 pw.println();
24144                 pw.println("-------------------------------------------------------------------------------");
24145                 dumpActivitiesLocked(null /* fd */, pw, null /* args */, 0 /* opti */,
24146                         true /* dumpAll */, false /* dumpClient */, null /* dumpPackage */,
24147                         "" /* header */);
24148                 pw.println();
24149                 pw.close();
24150
24151                 mLastANRState = sw.toString();
24152             }
24153         }
24154
24155         @Override
24156         public void clearSavedANRState() {
24157             synchronized (ActivityManagerService.this) {
24158                 mLastANRState = null;
24159             }
24160         }
24161
24162         @Override
24163         public boolean hasRunningActivity(int uid, @Nullable String packageName) {
24164             if (packageName == null) return false;
24165
24166             synchronized (ActivityManagerService.this) {
24167                 for (int i = 0; i < mLruProcesses.size(); i++) {
24168                     final ProcessRecord processRecord = mLruProcesses.get(i);
24169                     if (processRecord.uid == uid) {
24170                         for (int j = 0; j < processRecord.activities.size(); j++) {
24171                             final ActivityRecord activityRecord = processRecord.activities.get(j);
24172                             if (packageName.equals(activityRecord.packageName)) {
24173                                 return true;
24174                             }
24175                         }
24176                     }
24177                 }
24178             }
24179             return false;
24180         }
24181     }
24182
24183     /**
24184      * Called by app main thread to wait for the network policy rules to get updated.
24185      *
24186      * @param procStateSeq The sequence number indicating the process state change that the main
24187      *                     thread is interested in.
24188      */
24189     @Override
24190     public void waitForNetworkStateUpdate(long procStateSeq) {
24191         final int callingUid = Binder.getCallingUid();
24192         if (DEBUG_NETWORK) {
24193             Slog.d(TAG_NETWORK, "Called from " + callingUid + " to wait for seq: " + procStateSeq);
24194         }
24195         UidRecord record;
24196         synchronized (this) {
24197             record = mActiveUids.get(callingUid);
24198             if (record == null) {
24199                 return;
24200             }
24201         }
24202         synchronized (record.networkStateLock) {
24203             if (record.lastDispatchedProcStateSeq < procStateSeq) {
24204                 if (DEBUG_NETWORK) {
24205                     Slog.d(TAG_NETWORK, "Uid state change for seq no. " + procStateSeq + " is not "
24206                             + "dispatched to NPMS yet, so don't wait. Uid: " + callingUid
24207                             + " lastProcStateSeqDispatchedToObservers: "
24208                             + record.lastDispatchedProcStateSeq);
24209                 }
24210                 return;
24211             }
24212             if (record.curProcStateSeq > procStateSeq) {
24213                 if (DEBUG_NETWORK) {
24214                     Slog.d(TAG_NETWORK, "Ignore the wait requests for older seq numbers. Uid: "
24215                             + callingUid + ", curProcStateSeq: " + record.curProcStateSeq
24216                             + ", procStateSeq: " + procStateSeq);
24217                 }
24218                 return;
24219             }
24220             if (record.lastNetworkUpdatedProcStateSeq >= procStateSeq) {
24221                 if (DEBUG_NETWORK) {
24222                     Slog.d(TAG_NETWORK, "Network rules have been already updated for seq no. "
24223                             + procStateSeq + ", so no need to wait. Uid: "
24224                             + callingUid + ", lastProcStateSeqWithUpdatedNetworkState: "
24225                             + record.lastNetworkUpdatedProcStateSeq);
24226                 }
24227                 return;
24228             }
24229             try {
24230                 if (DEBUG_NETWORK) {
24231                     Slog.d(TAG_NETWORK, "Starting to wait for the network rules update."
24232                         + " Uid: " + callingUid + " procStateSeq: " + procStateSeq);
24233                 }
24234                 final long startTime = SystemClock.uptimeMillis();
24235                 record.waitingForNetwork = true;
24236                 record.networkStateLock.wait(mWaitForNetworkTimeoutMs);
24237                 record.waitingForNetwork = false;
24238                 final long totalTime = SystemClock.uptimeMillis() - startTime;
24239                 if (totalTime >= mWaitForNetworkTimeoutMs) {
24240                     Slog.wtf(TAG_NETWORK, "Total time waited for network rules to get updated: "
24241                             + totalTime + ". Uid: " + callingUid + " procStateSeq: "
24242                             + procStateSeq + " UidRec: " + record
24243                             + " validateUidRec: " + mValidateUids.get(callingUid));
24244                 }
24245             } catch (InterruptedException e) {
24246                 Thread.currentThread().interrupt();
24247             }
24248         }
24249     }
24250
24251     public void waitForBroadcastIdle(PrintWriter pw) {
24252         enforceCallingPermission(permission.DUMP, "waitForBroadcastIdle()");
24253         while (true) {
24254             boolean idle = true;
24255             synchronized (this) {
24256                 for (BroadcastQueue queue : mBroadcastQueues) {
24257                     if (!queue.isIdle()) {
24258                         final String msg = "Waiting for queue " + queue + " to become idle...";
24259                         pw.println(msg);
24260                         pw.flush();
24261                         Slog.v(TAG, msg);
24262                         idle = false;
24263                     }
24264                 }
24265             }
24266
24267             if (idle) {
24268                 final String msg = "All broadcast queues are idle!";
24269                 pw.println(msg);
24270                 pw.flush();
24271                 Slog.v(TAG, msg);
24272                 return;
24273             } else {
24274                 SystemClock.sleep(1000);
24275             }
24276         }
24277     }
24278
24279     /**
24280      * Return the user id of the last resumed activity.
24281      */
24282     @Override
24283     public @UserIdInt int getLastResumedActivityUserId() {
24284         enforceCallingPermission(
24285                 permission.INTERACT_ACROSS_USERS_FULL, "getLastResumedActivityUserId()");
24286         synchronized (this) {
24287             if (mLastResumedActivity == null) {
24288                 return mUserController.getCurrentUserIdLocked();
24289             }
24290             return mLastResumedActivity.userId;
24291         }
24292     }
24293
24294     private final class SleepTokenImpl extends SleepToken {
24295         private final String mTag;
24296         private final long mAcquireTime;
24297
24298         public SleepTokenImpl(String tag) {
24299             mTag = tag;
24300             mAcquireTime = SystemClock.uptimeMillis();
24301         }
24302
24303         @Override
24304         public void release() {
24305             synchronized (ActivityManagerService.this) {
24306                 if (mSleepTokens.remove(this)) {
24307                     updateSleepIfNeededLocked();
24308                 }
24309             }
24310         }
24311
24312         @Override
24313         public String toString() {
24314             return "{\"" + mTag + "\", acquire at " + TimeUtils.formatUptime(mAcquireTime) + "}";
24315         }
24316     }
24317
24318     /**
24319      * An implementation of IAppTask, that allows an app to manage its own tasks via
24320      * {@link android.app.ActivityManager.AppTask}.  We keep track of the callingUid to ensure that
24321      * only the process that calls getAppTasks() can call the AppTask methods.
24322      */
24323     class AppTaskImpl extends IAppTask.Stub {
24324         private int mTaskId;
24325         private int mCallingUid;
24326
24327         public AppTaskImpl(int taskId, int callingUid) {
24328             mTaskId = taskId;
24329             mCallingUid = callingUid;
24330         }
24331
24332         private void checkCaller() {
24333             if (mCallingUid != Binder.getCallingUid()) {
24334                 throw new SecurityException("Caller " + mCallingUid
24335                         + " does not match caller of getAppTasks(): " + Binder.getCallingUid());
24336             }
24337         }
24338
24339         @Override
24340         public void finishAndRemoveTask() {
24341             checkCaller();
24342
24343             synchronized (ActivityManagerService.this) {
24344                 long origId = Binder.clearCallingIdentity();
24345                 try {
24346                     // We remove the task from recents to preserve backwards
24347                     if (!mStackSupervisor.removeTaskByIdLocked(mTaskId, false,
24348                             REMOVE_FROM_RECENTS)) {
24349                         throw new IllegalArgumentException("Unable to find task ID " + mTaskId);
24350                     }
24351                 } finally {
24352                     Binder.restoreCallingIdentity(origId);
24353                 }
24354             }
24355         }
24356
24357         @Override
24358         public ActivityManager.RecentTaskInfo getTaskInfo() {
24359             checkCaller();
24360
24361             synchronized (ActivityManagerService.this) {
24362                 long origId = Binder.clearCallingIdentity();
24363                 try {
24364                     TaskRecord tr = mStackSupervisor.anyTaskForIdLocked(mTaskId);
24365                     if (tr == null) {
24366                         throw new IllegalArgumentException("Unable to find task ID " + mTaskId);
24367                     }
24368                     return createRecentTaskInfoFromTaskRecord(tr);
24369                 } finally {
24370                     Binder.restoreCallingIdentity(origId);
24371                 }
24372             }
24373         }
24374
24375         @Override
24376         public void moveToFront() {
24377             checkCaller();
24378             // Will bring task to front if it already has a root activity.
24379             final long origId = Binder.clearCallingIdentity();
24380             try {
24381                 synchronized (this) {
24382                     mStackSupervisor.startActivityFromRecentsInner(mTaskId, null);
24383                 }
24384             } finally {
24385                 Binder.restoreCallingIdentity(origId);
24386             }
24387         }
24388
24389         @Override
24390         public int startActivity(IBinder whoThread, String callingPackage,
24391                 Intent intent, String resolvedType, Bundle bOptions) {
24392             checkCaller();
24393
24394             int callingUser = UserHandle.getCallingUserId();
24395             TaskRecord tr;
24396             IApplicationThread appThread;
24397             synchronized (ActivityManagerService.this) {
24398                 tr = mStackSupervisor.anyTaskForIdLocked(mTaskId);
24399                 if (tr == null) {
24400                     throw new IllegalArgumentException("Unable to find task ID " + mTaskId);
24401                 }
24402                 appThread = IApplicationThread.Stub.asInterface(whoThread);
24403                 if (appThread == null) {
24404                     throw new IllegalArgumentException("Bad app thread " + appThread);
24405                 }
24406             }
24407             return mActivityStarter.startActivityMayWait(appThread, -1, callingPackage, intent,
24408                     resolvedType, null, null, null, null, 0, 0, null, null,
24409                     null, bOptions, false, callingUser, null, tr, "AppTaskImpl");
24410         }
24411
24412         @Override
24413         public void setExcludeFromRecents(boolean exclude) {
24414             checkCaller();
24415
24416             synchronized (ActivityManagerService.this) {
24417                 long origId = Binder.clearCallingIdentity();
24418                 try {
24419                     TaskRecord tr = mStackSupervisor.anyTaskForIdLocked(mTaskId);
24420                     if (tr == null) {
24421                         throw new IllegalArgumentException("Unable to find task ID " + mTaskId);
24422                     }
24423                     Intent intent = tr.getBaseIntent();
24424                     if (exclude) {
24425                         intent.addFlags(Intent.FLAG_ACTIVITY_EXCLUDE_FROM_RECENTS);
24426                     } else {
24427                         intent.setFlags(intent.getFlags()
24428                                 & ~Intent.FLAG_ACTIVITY_EXCLUDE_FROM_RECENTS);
24429                     }
24430                 } finally {
24431                     Binder.restoreCallingIdentity(origId);
24432                 }
24433             }
24434         }
24435     }
24436
24437     /**
24438      * Kill processes for the user with id userId and that depend on the package named packageName
24439      */
24440     @Override
24441     public void killPackageDependents(String packageName, int userId) {
24442         enforceCallingPermission(android.Manifest.permission.KILL_UID, "killPackageDependents()");
24443         if (packageName == null) {
24444             throw new NullPointerException(
24445                     "Cannot kill the dependents of a package without its name.");
24446         }
24447
24448         long callingId = Binder.clearCallingIdentity();
24449         IPackageManager pm = AppGlobals.getPackageManager();
24450         int pkgUid = -1;
24451         try {
24452             pkgUid = pm.getPackageUid(packageName, MATCH_DEBUG_TRIAGED_MISSING, userId);
24453         } catch (RemoteException e) {
24454         }
24455         if (userId != UserHandle.USER_ALL && pkgUid == -1) {
24456             throw new IllegalArgumentException(
24457                     "Cannot kill dependents of non-existing package " + packageName);
24458         }
24459         try {
24460             synchronized(this) {
24461                 killPackageProcessesLocked(packageName, UserHandle.getAppId(pkgUid), userId,
24462                         ProcessList.FOREGROUND_APP_ADJ, false, true, true, false,
24463                         "dep: " + packageName);
24464             }
24465         } finally {
24466             Binder.restoreCallingIdentity(callingId);
24467         }
24468     }
24469
24470     @Override
24471     public void dismissKeyguard(IBinder token, IKeyguardDismissCallback callback)
24472             throws RemoteException {
24473         final long callingId = Binder.clearCallingIdentity();
24474         try {
24475             mKeyguardController.dismissKeyguard(token, callback);
24476         } finally {
24477             Binder.restoreCallingIdentity(callingId);
24478         }
24479     }
24480
24481     @Override
24482     public int restartUserInBackground(final int userId) {
24483         return mUserController.restartUser(userId, /* foreground */ false);
24484     }
24485
24486     @Override
24487     public void scheduleApplicationInfoChanged(List<String> packageNames, int userId) {
24488         enforceCallingPermission(android.Manifest.permission.CHANGE_CONFIGURATION,
24489                 "scheduleApplicationInfoChanged()");
24490
24491         synchronized (this) {
24492             final long origId = Binder.clearCallingIdentity();
24493             try {
24494                 updateApplicationInfoLocked(packageNames, userId);
24495             } finally {
24496                 Binder.restoreCallingIdentity(origId);
24497             }
24498         }
24499     }
24500
24501     void updateApplicationInfoLocked(@NonNull List<String> packagesToUpdate, int userId) {
24502         final boolean updateFrameworkRes = packagesToUpdate.contains("android");
24503         for (int i = mLruProcesses.size() - 1; i >= 0; i--) {
24504             final ProcessRecord app = mLruProcesses.get(i);
24505             if (app.thread == null) {
24506                 continue;
24507             }
24508
24509             if (userId != UserHandle.USER_ALL && app.userId != userId) {
24510                 continue;
24511             }
24512
24513             final int packageCount = app.pkgList.size();
24514             for (int j = 0; j < packageCount; j++) {
24515                 final String packageName = app.pkgList.keyAt(j);
24516                 if (updateFrameworkRes || packagesToUpdate.contains(packageName)) {
24517                     try {
24518                         final ApplicationInfo ai = AppGlobals.getPackageManager()
24519                                 .getApplicationInfo(packageName, 0 /*flags*/, app.userId);
24520                         if (ai != null) {
24521                             app.thread.scheduleApplicationInfoChanged(ai);
24522                         }
24523                     } catch (RemoteException e) {
24524                         Slog.w(TAG, String.format("Failed to update %s ApplicationInfo for %s",
24525                                     packageName, app));
24526                     }
24527                 }
24528             }
24529         }
24530     }
24531
24532     /**
24533      * Attach an agent to the specified process (proces name or PID)
24534      */
24535     public void attachAgent(String process, String path) {
24536         try {
24537             synchronized (this) {
24538                 ProcessRecord proc = findProcessLocked(process, UserHandle.USER_SYSTEM, "attachAgent");
24539                 if (proc == null || proc.thread == null) {
24540                     throw new IllegalArgumentException("Unknown process: " + process);
24541                 }
24542
24543                 boolean isDebuggable = "1".equals(SystemProperties.get(SYSTEM_DEBUGGABLE, "0"));
24544                 if (!isDebuggable) {
24545                     if ((proc.info.flags & ApplicationInfo.FLAG_DEBUGGABLE) == 0) {
24546                         throw new SecurityException("Process not debuggable: " + proc);
24547                     }
24548                 }
24549
24550                 proc.thread.attachAgent(path);
24551             }
24552         } catch (RemoteException e) {
24553             throw new IllegalStateException("Process disappeared");
24554         }
24555     }
24556
24557     @VisibleForTesting
24558     public static class Injector {
24559         private NetworkManagementInternal mNmi;
24560
24561         public Context getContext() {
24562             return null;
24563         }
24564
24565         public AppOpsService getAppOpsService(File file, Handler handler) {
24566             return new AppOpsService(file, handler);
24567         }
24568
24569         public Handler getUiHandler(ActivityManagerService service) {
24570             return service.new UiHandler();
24571         }
24572
24573         public boolean isNetworkRestrictedForUid(int uid) {
24574             if (ensureHasNetworkManagementInternal()) {
24575                 return mNmi.isNetworkRestrictedForUid(uid);
24576             }
24577             return false;
24578         }
24579
24580         private boolean ensureHasNetworkManagementInternal() {
24581             if (mNmi == null) {
24582                 mNmi = LocalServices.getService(NetworkManagementInternal.class);
24583             }
24584             return mNmi != null;
24585         }
24586     }
24587 }